442a8245f5c7e43ae09efa699c066fcfb216d37d
[goodguy/history.git] / cinelerra-5.1 / guicast / bclistbox.h
1 /*
2  * CINELERRA
3  * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20
21 #ifndef BCLISTBOX_H
22 #define BCLISTBOX_H
23
24 #include "bcdragwindow.inc"
25 #include "bclistboxitem.inc"
26 #include "bcpixmap.inc"
27 #include "bcscrollbar.h"
28 #include "bcsubwindow.h"
29 #include "bctoggle.h"
30 #include "colors.h"
31
32 #define BCPOPUPLISTBOX_W 25
33 #define BCPOPUPLISTBOX_H 25
34
35
36 #define MIN_COLUMN_WIDTH 10
37
38
39 class BC_ListBoxYScroll : public BC_ScrollBar
40 {
41 public:
42         BC_ListBoxYScroll(BC_ListBox *listbox,
43                           int total_height,
44                                           int view_height,
45                           int position);
46         ~BC_ListBoxYScroll();
47         int handle_event();
48         int update_length(int64_t length, int64_t position, int64_t handlelength, int flush);
49 private:
50         BC_ListBox *listbox;
51 };
52
53 class BC_ListBoxXScroll : public BC_ScrollBar
54 {
55 public:
56         BC_ListBoxXScroll(BC_ListBox *listbox,
57                           int total_width,
58                                           int view_width,
59                           int position);
60         ~BC_ListBoxXScroll();
61         int handle_event();
62         int update_length(int64_t length, int64_t position, int64_t handlelength, int flush);
63 private:
64         BC_ListBox *listbox;
65 };
66
67 class BC_ListBoxToggle
68 {
69 public:
70         BC_ListBoxToggle(BC_ListBox *listbox,
71                 BC_ListBoxItem *item,
72                 int x,
73                 int y);
74
75         int cursor_motion_event(int *redraw_toggles);
76         int cursor_leave_event(int *redraw_toggles);
77         int button_press_event();
78         int button_release_event(int *redraw_toggles);
79         void update(BC_ListBoxItem *item, int x, int y, int flash);
80         void draw(int flash);
81
82         BC_ListBox *listbox;
83         BC_ListBoxItem *item;
84         int x, y;
85         int value, state;
86         enum
87         {
88                 TOGGLE_UP,
89                 TOGGLE_UPHI,
90                 TOGGLE_CHECKED,
91                 TOGGLE_DOWN,
92                 TOGGLE_CHECKEDHI,
93 // Button pressed then moved out
94                 TOGGLE_DOWN_EXIT
95         };
96 };
97
98
99 class BC_ListBox : public BC_SubWindow
100 {
101 public:
102         BC_ListBox(int x,
103                 int y,
104                 int w,
105                 int h,
106                 int display_format,                   // Display text list or icons
107                 ArrayList<BC_ListBoxItem*> *data = 0, // Each column has an ArrayList of BC_ListBoxItems.
108                 const char **column_titles = 0,             // Titles for columns.  Set to 0 for no titles
109                 int *column_width = 0,                // width of each column
110                 int columns = 1,                      // Total columns.  Only 1 in icon mode
111                 int yposition = 0,                    // Pixel of top of window.
112                 int is_popup = 0,                     // If this listbox is a popup window with a button
113                 int selection_mode = LISTBOX_SINGLE,  // Select one item or multiple items
114                 int icon_position = ICON_LEFT,        // Position of icon relative to text of each item
115                 int allow_drag = 0);                  // Allow user to drag icons around
116         virtual ~BC_ListBox();
117
118         friend class BC_ListBoxToggle;
119
120         int initialize();
121
122 // User event handler for new selections
123         virtual int selection_changed() { return 0; };
124 // User event handler for triggering a selection
125         virtual int handle_event() { return 0; };
126 // User event handler for a column resize
127         virtual int column_resize_event() { return 0; };
128 // Draw background on bg_surface
129         virtual void draw_background();
130 // Draw on bg_surface
131         virtual int draw_images() { return 0; }
132 // Column sort order.  This must return 1 or BC_ListBox will perform a default
133 // action.
134         virtual int sort_order_event() { return 0; };
135 // Column moved
136         virtual int move_column_event() { return 0; };
137
138         int enable();
139         int disable();
140
141 // Get the column movement
142         int get_from_column();
143         int get_to_column();
144
145 // Get the item in the given column which is the selection_number of the total
146 // selected rows.  Returns 0 on failure.
147         BC_ListBoxItem* get_selection(int column, int selection_number);
148         BC_ListBoxItem* get_selection_recursive(ArrayList<BC_ListBoxItem*> *data,
149                 int column,
150                 int selection_number);
151
152 // Get the flat index of the item in the given column which is the selection_number
153 // of the total selected rows.  Returns -1 on failure.  The column
154 // argument is really useless because it only checks column 1 and returns the row
155 // number.
156         int get_selection_number(int column, int selection_number);
157         int get_selection_number_recursive(ArrayList<BC_ListBoxItem*> *data,
158                 int column,
159                 int selection_number,
160                 int *counter = 0);
161
162         virtual int evaluate_query(char *string);
163         void expand_item(BC_ListBoxItem *item, int expand);
164 // Collapse all items
165         static void collapse_recursive(ArrayList<BC_ListBoxItem*> *data,
166                 int master_column);
167 // Convert recursive pointer to flat index.
168 // The pointer can be any item in the row corresponding to the index.
169 // Returns -1 if no item was found.
170         int item_to_index(ArrayList<BC_ListBoxItem*> *data,
171                 BC_ListBoxItem *item,
172                 int *counter = 0);
173 // Convert flat index and column to desired item.
174         BC_ListBoxItem* index_to_item(ArrayList<BC_ListBoxItem*> *data,
175                 int number,
176                 int column,
177                 int *counter = 0);
178 // Get all items with recursion for text mode
179         static int get_total_items(ArrayList<BC_ListBoxItem*> *data,
180                 int *result /* = 0 */,
181                 int master_column);
182
183         virtual int focus_out_event();
184         virtual int keypress_event();
185         virtual int button_press_event();
186         virtual int button_release_event();
187         virtual int cursor_enter_event();
188         virtual int cursor_leave_event();
189         virtual int cursor_motion_event();
190         virtual int drag_start_event();
191         virtual int drag_motion_event();
192         virtual int drag_stop_event();
193
194 // After popping up a menu call this to interrupt the selection process
195         void deactivate_selection();
196
197 // take_focus - used by the suggestion box to keep it from taking focus from the
198 // textbox
199         int activate(int take_focus = 1);
200         int activate(int x, int y, int w=-1, int h=-1);
201         int deactivate();
202         int is_active();
203
204         int translation_event();
205         int repeat_event(int64_t duration);
206         BC_DragWindow* get_drag_popup();
207 // If the popup window should show a button.
208 // Must be called in the constructor.
209         void set_use_button(int value);
210         void set_is_suggestions(int value);
211
212
213 // change the contents
214         int update(ArrayList<BC_ListBoxItem*> *data,
215                                                 const char **column_titles,
216                                                 int *column_widths,
217                                                 int columns,
218                                                 int xposition = 0,
219                                                 int yposition = 0,
220                                                 int highlighted_number = -1,  // Flat index of item cursor is over
221                                                 int recalc_positions = 0,     // set all autoplace flags to 1
222                                                 int draw = 1);
223         void center_selection();
224         void update_format(int display_format, int redraw);
225         int get_format();
226
227 // Allow scrolling when dragging items
228         void set_drag_scroll(int value);
229 // Allow column repositioning
230         void set_allow_drag_column(int value);
231 // Allow automatic moving of objects after drag
232         void set_process_drag(int value);
233
234 // Set the column to use for icons and sublists.
235         void set_master_column(int value, int redraw);
236 // Set column to search
237         void set_search_column(int value);
238         int set_selection_mode(int mode);
239         int set_yposition(int position, int draw_items = 1);
240         int get_yposition();
241         int set_xposition(int position);
242         int get_xposition();
243 // Return the flat index of the highlighted item
244         int get_highlighted_item();
245         int get_yscroll_x();
246         int get_yscroll_y();
247         int get_yscroll_height();
248         int get_xscroll_x();
249         int get_xscroll_y();
250         int get_xscroll_width();
251         int get_column_offset(int column);
252         int get_column_width(int column, int clamp_right = 0);
253         int get_title_h();
254         int get_display_mode();
255         void set_justify(int value);
256         int get_w() { return is_popup ? BCPOPUPLISTBOX_W : popup_w; }
257         int get_h() { return is_popup ? BCPOPUPLISTBOX_H : popup_h; }
258         int gui_tooltip(const char *text) {
259                 return is_popup && gui ? gui->show_tooltip(text, gui->get_w(),0, -1,-1) : -1;
260         }
261         int get_view_w() { return view_w; }
262         int get_view_h() { return view_h; }
263         int get_row_height() { return row_height; }
264         int get_row_ascent() { return row_ascent; }
265         int get_row_descent() { return row_descent; }
266         int get_first_visible() { return first_in_view; }
267         int get_last_visible() { return last_in_view; }
268
269
270         enum
271         {
272                 SORT_ASCENDING,
273                 SORT_DESCENDING
274         };
275
276         int get_sort_column();
277         void set_sort_column(int value, int redraw = 0);
278         int get_sort_order();
279         void set_sort_order(int value, int redraw = 0);
280
281
282         void reset_query();
283         int get_show_query() { return show_query; }
284         void set_show_query(int v) { show_query = v; }
285
286         int reposition_window(int x,
287                 int y,
288                 int w = -1,
289                 int h = -1,
290                 int flush = 1);
291         BC_Pixmap* get_bg_surface();
292 // Set all items for autoplacement with recursion into sublists
293         void set_autoplacement(ArrayList<BC_ListBoxItem*> *data,
294                 int do_icon,
295                 int do_text);
296 // Set selection status on all items with recursion
297         void set_all_selected(ArrayList<BC_ListBoxItem*> *data, int value);
298 // Set selection status of single row with recursion
299 // item_number - the flat index of the row to select
300         void set_selected(ArrayList<BC_ListBoxItem*> *data,
301                 int item_number,
302                 int value,
303                 int *counter = 0);
304
305 // Called by keypress_event for cursor up.  Selects previous and next visible
306 // row, skipping desired number of visible rows.
307         int select_previous(int skip,
308                 BC_ListBoxItem *selected_item = 0,
309                 int *counter = 0,
310                 ArrayList<BC_ListBoxItem*> *data = 0,
311                 int *got_it = 0,
312                 int *got_second = 0);
313         int select_next(int skip,
314                 BC_ListBoxItem *selected_item = 0,
315                 int *counter = 0,
316                 ArrayList<BC_ListBoxItem*> *data = 0,
317                 int *got_it = 0,
318                 int *got_second = 0);
319
320 // Called by cursor_motion_event to select different item if selection_number
321 // changed.  Returns 1 if redraw is required.
322         int update_selection(ArrayList<BC_ListBoxItem*> *data,
323                 int selection_number,
324                 int *counter = 0);
325
326         static void dump(ArrayList<BC_ListBoxItem*> *data,
327                 int columns,
328                 int indent /* = 0 */,
329                 int master_column);
330
331         int get_item_x(BC_ListBoxItem *item);
332         int get_item_y(BC_ListBoxItem *item);
333         int get_item_w(BC_ListBoxItem *item);
334         int get_item_h(BC_ListBoxItem *item);
335
336 // Draw the list items
337         int draw_items(int flash, int bg_draw=0);
338
339 private:
340         void delete_columns();
341         void set_columns(const char **column_titles,
342                 int *column_widths,
343                 int columns);
344 // Draw the button for a popup listbox
345         int draw_button(int flush);
346 // Draw list border
347         int draw_border(int flash);
348 // Draw column titles
349         void draw_title(int number);
350         int draw_titles(int flash);
351 // Draw expanders
352         void draw_toggles(int flash);
353 // Draw selection rectangle
354         int draw_rectangle(int flash);
355
356
357         void draw_text_recursive(ArrayList<BC_ListBoxItem*> *data,
358                 int column,
359                 int indent,
360                 int *current_toggle);
361 // Returns 1 if selection changed
362         int query_list();
363         void init_column_width();
364         void reset_cursor(int new_cursor);
365 // Fix boundary conditions after resize
366         void column_width_boundaries();
367 // Recursive function to get the first item selected in text mode.
368 // Returns > -1 only if it got it.  Always increments *result
369         int get_first_selection(ArrayList<BC_ListBoxItem*> *data, int *result = 0);
370 // Recursive function to get the last item selected in text mode.
371 // Returns > -1 only if it got it.  Always increments *result
372         int get_last_selection(ArrayList<BC_ListBoxItem*> *data, int *result = 0);
373 // Called by button_press_event and cursor_motion_event to expand the selection.
374 // Returns 1 if redraw is required.
375         int expand_selection(int button_press, int selection_number);
376 // Called by button_press_event and cursor_motion_event
377 // to select a range in text mode
378         void select_range(ArrayList<BC_ListBoxItem*> *data,
379                 int start,
380                 int end,
381                 int *current = 0);
382 // Called by button_press_event to toggle the selection status of a single item.
383 // Called for both text and icon mode.  In text mode it's recursive and fills
384 // the entire row with the first item's value.  Returns 1 when the item was toggled.
385         int toggle_item_selection(ArrayList<BC_ListBoxItem*> *data,
386                 int selection_number,
387                 int *counter = 0);
388 // Set value of selected in all selected items to new value
389         void promote_selections(ArrayList<BC_ListBoxItem*> *data,
390                 int old_value,
391                 int new_value);
392
393
394         int test_column_divisions(int cursor_x, int cursor_y, int &new_cursor);
395         int test_column_titles(int cursor_x, int cursor_y);
396         int test_expanders();
397
398         int calculate_item_coords();
399         void calculate_last_coords_recursive(
400                 ArrayList<BC_ListBoxItem*> *data,
401                 int *icon_x,
402                 int *next_icon_x,
403                 int *next_icon_y,
404                 int *next_text_y,
405                 int top_level);
406         void calculate_item_coords_recursive(
407                 ArrayList<BC_ListBoxItem*> *data,
408                 int *icon_x,
409                 int *next_icon_x,
410                 int *next_icon_y,
411                 int *next_text_y,
412                 int top_level);
413
414         int get_items_width();
415         int get_items_height(ArrayList<BC_ListBoxItem*> *data,
416                 int columns,
417                 int *result = 0);
418         int get_icon_w(BC_ListBoxItem *item);
419         int get_icon_h(BC_ListBoxItem *item);
420         int get_text_w(BC_ListBoxItem *item);
421         int get_text_h(BC_ListBoxItem *item);
422         int get_baseline(BC_ListBoxItem *item);
423         int get_item_highlight(ArrayList<BC_ListBoxItem*> *data, int column, int item);
424         int get_item_color(ArrayList<BC_ListBoxItem*> *data, int column, int item);
425         int get_icon_mask(BC_ListBoxItem *item, int &x, int &y, int &w, int &h);
426         int get_text_mask(BC_ListBoxItem *item, int &x, int &y, int &w, int &h);
427 // Copy sections of the bg_surface to the gui
428         void clear_listbox(int x, int y, int w, int h);
429
430 // Tests for cursor outside boundaries
431         int test_drag_scroll(int cursor_x, int cursor_y);
432 // Called by select_scroll_event, rectangle_scroll_event to execute for movement
433         int drag_scroll_event();
434         int select_scroll_event();
435         int rectangle_scroll_event();
436
437
438         void move_vertical(int pixels);
439         void move_horizontal(int pixels);
440         void clamp_positions();
441
442         int get_scrollbars();
443         void update_scrollbars(int flush);
444
445 // Flat index of the item the cursor is over.
446 // Points *item_return to the first item in the row or 0 if no item was found.
447 // if it's nonzero.  Returns -1 if no item was found.  Clamps the y coordinate
448 // only if the current operation is not SELECT, so scrolling is possible.
449 // expanded - 1 if items in this table should be tested for cursor coverage
450         int get_cursor_item(ArrayList<BC_ListBoxItem*> *data,
451                 int cursor_x,
452                 int cursor_y,
453                 BC_ListBoxItem **item_return = 0,
454                 int *counter = 0,
455                 int expanded = 1);
456 // Select the items in the rectangle and deselect the items outside of it.
457 // Returns 1 if redraw is required.
458         int select_rectangle(ArrayList<BC_ListBoxItem*> *data,
459                 int x1,
460                 int y1,
461                 int x2,
462                 int y2);
463 // Convert the row of the item to a pointer.
464         BC_ListBoxItem* number_to_item(int row);
465         int reposition_item(ArrayList<BC_ListBoxItem*> *data,
466                 int selection_number,
467                 int x,
468                 int y,
469                 int *counter = 0);
470 // Move selected items to src_items
471         void move_selection(ArrayList<BC_ListBoxItem*> *dst,
472                 ArrayList<BC_ListBoxItem*> *src);
473 // Put items from the src table into the data table starting at flat item number
474 // destination.
475         int put_selection(ArrayList<BC_ListBoxItem*> *data,
476                 ArrayList<BC_ListBoxItem*> *src,
477                 int destination,
478                 int *counter = 0);
479
480         int center_selection(int selection,
481                 ArrayList<BC_ListBoxItem*> *data = 0,
482                 int *counter = 0);
483
484 // Array of one list of pointers for each column
485         ArrayList<BC_ListBoxItem*> *data;
486
487
488 // 1 if a button is used to make the listbox display
489         int is_popup;      // popup
490 // If the button for a popup should be shown
491         int use_button;
492 // background update needed
493         int bg_draw;
494
495 // Dimensions for a popup if there is one
496         int popup_w, popup_h;
497 // pixel of top of display relative to top of list
498         int yposition;
499 // pixel of left display relative to first column
500         int xposition;
501 // dimensions of a row in the list
502         int row_height, row_ascent, row_descent;
503
504
505         int selection_mode;
506         int display_format;
507         int temp_display_format;
508         int icon_position;
509 // Scrollbars are created as needed
510         BC_ListBoxXScroll *xscrollbar;
511         BC_ListBoxYScroll *yscrollbar;
512         ArrayList<BC_ListBoxToggle*> expanders;
513         char query[BCTEXTLEN];
514         int show_query;
515
516 // Window containing the listbox
517         BC_WindowBase *gui;
518         int disabled;
519 // Size of the popup if there is one
520         char **column_titles;
521         int *column_width;
522         int default_column_width[1];
523         int columns;
524         int master_column;
525         int search_column;
526
527         int view_h, view_w;
528         int first_in_view, last_in_view;
529         int title_h;
530 // Maximum width of items.  Calculated by get_items_width
531         int items_w;
532         int items_h;
533 // In BCLISTBOX_SELECT mode determines the value to set items to
534         int new_value;
535         int need_xscroll, need_yscroll;
536 // Move items during drag operation of text items.
537         int process_drag;
538         int allow_drag;
539         int allow_drag_scroll;
540         int allow_drag_column;
541 // Background color of listbox
542         int list_background;
543
544
545 // Popup button
546         BC_Pixmap *button_images[4];
547 // Expander
548         BC_Pixmap *toggle_images[5];
549 // Background for drawing on
550         BC_Pixmap *bg_surface;
551 // Background if 9 segment
552         BC_Pixmap *bg_tile;
553 // Drag icon for text mode
554         VFrame *drag_icon_vframe;
555 // Drag column icon
556         VFrame *drag_column_icon_vframe;
557 // Background picon to be drawn in the upper right
558         BC_Pixmap *bg_pixmap;
559
560
561 // Column title backgrounds
562         BC_Pixmap *column_bg[3];
563 // Column sort order
564         BC_Pixmap *column_sort_up;
565         BC_Pixmap *column_sort_dn;
566
567
568
569
570 // Number of column to sort
571         int sort_column;
572 // Sort order.  -1 means no column is being sorted.
573         int sort_order;
574
575
576
577
578
579 // State of the list box and button when the mouse button is pressed.
580         int current_operation;
581
582         enum
583         {
584                 NO_OPERATION,
585                 BUTTON_DOWN_SELECT, // Pressed button and slid off to select items.
586                 BUTTON_DN,
587                 DRAG_DIVISION,    // Dragging column division
588                 DRAG_COLUMN,      // Dragging column
589                 DRAG_ITEM,        // Dragging item
590                 SELECT,                   // Select item
591                 SELECT_RECT,      // Selection rectangle
592                 WHEEL,                    // Wheel mouse
593                 COLUMN_DN,                // column title down
594                 COLUMN_DRAG,      // column title is being dragged
595                 EXPAND_DN         // Expander is down
596         };
597
598
599 // More state variables
600         int button_highlighted;
601         int list_highlighted;
602 // item cursor is over.  May not exist in tables.
603 // Must be an index since this is needed to change the database.
604         int highlighted_item;
605         BC_ListBoxItem* highlighted_ptr;
606 // column title if the cursor is over a column title
607         int highlighted_title;
608 // Division the cursor is operating on when resizing
609         int highlighted_division;
610 // Column title being dragged
611         int dragged_title;
612 // start of column title drag
613         int drag_cursor_x;
614         int drag_column_w;
615
616 // Selection range being extended
617         int selection_start, selection_end, selection_center;
618 // Item being dragged or last item selected in a double click operation
619         int selection_number;
620 // Used in button_press_event and button_release_event to detect double clicks
621         int selection_number1, selection_number2;
622
623
624
625
626         int active;
627 // Popup listboxes have different behavior for suggestion boxes where the
628 // textbox needs to be active when the listbox is visible.
629         int is_suggestions;
630
631 // Button release counter for double clicking
632         int button_releases;
633         int current_cursor;
634 // Starting coordinates of rectangle
635         int rect_x1, rect_y1;
636         int rect_x2, rect_y2;
637
638
639
640 // Window for dragging
641         BC_DragWindow *drag_popup;
642         int justify;
643 };
644
645
646
647
648 #endif