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