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