improve delays created by vicon drawing locks, reset_cache segv fix, gang track toolt...
[goodguy/cinelerra.git] / cinelerra-5.1 / guicast / bcmenu.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 "bcmenu.h"
23 #include "bcmenubar.h"
24 #include "bcmenuitem.h"
25 #include "bcmenupopup.h"
26 #include "bcpixmap.h"
27 #include "bcresources.h"
28 #include "bcsignals.h"
29 #include <string.h>
30
31
32
33 // ==================================== Menu ===================================
34
35 BC_Menu::BC_Menu(const char *text)
36 {
37         strcpy(this->text, text);
38         menu_bar = 0;
39         active = 0;
40         highlighted = 0;
41 }
42
43 BC_Menu::~BC_Menu()
44 {
45         delete menu_popup;
46 }
47
48 int BC_Menu::initialize(BC_WindowBase *top_level,
49                 BC_MenuBar *menu_bar, int x, int y, int w, int h)
50 {
51         this->x = x;
52         this->y = y;
53         this->w = w;
54         this->h = h;
55         this->menu_bar = menu_bar;
56         this->top_level = top_level;
57         menu_popup = new BC_MenuPopup;
58         menu_popup->initialize(top_level, menu_bar, this, 0, 0);
59         draw_title(1, 0);
60         return 0;
61 }
62
63 int BC_Menu::add_item(BC_MenuItem* menuitem)
64 {
65         menu_popup->add_item(menuitem);
66         return 0;
67 }
68
69 int BC_Menu::del_item(BC_MenuItem *item)
70 {
71         menu_popup->del_item(item);
72         return 0;
73 }
74
75 int BC_Menu::total_items()
76 {
77         return menu_popup->total_items();
78 }
79
80 int BC_Menu::dispatch_button_press()
81 {
82         int result = 0;
83
84 // Menu is down so dispatch to popup
85         if(active)
86         {
87                 result = menu_popup->dispatch_button_press();
88         }
89
90 // Try title.
91         if(!result)
92         {
93                 if(top_level->event_win == menu_bar->win &&
94                         top_level->cursor_x >= x && top_level->cursor_x < x + w &&
95                         top_level->cursor_y >= y && top_level->cursor_y < y + h)
96                 {
97                         if(!active)
98                         {
99                                 menu_bar->deactivate();
100                                 menu_bar->unhighlight();
101                                 menu_bar->button_releases = 0;
102                                 menu_bar->activate();
103                                 activate_menu();
104                         }
105                         result = 1;
106                 }
107         }
108         return result;
109 }
110
111 int BC_Menu::dispatch_button_release()
112 {
113 // try the title
114         int result = 0;
115         if(top_level->event_win == menu_bar->win &&
116                 top_level->cursor_x >= x && top_level->cursor_y < x + w &&
117                 top_level->cursor_y >= y && top_level->cursor_y < y + h)
118         {
119                 if(menu_bar->button_releases >= 2)
120                 {
121                         highlighted = 1;
122                         menu_bar->deactivate();
123                 }
124                 result = 1;
125         }
126         else
127 // try the popup
128                 result = menu_popup->dispatch_button_release();
129         return result;
130 }
131
132 int BC_Menu::dispatch_keypress()
133 {
134         return menu_popup->dispatch_key_press();
135 }
136
137 int BC_Menu::dispatch_motion_event()
138 {
139         int result = 0;
140         int cursor_x = 0, cursor_y = 0;
141
142 // try the popup
143         if(active)
144         {
145                 result = menu_popup->dispatch_motion_event();
146         }
147
148         if(!result && top_level->match_window(top_level->event_win))
149         {
150                 top_level->translate_coordinates(top_level->event_win,
151                         menu_bar->win,
152                         top_level->cursor_x,
153                         top_level->cursor_y,
154                         &cursor_x,
155                         &cursor_y);
156
157 // change focus from other menu
158                 if(menu_bar->active && !active &&
159                         cursor_x >= x && cursor_x < x + w &&
160                         cursor_y >= y && cursor_y < y + h)
161                 {
162                         menu_bar->activate();
163                         activate_menu();
164                         result = 1;
165                 }
166                 else
167 // control highlighting
168                 if(highlighted)
169                 {
170                         if(cursor_x < x || cursor_x >= x + w ||
171                                 cursor_y < y || cursor_y >= y + h)
172                         {
173                                 highlighted = 0;
174                                 draw_title(1, 1);
175                         }
176                 }
177                 else
178                 {
179                         if(cursor_x >= x && cursor_x < x + w &&
180                                 cursor_y >= y && cursor_y < y + h)
181                         {
182                                 menu_bar->unhighlight();
183                                 highlighted = 1;
184                                 draw_title(1, 1);
185                                 result = 1;
186                         }
187                 }
188         }
189         return result;
190 }
191
192 int BC_Menu::dispatch_cursor_leave()
193 {
194         if(active)
195         {
196 //              if( !menu_popup->cursor_inside() )
197 //                      deactivate_menu();
198                 menu_popup->dispatch_cursor_leave();
199         }
200         unhighlight();
201         return 0;
202 }
203
204 int BC_Menu::dispatch_translation_event()
205 {
206         if(active)
207         {
208                 menu_popup->dispatch_translation_event();
209         }
210         return 0;
211 }
212
213 int BC_Menu::activate_menu()
214 {
215         Window tempwin;
216         int new_x, new_y;
217         if(menu_bar)
218         {
219                 XTranslateCoordinates(top_level->display,
220                         menu_bar->win,
221                         top_level->rootwin,
222                         x,
223                         y,
224                         &new_x,
225                         &new_y,
226                         &tempwin);
227                 menu_popup->activate_menu(new_x, new_y, w, h, 0, 1);
228         }
229         else
230                 menu_popup->activate_menu(x, y, w, h, 1, 1);
231
232         active = 1;
233         draw_title(1, 1);
234         return 0;
235 }
236
237 void BC_Menu::draw_items()
238 {
239         if(active) menu_popup->draw_items();
240 }
241
242 int BC_Menu::set_text(char *text)
243 {
244         strcpy(this->text, text);
245         draw_title(1, 1);
246         return 0;
247 }
248
249 int BC_Menu::draw_title(int flash, int flush)
250 {
251         BC_Resources *resources = top_level->get_resources();
252         int text_offset = 0;
253
254         if(active && menu_popup)
255         {
256 // Menu is pulled down and title is recessed.
257
258                 if(menu_bar->menu_title_bg[0])
259                 {
260
261                         menu_bar->draw_9segment(x, 0, w, menu_bar->get_h(), menu_bar->menu_title_bg[2]);
262                 }
263                 else
264                 {
265                         menu_bar->draw_3d_box(x, y, w, h,
266                                 resources->menu_shadow,
267                                 BLACK,
268                                 resources->menu_down,
269                                 resources->menu_down,
270                                 resources->menu_light);
271                 }
272                 text_offset = 1;
273         }
274         else
275 // Menu is not pulled down.
276         {
277                 if(highlighted)
278                 {
279
280                         if(menu_bar->menu_title_bg[0])
281                         {
282
283                                 menu_bar->draw_9segment(x, 0, w, menu_bar->get_h(), menu_bar->menu_title_bg[1]);
284                         }
285                         else
286                         {
287                                 menu_bar->set_color(resources->menu_highlighted);
288                                 menu_bar->draw_box(x, y, w, h);
289                         }
290                 }
291                 else
292                 {
293
294                         if(menu_bar->menu_title_bg[0])
295                         {
296
297                                 menu_bar->draw_9segment(x, 0, w, menu_bar->get_h(), menu_bar->menu_title_bg[0]);
298                         }
299                         else
300                         {
301                                 menu_bar->draw_background(x, y, w, h);
302                         }
303                 }
304         }
305
306         menu_bar->set_color(resources->menu_title_text);
307         menu_bar->set_font(MEDIUMFONT);
308         menu_bar->draw_text(x + xS(10) + text_offset,
309                 h / 2 + menu_bar->get_text_ascent(MEDIUMFONT) / 2 + 1 + text_offset,
310                 text);
311         if(flash) menu_bar->flash(flush);
312
313         return 0;
314 }
315
316 int BC_Menu::deactivate_menu()
317 {
318         if(active)
319         {
320                 menu_popup->deactivate_menu();
321                 active = 0;
322                 draw_title(1, 1);
323         }
324         return 0;
325 }
326
327 int BC_Menu::unhighlight()
328 {
329         if(highlighted)
330         {
331                 highlighted = 0;
332                 draw_title(1, 1);
333         }
334         return 0;
335 }