initial commit
[goodguy/history.git] / cinelerra-5.0 / 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 "bcwindowbase.h"
30 #include "colors.h"
31
32 #include <string.h>
33
34
35 #define MENUITEM_UP 0
36 #define MENUITEM_HI 1
37 #define MENUITEM_DN 2
38
39
40 #define MENUITEM_MARGIN 2
41
42 // ================================ Menu Item ==================================
43
44 BC_MenuItem::BC_MenuItem(const char *text, const char *hotkey_text, int hotkey)
45 {
46         reset();
47
48         if(text) set_text(text);
49         if(hotkey_text) set_hotkey_text(hotkey_text);
50
51         this->hotkey = hotkey;
52         checked = 0;
53         highlighted = 0;
54         down = 0;
55         submenu = 0;
56         shift_hotkey = 0;
57         alt_hotkey = 0;
58         ctrl_hotkey = 0;
59         menu_popup = 0;
60 }
61
62 BC_MenuItem::~BC_MenuItem()
63 {
64         if(text) delete [] text;
65         text = 0;
66         if(hotkey_text) delete [] hotkey_text;
67         hotkey_text = 0;
68         if(submenu) delete submenu;
69         submenu = 0;
70 // deletes this
71         if(menu_popup) menu_popup->remove_item(this, 1);
72 }
73
74 void BC_MenuItem::reset()
75 {
76         text = new char[1];
77         hotkey_text = new char[1];
78         text[0] = 0;
79         hotkey_text[0] = 0;
80         icon = 0;
81 }
82
83 int BC_MenuItem::initialize(BC_WindowBase *top_level, BC_MenuBar *menu_bar, BC_MenuPopup *menu_popup)
84 {
85         this->top_level = top_level;
86         this->menu_popup = menu_popup;
87         this->menu_bar = menu_bar;
88         return 0;
89 }
90
91 int BC_MenuItem::set_checked(int value)
92 {
93         this->checked = value;
94         return 0;
95 }
96
97 int BC_MenuItem::get_checked()
98 {
99         return checked;
100 }
101
102 void BC_MenuItem::set_icon(BC_Pixmap *icon)
103 {
104         this->icon = icon;
105 }
106
107 BC_Pixmap* BC_MenuItem::get_icon()
108 {
109         return icon;
110 }
111
112 void BC_MenuItem::set_text(const char *text)
113 {
114         if(this->text) delete [] this->text;
115         this->text = new char[strlen(text) + 1];
116         strcpy(this->text, text);
117 }
118
119 void BC_MenuItem::set_hotkey_text(const char *text)
120 {
121         if(this->hotkey_text) delete [] this->hotkey_text;
122         this->hotkey_text = new char[strlen(text) + 1];
123         strcpy(this->hotkey_text, text);
124 }
125
126 int BC_MenuItem::deactivate_submenus(BC_MenuPopup *exclude)
127 {
128         if(submenu && submenu != exclude)
129         {
130                 submenu->deactivate_submenus(exclude);
131                 submenu->deactivate_menu();
132                 highlighted = 0;
133         }
134         return 0;
135 }
136
137 int BC_MenuItem::activate_submenu()
138 {
139         int new_x, new_y;
140         if(menu_popup->popup && submenu && !submenu->popup)
141         {
142                 Window tempwin;
143                 XTranslateCoordinates(top_level->display,
144                         menu_popup->get_popup()->win,
145                         top_level->rootwin,
146                         0,
147                         y,
148                         &new_x,
149                         &new_y,
150                         &tempwin);
151                 submenu->activate_menu(new_x + 5, new_y, menu_popup->w - 10, h, 0, 0);
152                 highlighted = 1;
153         }
154         return 0;
155 }
156
157
158 int BC_MenuItem::dispatch_button_press()
159 {
160         int result = 0;
161
162         if(submenu)
163         {
164                 result = submenu->dispatch_button_press();
165         }
166
167         if(!result && top_level->event_win == menu_popup->get_popup()->win)
168         {
169                 if(top_level->cursor_x >= 0 && top_level->cursor_x < menu_popup->get_w() &&
170                         top_level->cursor_y >= y && top_level->cursor_y < y + h)
171                 {
172                         if(!highlighted)
173                         {
174                                 highlighted = 1;
175                         }
176                         result = 1;
177                 }
178                 else
179                 if(highlighted)
180                 {
181                         highlighted = 0;
182                         result = 1;
183                 }
184         }
185
186         return result;
187 }
188
189 int BC_MenuItem::dispatch_button_release(int &redraw)
190 {
191         int result = 0;
192         int cursor_x, cursor_y;
193         Window tempwin;
194
195         if(!strcmp(text, "-")) return 0;
196
197         if(submenu)
198         {
199                 result = submenu->dispatch_button_release();
200         }
201
202         if(!result)
203         {
204                 XTranslateCoordinates(top_level->display,
205                         top_level->event_win,
206                         menu_popup->get_popup()->win,
207                         top_level->cursor_x,
208                         top_level->cursor_y,
209                         &cursor_x,
210                         &cursor_y,
211                         &tempwin);
212
213                 if(cursor_x >= 0 && cursor_x < menu_popup->get_w() &&
214                         cursor_y >= y && cursor_y < y + h)
215                 {
216                         if(menu_bar)
217                                 menu_bar->deactivate();
218                         else
219                                 menu_popup->popup_menu->deactivate();
220
221                         if(!handle_event() && menu_popup && menu_popup->popup_menu)
222                         {
223                                 menu_popup->popup_menu->set_text(text);
224                                 menu_popup->popup_menu->handle_event();
225                         }
226                         return 1;
227                 }
228         }
229         return 0;
230 }
231
232 int BC_MenuItem::dispatch_motion_event(int &redraw)
233 {
234         int result = 0;
235         int cursor_x, cursor_y;
236
237         if(submenu)
238         {
239                 result = submenu->dispatch_motion_event();
240         }
241
242         top_level->translate_coordinates(top_level->event_win,
243                 menu_popup->get_popup()->win,
244                 top_level->cursor_x,
245                 top_level->cursor_y,
246                 &cursor_x,
247                 &cursor_y);
248
249         if(cursor_x >= 0 && cursor_x < menu_popup->get_w() &&
250                 cursor_y >= y && cursor_y < y + h)
251         {
252 // Highlight the item
253                 if(!highlighted)
254                 {
255 // Deactivate submenus in the parent menu excluding this one.
256                         menu_popup->deactivate_submenus(submenu);
257                         highlighted = 1;
258                         if(submenu) activate_submenu();
259                         redraw = 1;
260                 }
261                 result = 1;
262         }
263         else
264         if(highlighted)
265         {
266                 highlighted = 0;
267                 result = 1;
268                 redraw = 1;
269         }
270         return result;
271 }
272
273 int BC_MenuItem::dispatch_translation_event()
274 {
275         if(submenu)
276                 submenu->dispatch_translation_event();
277         return 0;
278 }
279
280 int BC_MenuItem::dispatch_cursor_leave()
281 {
282         int result = 0;
283         if(submenu)
284         {
285                 result = submenu->dispatch_cursor_leave();
286         }
287
288         if(!result && highlighted && top_level->event_win == menu_popup->get_popup()->win)
289         {
290                 highlighted = 0;
291                 return 1;
292         }
293         return 0;
294 }
295
296 int BC_MenuItem::dispatch_key_press()
297 {
298         int result = 0;
299         if(submenu)
300         {
301                 result = submenu->dispatch_key_press();
302         }
303
304         if(!result)
305         {
306
307                 if(top_level->get_keypress() == hotkey &&
308                         shift_hotkey == top_level->shift_down() &&
309                         alt_hotkey == top_level->alt_down() &&
310                         ctrl_hotkey == top_level->ctrl_down())
311                 {
312                         result = 1;
313                         handle_event();
314                 }
315         }
316         return result;
317 }
318
319
320 int BC_MenuItem::draw()
321 {
322         int text_line = top_level->get_text_descent(MEDIUMFONT);
323         BC_Resources *resources = top_level->get_resources();
324
325         if(!strcmp(text, "-"))
326         {
327                 menu_popup->get_popup()->set_color(DKGREY);
328                 menu_popup->get_popup()->draw_line(5, y + h / 2, menu_popup->get_w() - 5, y + h / 2);
329                 menu_popup->get_popup()->set_color(LTGREY);
330                 menu_popup->get_popup()->draw_line(5, y + h / 2 + 1, menu_popup->get_w() - 5, y + h / 2 + 1);
331         }
332         else
333         {
334                 int offset = 0;
335                 if(highlighted)
336                 {
337                         int y = this->y;
338                         //int w = menu_popup->get_w() - 4;
339                         int h = this->h;
340
341 // Button down
342                         if(top_level->get_button_down() && !submenu)
343                         {
344                                 if(menu_popup->item_bg[MENUITEM_DN])
345                                 {
346                                         menu_popup->get_popup()->draw_9segment(MENUITEM_MARGIN,
347                                                 y,
348                                                 menu_popup->get_w() - MENUITEM_MARGIN * 2,
349                                                 h,
350                                                 menu_popup->item_bg[MENUITEM_DN]);
351                                 }
352                                 else
353                                 {
354                                         menu_popup->get_popup()->draw_3d_box(MENUITEM_MARGIN,
355                                                 y,
356                                                 menu_popup->get_w() - MENUITEM_MARGIN * 2,
357                                                 h,
358                                                 resources->menu_shadow,
359                                                 BLACK,
360                                                 resources->menu_down,
361                                                 resources->menu_down,
362                                                 resources->menu_light);
363                                 }
364                                 offset = 1;
365                         }
366                         else
367 // Highlighted
368                         {
369                                 if(menu_popup->item_bg[MENUITEM_HI])
370                                 {
371                                         menu_popup->get_popup()->draw_9segment(MENUITEM_MARGIN,
372                                                 y,
373                                                 menu_popup->get_w() - MENUITEM_MARGIN * 2,
374                                                 h,
375                                                 menu_popup->item_bg[MENUITEM_HI]);
376                                 }
377                                 else
378                                 {
379                                         menu_popup->get_popup()->set_color(resources->menu_highlighted);
380                                         menu_popup->get_popup()->draw_box(MENUITEM_MARGIN,
381                                                 y,
382                                                 menu_popup->get_w() - MENUITEM_MARGIN * 2,
383                                                 h);
384                                 }
385                         }
386                         menu_popup->get_popup()->set_color(resources->menu_highlighted_fontcolor);
387                 }
388                 else
389                   {
390                 menu_popup->get_popup()->set_color(resources->menu_item_text);
391                   }
392                 if(checked)
393                 {
394                         menu_popup->get_popup()->draw_check(10 + offset, y + 2 + offset);
395                         menu_popup->get_popup()->set_font(MEDIUMFONT);
396                         menu_popup->get_popup()->draw_text(30 + offset, y + h - text_line - 2 + offset, text);
397                         menu_popup->get_popup()->draw_text(menu_popup->get_key_x() + offset, y + h - text_line - 2 + offset, hotkey_text);
398                 }
399                 else
400                 {
401                         menu_popup->get_popup()->set_font(MEDIUMFONT);
402                         menu_popup->get_popup()->draw_text(10 + offset, y + h - text_line - 2 + offset, text);
403                         menu_popup->get_popup()->draw_text(menu_popup->get_key_x() + offset, y + h - text_line - 2 + offset, hotkey_text);
404                 }
405         }
406         return 0;
407 }
408
409
410 int BC_MenuItem::add_submenu(BC_SubMenu *submenu)
411 {
412         this->submenu = submenu;
413         submenu->initialize(top_level, menu_bar, 0, this, 0);
414         return 0;
415 }
416
417 char* BC_MenuItem::get_text()
418 {
419         return text;
420 }
421
422 BC_WindowBase* BC_MenuItem::get_top_level()
423 {
424         return top_level;
425 }
426
427 BC_PopupMenu* BC_MenuItem::get_popup_menu()
428 {
429         return menu_popup->popup_menu;
430 }
431
432 int BC_MenuItem::set_shift(int value)
433 {
434         shift_hotkey = value;
435         return 0;
436 }
437
438 int BC_MenuItem::set_alt(int value)
439 {
440         alt_hotkey = value;
441         return 0;
442 }
443
444 void BC_MenuItem::set_ctrl(int value)
445 {
446         ctrl_hotkey = value;
447 }
448