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