graphic art overlay modes, pref window resize, submenu fixes
[goodguy/history.git] / cinelerra-5.1 / guicast / bcmenuitem.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "bcmenubar.h"
23 #include "bcmenuitem.h"
24 #include "bcmenupopup.h"
25 #include "bcpixmap.h"
26 #include "bcpopup.h"
27 #include "bcpopupmenu.h"
28 #include "bcresources.h"
29 #include "bcsignals.h"
30 #include "bcwindowbase.h"
31 #include "colors.h"
32
33 #include <string.h>
34
35
36 #define MENUITEM_UP 0
37 #define MENUITEM_HI 1
38 #define MENUITEM_DN 2
39
40
41 #define MENUITEM_MARGIN 2
42
43 // ================================ Menu Item ==================================
44
45 BC_MenuItem::BC_MenuItem(const char *text, const char *hotkey_text, int hotkey)
46 {
47         reset();
48
49         if(text) set_text(text);
50         if(hotkey_text) set_hotkey_text(hotkey_text);
51
52         this->hotkey = hotkey;
53         checked = 0;
54         highlighted = 0;
55         down = 0;
56         submenu = 0;
57         shift_hotkey = 0;
58         alt_hotkey = 0;
59         ctrl_hotkey = 0;
60         menu_popup = 0;
61 }
62
63 BC_MenuItem::~BC_MenuItem()
64 {
65         if(text) delete [] text;
66         text = 0;
67         if(hotkey_text) delete [] hotkey_text;
68         hotkey_text = 0;
69         if(submenu) delete submenu;
70         submenu = 0;
71         if(menu_popup)
72                 menu_popup->remove_item(this);
73 }
74
75 void BC_MenuItem::reset()
76 {
77         text = new char[1];
78         hotkey_text = new char[1];
79         text[0] = 0;
80         hotkey_text[0] = 0;
81         icon = 0;
82 }
83
84 int BC_MenuItem::initialize(BC_WindowBase *top_level, BC_MenuBar *menu_bar, BC_MenuPopup *menu_popup)
85 {
86         this->top_level = top_level;
87         this->menu_popup = menu_popup;
88         this->menu_bar = menu_bar;
89         return 0;
90 }
91
92 int BC_MenuItem::set_checked(int value)
93 {
94         this->checked = value;
95         return 0;
96 }
97
98 int BC_MenuItem::get_checked()
99 {
100         return checked;
101 }
102
103 void BC_MenuItem::set_icon(BC_Pixmap *icon)
104 {
105         this->icon = icon;
106 }
107
108 BC_Pixmap* BC_MenuItem::get_icon()
109 {
110         return icon;
111 }
112
113 void BC_MenuItem::set_text(const char *text)
114 {
115         if(this->text) delete [] this->text;
116         this->text = new char[strlen(text) + 1];
117         strcpy(this->text, text);
118 }
119
120 void BC_MenuItem::set_hotkey_text(const char *text)
121 {
122         if(this->hotkey_text) delete [] this->hotkey_text;
123         this->hotkey_text = new char[strlen(text) + 1];
124         strcpy(this->hotkey_text, text);
125 }
126
127 int BC_MenuItem::deactivate_submenus(BC_MenuPopup *exclude)
128 {
129         if(submenu && submenu != exclude)
130         {
131                 submenu->deactivate_submenus(exclude);
132                 submenu->deactivate_menu();
133                 submenu->popup_menu = 0;
134                 highlighted = 0;
135         }
136         return 0;
137 }
138
139 int BC_MenuItem::activate_submenu()
140 {
141         int new_x, new_y;
142         if(menu_popup->popup && submenu && !submenu->popup)
143         {
144                 Window tempwin;
145                 XTranslateCoordinates(top_level->display,
146                         menu_popup->get_popup()->win,
147                         top_level->rootwin,
148                         0,
149                         y,
150                         &new_x,
151                         &new_y,
152                         &tempwin);
153                 submenu->popup_menu = menu_popup->popup_menu;
154                 submenu->activate_menu(new_x + 5, new_y, menu_popup->w - 10, h, 0, 0);
155                 highlighted = 1;
156         }
157         return 0;
158 }
159
160
161 int BC_MenuItem::dispatch_button_press()
162 {
163         int result = 0;
164
165         if(submenu)
166         {
167                 result = submenu->dispatch_button_press();
168         }
169
170         if(!result && top_level->event_win == menu_popup->get_popup()->win)
171         {
172                 if(top_level->cursor_x >= 0 && top_level->cursor_x < menu_popup->get_w() &&
173                         top_level->cursor_y >= y && top_level->cursor_y < y + h)
174                 {
175                         if(!highlighted)
176                         {
177                                 highlighted = 1;
178                         }
179                         result = 1;
180                 }
181                 else
182                 if(highlighted)
183                 {
184                         highlighted = 0;
185                         result = 1;
186                 }
187         }
188
189         return result;
190 }
191
192 int BC_MenuItem::dispatch_button_release(int &redraw)
193 {
194         int result = 0;
195         int cursor_x, cursor_y;
196         Window tempwin;
197
198         if(!strcmp(text, "-")) return 0;
199
200         if(submenu)
201         {
202                 result = submenu->dispatch_button_release();
203         }
204
205         if(!result)
206         {
207                 XTranslateCoordinates(top_level->display,
208                         top_level->event_win,
209                         menu_popup->get_popup()->win,
210                         top_level->cursor_x,
211                         top_level->cursor_y,
212                         &cursor_x,
213                         &cursor_y,
214                         &tempwin);
215
216                 if(cursor_x >= 0 && cursor_x < menu_popup->get_w() &&
217                         cursor_y >= y && cursor_y < y + h)
218                 {
219                         if(menu_bar)
220                                 menu_bar->deactivate();
221                         else
222                                 menu_popup->popup_menu->deactivate();
223
224                         if(!handle_event() && menu_popup && menu_popup->popup_menu)
225                         {
226                                 menu_popup->popup_menu->set_text(text);
227                                 menu_popup->popup_menu->handle_event();
228                         }
229                         return 1;
230                 }
231         }
232         return 0;
233 }
234
235 int BC_MenuItem::dispatch_motion_event(int &redraw)
236 {
237         int result = 0;
238         int cursor_x, cursor_y;
239
240         if(submenu)
241         {
242                 result = submenu->dispatch_motion_event();
243         }
244
245         top_level->translate_coordinates(top_level->event_win,
246                 menu_popup->get_popup()->win,
247                 top_level->cursor_x,
248                 top_level->cursor_y,
249                 &cursor_x,
250                 &cursor_y);
251
252         if(cursor_x >= 0 && cursor_x < menu_popup->get_w() &&
253                 cursor_y >= y && cursor_y < y + h)
254         {
255 // Highlight the item
256                 if(!highlighted)
257                 {
258 // Deactivate submenus in the parent menu excluding this one.
259                         menu_popup->deactivate_submenus(submenu);
260                         highlighted = 1;
261                         if(submenu) activate_submenu();
262                         redraw = 1;
263                 }
264                 result = 1;
265         }
266         else
267         if(highlighted)
268         {
269                 highlighted = 0;
270                 result = 1;
271                 redraw = 1;
272         }
273         return result;
274 }
275
276 int BC_MenuItem::dispatch_translation_event()
277 {
278         if(submenu)
279                 submenu->dispatch_translation_event();
280         return 0;
281 }
282
283 int BC_MenuItem::dispatch_cursor_leave()
284 {
285         int result = 0;
286         if(submenu)
287         {
288                 result = submenu->dispatch_cursor_leave();
289         }
290
291         if(!result && highlighted && top_level->event_win == menu_popup->get_popup()->win)
292         {
293                 highlighted = 0;
294                 return 1;
295         }
296         return 0;
297 }
298
299 int BC_MenuItem::dispatch_key_press()
300 {
301         int result = 0;
302         if(submenu)
303         {
304                 result = submenu->dispatch_key_press();
305         }
306
307         if(!result)
308         {
309
310                 if(top_level->get_keypress() == hotkey &&
311                         shift_hotkey == top_level->shift_down() &&
312                         alt_hotkey == top_level->alt_down() &&
313                         ctrl_hotkey == top_level->ctrl_down())
314                 {
315                         result = 1;
316                         handle_event();
317                 }
318         }
319         return result;
320 }
321
322
323 int BC_MenuItem::draw()
324 {
325         int text_line = top_level->get_text_descent(MEDIUMFONT);
326         BC_Resources *resources = top_level->get_resources();
327
328         if(!strcmp(text, "-"))
329         {
330                 menu_popup->get_popup()->set_color(DKGREY);
331                 menu_popup->get_popup()->draw_line(5, y + h / 2, menu_popup->get_w() - 5, y + h / 2);
332                 menu_popup->get_popup()->set_color(LTGREY);
333                 menu_popup->get_popup()->draw_line(5, y + h / 2 + 1, menu_popup->get_w() - 5, y + h / 2 + 1);
334         }
335         else
336         {
337                 int offset = 0;
338                 if(highlighted)
339                 {
340                         int y = this->y;
341                         //int w = menu_popup->get_w() - 4;
342                         int h = this->h;
343
344 // Button down
345                         if(top_level->get_button_down() && !submenu)
346                         {
347                                 if(menu_popup->item_bg[MENUITEM_DN])
348                                 {
349 //                                      menu_popup->get_popup()->draw_9segment(MENUITEM_MARGIN,
350 //                                              y,
351 //                                              menu_popup->get_w() - MENUITEM_MARGIN * 2,
352 //                                              h,
353 //                                              menu_popup->item_bg[MENUITEM_DN]);
354                                         menu_popup->get_popup()->draw_3segmenth(MENUITEM_MARGIN,
355                                                 y,
356                                                 menu_popup->get_w() - MENUITEM_MARGIN * 2,
357                                                 menu_popup->item_bg[MENUITEM_DN]);
358                                 }
359                                 else
360                                 {
361                                         menu_popup->get_popup()->draw_3d_box(MENUITEM_MARGIN,
362                                                 y,
363                                                 menu_popup->get_w() - MENUITEM_MARGIN * 2,
364                                                 h,
365                                                 resources->menu_shadow,
366                                                 BLACK,
367                                                 resources->menu_down,
368                                                 resources->menu_down,
369                                                 resources->menu_light);
370                                 }
371                                 offset = 1;
372                         }
373                         else
374 // Highlighted
375                         {
376                                 if(menu_popup->item_bg[MENUITEM_HI])
377                                 {
378 //                                      menu_popup->get_popup()->draw_9segment(MENUITEM_MARGIN,
379 //                                              y,
380 //                                              menu_popup->get_w() - MENUITEM_MARGIN * 2,
381 //                                              h,
382 //                                              menu_popup->item_bg[MENUITEM_HI]);
383                                         menu_popup->get_popup()->draw_3segmenth(MENUITEM_MARGIN,
384                                                 y,
385                                                 menu_popup->get_w() - MENUITEM_MARGIN * 2,
386                                                 menu_popup->item_bg[MENUITEM_HI]);
387                                 }
388                                 else
389                                 {
390                                         menu_popup->get_popup()->set_color(resources->menu_highlighted);
391                                         menu_popup->get_popup()->draw_box(MENUITEM_MARGIN,
392                                                 y,
393                                                 menu_popup->get_w() - MENUITEM_MARGIN * 2,
394                                                 h);
395                                 }
396                         }
397                         menu_popup->get_popup()->set_color(resources->menu_highlighted_fontcolor);
398                 }
399                 else
400                   {
401                 menu_popup->get_popup()->set_color(resources->menu_item_text);
402                   }
403                 if(checked)
404                 {
405 //                      menu_popup->get_popup()->draw_check(10 + offset, y + 2 + offset);
406                         menu_popup->get_popup()->draw_pixmap(menu_popup->check,
407                                 offset, 
408                                 y + (this->h - menu_popup->check->get_h()) / 2 + offset);
409                         menu_popup->get_popup()->set_font(MEDIUMFONT);
410                         menu_popup->get_popup()->draw_text(menu_popup->check->get_w() + offset, 
411                                 y + h - text_line - 2 + offset, 
412                                 text);
413                         menu_popup->get_popup()->draw_text(menu_popup->get_key_x() + offset, 
414                                 y + h - text_line - 2 + offset, 
415                                 hotkey_text);
416                 }
417                 else
418                 {
419                         menu_popup->get_popup()->set_font(MEDIUMFONT);
420                         menu_popup->get_popup()->draw_text(10 + offset, y + h - text_line - 2 + offset, text);
421                         menu_popup->get_popup()->draw_text(menu_popup->get_key_x() + offset, y + h - text_line - 2 + offset, hotkey_text);
422                 }
423         }
424         return 0;
425 }
426
427
428 int BC_MenuItem::add_submenu(BC_SubMenu *submenu)
429 {
430         this->submenu = submenu;
431         submenu->initialize(top_level, menu_bar, 0, this, 0);
432         return 0;
433 }
434
435 BC_SubMenu* BC_MenuItem::get_submenu()
436 {
437         return submenu;
438 }
439
440 char* BC_MenuItem::get_text()
441 {
442         return text;
443 }
444
445 BC_WindowBase* BC_MenuItem::get_top_level()
446 {
447         return top_level;
448 }
449
450 BC_PopupMenu* BC_MenuItem::get_popup_menu()
451 {
452         return menu_popup->popup_menu;
453 }
454
455 int BC_MenuItem::set_shift(int value)
456 {
457         shift_hotkey = value;
458         return 0;
459 }
460
461 int BC_MenuItem::set_alt(int value)
462 {
463         alt_hotkey = value;
464         return 0;
465 }
466
467 void BC_MenuItem::set_ctrl(int value)
468 {
469         ctrl_hotkey = value;
470 }
471