r717: Made the highlighted text color of the menus WHITE
[cinelerra_cv/mob.git] / guicast / bcpopupmenu.C
blobabce53cee22c18cc9a6ed8e5fd11491403707cab
1 #include "bcmenubar.h"
2 #include "bcmenupopup.h"
3 #include "bcpixmap.h"
4 #include "bcpopupmenu.h"
5 #include "bcresources.h"
6 #include "colors.h"
7 #include "fonts.h"
8 #include <string.h>
9 #include "vframe.h"
11 #define BUTTON_UP 0
12 #define BUTTON_HI 1
13 #define BUTTON_DN 2
14 #define TOTAL_IMAGES 3
17 #define TRIANGLE_W 10
18 #define TRIANGLE_H 10
21 BC_PopupMenu::BC_PopupMenu(int x, 
22                 int y, 
23                 int w, 
24                 char *text, 
25                 int use_title,
26                 VFrame **data,
27                 int margin)
28  : BC_SubWindow(x, y, 0, 0, -1)
30         highlighted = popup_down = 0;
31         menu_popup = 0;
32         icon = 0;
33         if(margin >= 0)
34                 this->margin = margin;
35         else
36                 this->margin = BC_WindowBase::get_resources()->popupmenu_margin;
38         this->use_title = use_title;
39         strcpy(this->text, text);
40         for(int i = 0; i < TOTAL_IMAGES; i++)
41         {
42                 images[i] = 0;
43         }
44         this->data = data;
45         this->w_argument = w;
46         status = BUTTON_UP;
49 BC_PopupMenu::BC_PopupMenu(int x, 
50                 int y, 
51                 char *text, 
52                 int use_title,
53                 VFrame **data)
54  : BC_SubWindow(x, y, w, -1, -1)
56         highlighted = popup_down = 0;
57         menu_popup = 0;
58         icon = 0;
59         this->use_title = use_title;
60         strcpy(this->text, text);
61         for(int i = 0; i < TOTAL_IMAGES; i++)
62         {
63                 images[i] = 0;
64         }
65         this->data = data;
66         this->w_argument = 0;
67         status = BUTTON_UP;
70 BC_PopupMenu::~BC_PopupMenu()
72         if(menu_popup) delete menu_popup;
73         for(int i = 0; i < TOTAL_IMAGES; i++)
74         {
75                 if(images[i]) delete images[i];
76         }
79 char* BC_PopupMenu::get_text()
81         return text;
84 void BC_PopupMenu::set_text(char *text)
86         if(use_title)
87         {
88                 strcpy(this->text, text);
89                 draw_title();
90         }
93 void BC_PopupMenu::set_icon(BC_Pixmap *icon)
95         if(use_title)
96         {
97                 this->icon = icon;
98                 if(menu_popup) draw_title();
99         }
102 int BC_PopupMenu::initialize()
104         if(use_title)
105         {
106                 if(data)
107                         set_images(data);
108                 else
109                 if(BC_WindowBase::get_resources()->popupmenu_images)
110                         set_images(BC_WindowBase::get_resources()->popupmenu_images);
111                 else
112                         set_images(BC_WindowBase::get_resources()->generic_button_images);
113         }
114         else
115 // Move outside window if no title
116         {
117                 x = -10;
118                 y = -10;
119                 w = 10;
120                 h = 10;
121         }
123         BC_SubWindow::initialize();
125         menu_popup = new BC_MenuPopup;
126         menu_popup->initialize(top_level, 
127                 0, 
128                 0, 
129                 0, 
130                 this);
132         if(use_title) draw_title();
134         return 0;
137 int BC_PopupMenu::set_images(VFrame **data)
139         BC_Resources *resources = get_resources();
140         for(int i = 0; i < 3; i++)
141         {
142                 if(images[i]) delete images[i];
143                 images[i] = new BC_Pixmap(parent_window, data[i], PIXMAP_ALPHA);
144         }
146         if(w_argument > 0)
147                 w = w_argument + 
148                         margin +
149                         resources->popupmenu_triangle_margin;
150         else
151                 w = get_text_width(MEDIUMFONT, text) + 
152                         margin +
153                         resources->popupmenu_triangle_margin;
155         h = images[BUTTON_UP]->get_h();
156         return 0;
159 int BC_PopupMenu::calculate_h(VFrame **data)
161         if(data)
162                 ;
163         else
164         if(BC_WindowBase::get_resources()->popupmenu_images)
165                 data = BC_WindowBase::get_resources()->popupmenu_images;
166         else
167                 data = BC_WindowBase::get_resources()->generic_button_images;
169         
170         return data[BUTTON_UP]->get_h();
173 int BC_PopupMenu::add_item(BC_MenuItem *item)
175         menu_popup->add_item(item);
176         return 0;
179 int BC_PopupMenu::remove_item(BC_MenuItem *item)
181         menu_popup->remove_item(item);
182         return 0;
185 int BC_PopupMenu::total_items()
187         return menu_popup->total_menuitems();
188         return 0;
191 BC_MenuItem* BC_PopupMenu::get_item(int i)
193         return menu_popup->menu_items.values[i];
196 int BC_PopupMenu::draw_title()
198         if(!use_title) return 0;
199         BC_Resources *resources = get_resources();
201 // Background
202         draw_top_background(parent_window, 0, 0, w, h);
203         draw_3segmenth(0, 0, w, images[status]);
205 // Overlay text
206         set_color(get_resources()->popup_title_text);
207         int offset = 0;
208         if(status == BUTTON_DN)
209                 offset = 1;
210         if(!icon)
211         {
212                 set_font(MEDIUMFONT);
213                 BC_WindowBase::draw_center_text(
214                         (get_w() - margin * 2 - resources->popupmenu_triangle_margin) / 2 + margin + offset, 
215                         (int)((float)get_h() / 2 + get_text_ascent(MEDIUMFONT) / 2 - 2) + offset, 
216                         text);
217         }
219         if(icon)
220         {
221                 draw_pixmap(icon,
222                         (get_w() - margin * 2 - resources->popupmenu_triangle_margin) / 2 + margin + offset - icon->get_w() / 2 ,
223                         get_h() / 2 - icon->get_h() / 2 + offset);
224         }
226         draw_triangle_down_flat(get_w() - margin - resources->popupmenu_triangle_margin, 
227                 get_h() / 2 - TRIANGLE_H / 2, 
228                 TRIANGLE_W, TRIANGLE_H);
230         flash();
231         return 0;
234 int BC_PopupMenu::deactivate()
236         if(popup_down)
237         {
238                 top_level->active_popup_menu = 0;
239                 popup_down = 0;
240                 menu_popup->deactivate_menu();
242                 if(use_title) draw_title();    // draw the title
243         }
244         return 0;
247 int BC_PopupMenu::activate_menu()
249         if(!popup_down)
250         {
251                 int x = this->x;
252                 int y = this->y;
254                 top_level->deactivate();
255                 top_level->active_popup_menu = this;
256                 if(!use_title)
257                 {
258                         x = top_level->get_abs_cursor_x(0) - get_w();
259                         y = top_level->get_abs_cursor_y(0) - get_h();
260                         button_press_x = top_level->cursor_x;
261                         button_press_y = top_level->cursor_y;
262                 }
264                 button_releases = 0;
265                 if(use_title)
266                 {
267                         Window tempwin;
268                         int new_x, new_y, top_w, top_h;
269                         XTranslateCoordinates(top_level->display, 
270                                 win, 
271                                 top_level->rootwin, 
272                                 0, 
273                                 0, 
274                                 &new_x, 
275                                 &new_y, 
276                                 &tempwin);
277                         menu_popup->activate_menu(new_x, 
278                                 new_y, 
279                                 w, 
280                                 h, 
281                                 0, 
282                                 1);
283                 }
284                 else
285                         menu_popup->activate_menu(x, y, w, h, 0, 1);
286                 popup_down = 1;
287                 if(use_title) draw_title();
288         }
289         return 0;
292 int BC_PopupMenu::deactivate_menu()
294         deactivate();
295         return 0;
299 int BC_PopupMenu::reposition_window(int x, int y)
301         BC_WindowBase::reposition_window(x, y);
302         draw_title();
303         return 0;
306 int BC_PopupMenu::focus_out_event()
308         deactivate();
309         return 0;
313 int BC_PopupMenu::repeat_event(int64_t duration)
315         if(duration == top_level->get_resources()->tooltip_delay &&
316                 tooltip_text[0] != 0 &&
317                 status == BUTTON_HI &&
318                 !tooltip_done)
319         {
320                 show_tooltip();
321                 tooltip_done = 1;
322                 return 1;
323         }
324         return 0;
327 int BC_PopupMenu::button_press_event()
329         int result = 0;
331         if(get_buttonpress() == 1 &&
332                 is_event_win() && 
333                 use_title)
334         {
335                 top_level->hide_tooltip();
336                 if(status == BUTTON_HI || status == BUTTON_UP) status = BUTTON_DN;
337                 activate_menu();
338                 draw_title();
339                 return 1;
340         }
342         if(popup_down)
343         {
344 // Menu is down so dispatch to popup.
345                 menu_popup->dispatch_button_press();
346                 return 1;
347         }
349         return 0;
352 int BC_PopupMenu::button_release_event()
354 // try the title
355         int result = 0;
357         button_releases++;
358 //printf("BC_PopupMenu::button_release_event 1 %d\n", result);
360         if(is_event_win() && use_title)
361         {
362                 hide_tooltip();
363                 if(status == BUTTON_DN)
364                 {
365                         status = BUTTON_HI;
366                         draw_title();
367                 }
368         }
369 //printf("BC_PopupMenu::button_release_event 2 %d\n", result);
371         if(popup_down)
372         {
373 // Menu is down so dispatch to popup.
374                 result = menu_popup->dispatch_button_release();
375         }
377         if(popup_down && button_releases >= 2)
378         {
379                 deactivate();
380         }
381 //printf("BC_PopupMenu::button_release_event 3 %d\n", result);
383         if(!result && use_title && cursor_inside() && is_event_win())
384         {
385 //printf("BC_PopupMenu::button_release_event 4 %d\n", result);
386                 hide_tooltip();
387                 result = 1;
388         }
389         else
390         if(!result && !use_title && popup_down && button_releases < 2)
391         {
392 //printf("BC_PopupMenu::button_release_event 5 %d\n", result);
393                 result = 1;
394         }
395 //printf("BC_PopupMenu::button_release_event 6 %d\n", result);
398         if(!result && popup_down)
399         {
400 // Button was released outside any menu.
401                 deactivate();
402                 result = 1;
403         }
404 //printf("BC_PopupMenu::button_release_event 5 %d\n", result);
406         return result;
417         if(popup_down)
418         {
419 // Menu is down so dispatch to popup.
420                 result = menu_popup->dispatch_button_release();
421         }
423         if(!result && use_title && cursor_inside() && top_level->event_win == win)
424         {
425 // Inside title
426                 if(button_releases >= 2)
427                 {
428                         highlighted = 1;
429                         deactivate();
430                 }
431                 result = 1;
432         }
433         else
434         if(!result && !use_title && button_releases < 2)
435         {
436 // First release outside a floating menu
437 // Released outside a fictitious title area
438 //              if(top_level->cursor_x < button_press_x - 5 ||
439 //                      top_level->cursor_y < button_press_y - 5 ||
440 //                      top_level->cursor_x > button_press_x + 5 ||
441 //                      top_level->cursor_y > button_press_y + 5)       
442                         deactivate();
443                 result = 1;
444         }
446         return result;
449 int BC_PopupMenu::translation_event()
451 //printf("BC_PopupMenu::translation_event 1\n");
452         if(popup_down) menu_popup->dispatch_translation_event();
453         return 0;
456 int BC_PopupMenu::cursor_leave_event()
459         if(status == BUTTON_HI && use_title)
460         {
461                 status = BUTTON_UP;
462                 draw_title();
463                 hide_tooltip();
464         }
466 // dispatch to popup
467         if(popup_down)
468         {
469                 menu_popup->dispatch_cursor_leave();
470         }
472         return 0;
476 int BC_PopupMenu::cursor_enter_event()
478         if(is_event_win() && use_title)
479         {
480                 tooltip_done = 0;
481                 if(top_level->button_down)
482                 {
483                         status = BUTTON_DN;
484                 }
485                 else
486                 if(status == BUTTON_UP) 
487                         status = BUTTON_HI;
488                 draw_title();
489         }
491         return 0;
494 int BC_PopupMenu::cursor_motion_event()
496         int result = 0;
498 // This menu is down.
499         if(popup_down)
500         {
501                 result = menu_popup->dispatch_motion_event();
502         }
504         if(!result && use_title && top_level->event_win == win)
505         {
506                 if(highlighted)
507                 {
508                         if(cursor_inside())
509                         {
510                                 highlighted = 0;
511                                 draw_title();
512                         }
513                 }
514                 else
515                 {
516                         if(cursor_inside())
517                         {
518                                 highlighted = 1;
519                                 draw_title();
520                                 result = 1;
521                         }
522                 }
523         }
525         return result;
528 int BC_PopupMenu::drag_start_event()
530 //printf("BC_PopupMenu::drag_start_event %d\n", popup_down);
531         if(popup_down) return 1;
532         return 0;
535 int BC_PopupMenu::drag_stop_event()
537         if(popup_down) return 1;
538         return 0;
541 int BC_PopupMenu::drag_motion_event()
543         if(popup_down) return 1;
544         return 0;