rework keyframe hide popup, keyframe auto render, textbox set_selection wide text
[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                 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->activate_menu(new_x + 5, new_y, menu_popup->w - 10, h, 0, 0);
153                 highlighted = 1;
154         }
155         return 0;
156 }
157
158
159 int BC_MenuItem::dispatch_button_press()
160 {
161         int result = 0;
162
163         if(submenu)
164         {
165                 result = submenu->dispatch_button_press();
166         }
167
168         if(!result && top_level->event_win == menu_popup->get_popup()->win)
169         {
170                 if(top_level->cursor_x >= 0 && top_level->cursor_x < menu_popup->get_w() &&
171                         top_level->cursor_y >= y && top_level->cursor_y < y + h)
172                 {
173                         if(!highlighted)
174                         {
175                                 highlighted = 1;
176                         }
177                         result = 1;
178                 }
179                 else
180                 if(highlighted)
181                 {
182                         highlighted = 0;
183                         result = 1;
184                 }
185         }
186
187         return result;
188 }
189
190 int BC_MenuItem::dispatch_button_release(int &redraw)
191 {
192         int result = 0;
193         int cursor_x, cursor_y;
194         Window tempwin;
195
196         if(!strcmp(text, "-")) return 0;
197
198         if(submenu)
199         {
200                 result = submenu->dispatch_button_release();
201         }
202
203         if(!result)
204         {
205                 XTranslateCoordinates(top_level->display,
206                         top_level->event_win,
207                         menu_popup->get_popup()->win,
208                         top_level->cursor_x,
209                         top_level->cursor_y,
210                         &cursor_x,
211                         &cursor_y,
212                         &tempwin);
213
214                 if(cursor_x >= 0 && cursor_x < menu_popup->get_w() &&
215                         cursor_y >= y && cursor_y < y + h)
216                 {
217                         if(menu_bar)
218                                 menu_bar->deactivate();
219                         else
220                                 menu_popup->popup_menu->deactivate();
221
222                         if(!handle_event() && menu_popup && menu_popup->popup_menu)
223                         {
224                                 menu_popup->popup_menu->set_text(text);
225                                 menu_popup->popup_menu->handle_event();
226                         }
227                         return 1;
228                 }
229         }
230         return 0;
231 }
232
233 int BC_MenuItem::dispatch_motion_event(int &redraw)
234 {
235         int result = 0;
236         int cursor_x, cursor_y;
237
238         if(submenu)
239         {
240                 result = submenu->dispatch_motion_event();
241         }
242
243         top_level->translate_coordinates(top_level->event_win,
244                 menu_popup->get_popup()->win,
245                 top_level->cursor_x,
246                 top_level->cursor_y,
247                 &cursor_x,
248                 &cursor_y);
249
250         if(cursor_x >= 0 && cursor_x < menu_popup->get_w() &&
251                 cursor_y >= y && cursor_y < y + h)
252         {
253 // Highlight the item
254                 if(!highlighted)
255                 {
256 // Deactivate submenus in the parent menu excluding this one.
257                         menu_popup->deactivate_submenus(submenu);
258                         highlighted = 1;
259                         if(submenu) activate_submenu();
260                         redraw = 1;
261                 }
262                 result = 1;
263         }
264         else
265         if(highlighted)
266         {
267                 highlighted = 0;
268                 result = 1;
269                 redraw = 1;
270         }
271         return result;
272 }
273
274 int BC_MenuItem::dispatch_translation_event()
275 {
276         if(submenu)
277                 submenu->dispatch_translation_event();
278         return 0;
279 }
280
281 int BC_MenuItem::dispatch_cursor_leave()
282 {
283         int result = 0;
284         if(submenu)
285         {
286                 result = submenu->dispatch_cursor_leave();
287         }
288
289         if(!result && highlighted && top_level->event_win == menu_popup->get_popup()->win)
290         {
291                 highlighted = 0;
292                 return 1;
293         }
294         return 0;
295 }
296
297 int BC_MenuItem::dispatch_key_press()
298 {
299         int result = 0;
300         if(submenu)
301         {
302                 result = submenu->dispatch_key_press();
303         }
304
305         if(!result)
306         {
307
308                 if(top_level->get_keypress() == hotkey &&
309                         shift_hotkey == top_level->shift_down() &&
310                         alt_hotkey == top_level->alt_down() &&
311                         ctrl_hotkey == top_level->ctrl_down())
312                 {
313                         result = 1;
314                         handle_event();
315                 }
316         }
317         return result;
318 }
319
320
321 int BC_MenuItem::draw()
322 {
323         int text_line = top_level->get_text_descent(MEDIUMFONT);
324         BC_Resources *resources = top_level->get_resources();
325
326         if(!strcmp(text, "-"))
327         {
328                 menu_popup->get_popup()->set_color(DKGREY);
329                 menu_popup->get_popup()->draw_line(5, y + h / 2, menu_popup->get_w() - 5, y + h / 2);
330                 menu_popup->get_popup()->set_color(LTGREY);
331                 menu_popup->get_popup()->draw_line(5, y + h / 2 + 1, menu_popup->get_w() - 5, y + h / 2 + 1);
332         }
333         else
334         {
335                 int offset = 0;
336                 if(highlighted)
337                 {
338                         int y = this->y;
339                         //int w = menu_popup->get_w() - 4;
340                         int h = this->h;
341
342 // Button down
343                         if(top_level->get_button_down() && !submenu)
344                         {
345                                 if(menu_popup->item_bg[MENUITEM_DN])
346                                 {
347 //                                      menu_popup->get_popup()->draw_9segment(MENUITEM_MARGIN,
348 //                                              y,
349 //                                              menu_popup->get_w() - MENUITEM_MARGIN * 2,
350 //                                              h,
351 //                                              menu_popup->item_bg[MENUITEM_DN]);
352                                         menu_popup->get_popup()->draw_3segmenth(MENUITEM_MARGIN,
353                                                 y,
354                                                 menu_popup->get_w() - MENUITEM_MARGIN * 2,
355                                                 menu_popup->item_bg[MENUITEM_DN]);
356                                 }
357                                 else
358                                 {
359                                         menu_popup->get_popup()->draw_3d_box(MENUITEM_MARGIN,
360                                                 y,
361                                                 menu_popup->get_w() - MENUITEM_MARGIN * 2,
362                                                 h,
363                                                 resources->menu_shadow,
364                                                 BLACK,
365                                                 resources->menu_down,
366                                                 resources->menu_down,
367                                                 resources->menu_light);
368                                 }
369                                 offset = 1;
370                         }
371                         else
372 // Highlighted
373                         {
374                                 if(menu_popup->item_bg[MENUITEM_HI])
375                                 {
376 //                                      menu_popup->get_popup()->draw_9segment(MENUITEM_MARGIN,
377 //                                              y,
378 //                                              menu_popup->get_w() - MENUITEM_MARGIN * 2,
379 //                                              h,
380 //                                              menu_popup->item_bg[MENUITEM_HI]);
381                                         menu_popup->get_popup()->draw_3segmenth(MENUITEM_MARGIN,
382                                                 y,
383                                                 menu_popup->get_w() - MENUITEM_MARGIN * 2,
384                                                 menu_popup->item_bg[MENUITEM_HI]);
385                                 }
386                                 else
387                                 {
388                                         menu_popup->get_popup()->set_color(resources->menu_highlighted);
389                                         menu_popup->get_popup()->draw_box(MENUITEM_MARGIN,
390                                                 y,
391                                                 menu_popup->get_w() - MENUITEM_MARGIN * 2,
392                                                 h);
393                                 }
394                         }
395                         menu_popup->get_popup()->set_color(resources->menu_highlighted_fontcolor);
396                 }
397                 else
398                   {
399                 menu_popup->get_popup()->set_color(resources->menu_item_text);
400                   }
401                 if(checked)
402                 {
403 //                      menu_popup->get_popup()->draw_check(10 + offset, y + 2 + offset);
404                         menu_popup->get_popup()->draw_pixmap(menu_popup->check,
405                                 offset, 
406                                 y + (this->h - menu_popup->check->get_h()) / 2 + offset);
407                         menu_popup->get_popup()->set_font(MEDIUMFONT);
408                         menu_popup->get_popup()->draw_text(menu_popup->check->get_w() + offset, 
409                                 y + h - text_line - 2 + offset, 
410                                 text);
411                         menu_popup->get_popup()->draw_text(menu_popup->get_key_x() + offset, 
412                                 y + h - text_line - 2 + offset, 
413                                 hotkey_text);
414                 }
415                 else
416                 {
417                         menu_popup->get_popup()->set_font(MEDIUMFONT);
418                         menu_popup->get_popup()->draw_text(10 + offset, y + h - text_line - 2 + offset, text);
419                         menu_popup->get_popup()->draw_text(menu_popup->get_key_x() + offset, y + h - text_line - 2 + offset, hotkey_text);
420                 }
421         }
422         return 0;
423 }
424
425
426 int BC_MenuItem::add_submenu(BC_SubMenu *submenu)
427 {
428         this->submenu = submenu;
429         submenu->initialize(top_level, menu_bar, 0, this, 0);
430         return 0;
431 }
432
433 char* BC_MenuItem::get_text()
434 {
435         return text;
436 }
437
438 BC_WindowBase* BC_MenuItem::get_top_level()
439 {
440         return top_level;
441 }
442
443 BC_PopupMenu* BC_MenuItem::get_popup_menu()
444 {
445         return menu_popup->popup_menu;
446 }
447
448 int BC_MenuItem::set_shift(int value)
449 {
450         shift_hotkey = value;
451         return 0;
452 }
453
454 int BC_MenuItem::set_alt(int value)
455 {
456         alt_hotkey = value;
457         return 0;
458 }
459
460 void BC_MenuItem::set_ctrl(int value)
461 {
462         ctrl_hotkey = value;
463 }
464