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