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