Mercurial > vim
annotate src/gui_athena.c @ 11044:eb3a2ff3309a v8.0.0411
patch 8.0.0411: menu translations don't match when case is changed.
commit https://github.com/vim/vim/commit/11dd8c1201033dd74e2ea665ba277425b4b965b0
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Mar 4 20:41:34 2017 +0100
patch 8.0.0411: menu translations don't match when case is changed.
Problem: We can't change the case in menu entries, it breaks translations.
Solution: Ignore case when looking up a menu translation.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 04 Mar 2017 20:45:05 +0100 |
parents | 90af0c60d78d |
children | 68d7bc045dbe |
rev | line source |
---|---|
10042
4aead6a9b7a9
commit https://github.com/vim/vim/commit/edf3f97ae2af024708ebb4ac614227327033ca47
Christian Brabandt <cb@256bit.org>
parents:
7825
diff
changeset
|
1 /* vi:set ts=8 sts=4 sw=4 noet: |
7 | 2 * |
3 * VIM - Vi IMproved by Bram Moolenaar | |
4 * GUI/Motif support by Robert Webb | |
5 * Athena port by Bill Foster | |
6 * | |
7 * Do ":help uganda" in Vim to read copying and usage conditions. | |
8 * Do ":help credits" in Vim to see a list of people who contributed. | |
9 * See README.txt for an overview of the Vim source code. | |
10 */ | |
11 | |
10956
90af0c60d78d
patch 8.0.0367: types in include files may be inconsistent
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
12 #include "vim.h" |
90af0c60d78d
patch 8.0.0367: types in include files may be inconsistent
Christian Brabandt <cb@256bit.org>
parents:
10042
diff
changeset
|
13 |
7 | 14 #include <X11/StringDefs.h> |
15 #include <X11/Intrinsic.h> | |
16 #ifdef FEAT_GUI_NEXTAW | |
17 # include <X11/neXtaw/Form.h> | |
18 # include <X11/neXtaw/SimpleMenu.h> | |
19 # include <X11/neXtaw/MenuButton.h> | |
20 # include <X11/neXtaw/SmeBSB.h> | |
21 # include <X11/neXtaw/SmeLine.h> | |
22 # include <X11/neXtaw/Box.h> | |
23 # include <X11/neXtaw/Dialog.h> | |
24 # include <X11/neXtaw/Text.h> | |
25 # include <X11/neXtaw/AsciiText.h> | |
26 # include <X11/neXtaw/Scrollbar.h> | |
27 #else | |
28 # include <X11/Xaw/Form.h> | |
29 # include <X11/Xaw/SimpleMenu.h> | |
30 # include <X11/Xaw/MenuButton.h> | |
31 # include <X11/Xaw/SmeBSB.h> | |
32 # include <X11/Xaw/SmeLine.h> | |
33 # include <X11/Xaw/Box.h> | |
34 # include <X11/Xaw/Dialog.h> | |
35 # include <X11/Xaw/Text.h> | |
36 # include <X11/Xaw/AsciiText.h> | |
37 #endif /* FEAT_GUI_NEXTAW */ | |
38 | |
39 #ifndef FEAT_GUI_NEXTAW | |
40 # include "gui_at_sb.h" | |
41 #endif | |
42 | |
43 extern Widget vimShell; | |
44 | |
45 static Widget vimForm = (Widget)0; | |
215 | 46 Widget textArea = (Widget)0; |
7 | 47 #ifdef FEAT_MENU |
48 static Widget menuBar = (Widget)0; | |
49 static XtIntervalId timer = 0; /* 0 = expired, otherwise active */ | |
50 | |
51 /* Used to figure out menu ordering */ | |
52 static vimmenu_T *a_cur_menu = NULL; | |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
53 static Cardinal athena_calculate_ins_pos(Widget); |
7 | 54 |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
55 static Pixmap gui_athena_create_pullright_pixmap(Widget); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
56 static void gui_athena_menu_timeout(XtPointer, XtIntervalId *); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
57 static void gui_athena_popup_callback(Widget, XtPointer, XtPointer); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
58 static void gui_athena_delayed_arm_action(Widget, XEvent *, String *, |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
59 Cardinal *); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
60 static void gui_athena_popdown_submenus_action(Widget, XEvent *, |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
61 String *, Cardinal *); |
7 | 62 static XtActionsRec pullAction[2] = { |
63 { "menu-delayedpopup", (XtActionProc)gui_athena_delayed_arm_action}, | |
64 { "menu-popdownsubmenus", (XtActionProc)gui_athena_popdown_submenus_action} | |
65 }; | |
66 #endif | |
67 | |
68 #ifdef FEAT_TOOLBAR | |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
69 static void gui_mch_reset_focus(void); |
7 | 70 static Widget toolBar = (Widget)0; |
71 #endif | |
72 | |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
73 static void gui_athena_scroll_cb_jump(Widget, XtPointer, XtPointer); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
74 static void gui_athena_scroll_cb_scroll(Widget, XtPointer, XtPointer); |
7 | 75 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_MENU) |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
76 static void gui_athena_menu_colors(Widget id); |
7 | 77 #endif |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
78 static void gui_athena_scroll_colors(Widget id); |
7 | 79 |
80 #ifdef FEAT_MENU | |
81 static XtTranslations popupTrans, parentTrans, menuTrans, supermenuTrans; | |
82 static Pixmap pullerBitmap = None; | |
83 static int puller_width = 0; | |
84 #endif | |
85 | |
86 /* | |
87 * Scrollbar callback (XtNjumpProc) for when the scrollbar is dragged with the | |
88 * left or middle mouse button. | |
89 */ | |
90 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
91 gui_athena_scroll_cb_jump( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
92 Widget w UNUSED, |
7825
7898da204b98
commit https://github.com/vim/vim/commit/02fdaeaa697fb5af4ba7fee6e209b3c2c825bb4f
Christian Brabandt <cb@256bit.org>
parents:
7821
diff
changeset
|
93 XtPointer client_data, |
7898da204b98
commit https://github.com/vim/vim/commit/02fdaeaa697fb5af4ba7fee6e209b3c2c825bb4f
Christian Brabandt <cb@256bit.org>
parents:
7821
diff
changeset
|
94 XtPointer call_data) |
7 | 95 { |
96 scrollbar_T *sb, *sb_info; | |
97 long value; | |
98 | |
99 sb = gui_find_scrollbar((long)client_data); | |
100 | |
101 if (sb == NULL) | |
102 return; | |
103 else if (sb->wp != NULL) /* Left or right scrollbar */ | |
104 { | |
105 /* | |
106 * Careful: need to get scrollbar info out of first (left) scrollbar | |
107 * for window, but keep real scrollbar too because we must pass it to | |
108 * gui_drag_scrollbar(). | |
109 */ | |
110 sb_info = &sb->wp->w_scrollbars[0]; | |
111 } | |
112 else /* Bottom scrollbar */ | |
113 sb_info = sb; | |
114 | |
115 value = (long)(*((float *)call_data) * (float)(sb_info->max + 1) + 0.001); | |
116 if (value > sb_info->max) | |
117 value = sb_info->max; | |
118 | |
119 gui_drag_scrollbar(sb, value, TRUE); | |
120 } | |
121 | |
122 /* | |
123 * Scrollbar callback (XtNscrollProc) for paging up or down with the left or | |
124 * right mouse buttons. | |
125 */ | |
126 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
127 gui_athena_scroll_cb_scroll( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
128 Widget w UNUSED, |
7825
7898da204b98
commit https://github.com/vim/vim/commit/02fdaeaa697fb5af4ba7fee6e209b3c2c825bb4f
Christian Brabandt <cb@256bit.org>
parents:
7821
diff
changeset
|
129 XtPointer client_data, |
7898da204b98
commit https://github.com/vim/vim/commit/02fdaeaa697fb5af4ba7fee6e209b3c2c825bb4f
Christian Brabandt <cb@256bit.org>
parents:
7821
diff
changeset
|
130 XtPointer call_data) |
7 | 131 { |
132 scrollbar_T *sb, *sb_info; | |
133 long value; | |
134 int data = (int)(long)call_data; | |
135 int page; | |
136 | |
137 sb = gui_find_scrollbar((long)client_data); | |
138 | |
139 if (sb == NULL) | |
140 return; | |
141 if (sb->wp != NULL) /* Left or right scrollbar */ | |
142 { | |
143 /* | |
144 * Careful: need to get scrollbar info out of first (left) scrollbar | |
145 * for window, but keep real scrollbar too because we must pass it to | |
146 * gui_drag_scrollbar(). | |
147 */ | |
148 sb_info = &sb->wp->w_scrollbars[0]; | |
149 | |
150 if (sb_info->size > 5) | |
151 page = sb_info->size - 2; /* use two lines of context */ | |
152 else | |
153 page = sb_info->size; | |
154 #ifdef FEAT_GUI_NEXTAW | |
155 if (data < 0) | |
156 { | |
157 data = (data - gui.char_height + 1) / gui.char_height; | |
158 if (data > -sb_info->size) | |
159 data = -1; | |
160 else | |
161 data = -page; | |
162 } | |
163 else if (data > 0) | |
164 { | |
165 data = (data + gui.char_height - 1) / gui.char_height; | |
166 if (data < sb_info->size) | |
167 data = 1; | |
168 else | |
169 data = page; | |
170 } | |
171 #else | |
172 switch (data) | |
173 { | |
174 case ONE_LINE_DATA: data = 1; break; | |
175 case -ONE_LINE_DATA: data = -1; break; | |
176 case ONE_PAGE_DATA: data = page; break; | |
177 case -ONE_PAGE_DATA: data = -page; break; | |
178 case END_PAGE_DATA: data = sb_info->max; break; | |
179 case -END_PAGE_DATA: data = -sb_info->max; break; | |
180 default: data = 0; break; | |
181 } | |
182 #endif | |
183 } | |
184 else /* Bottom scrollbar */ | |
185 { | |
186 sb_info = sb; | |
187 #ifdef FEAT_GUI_NEXTAW | |
188 if (data < 0) | |
189 { | |
190 data = (data - gui.char_width + 1) / gui.char_width; | |
191 if (data > -sb->size) | |
192 data = -1; | |
193 } | |
194 else if (data > 0) | |
195 { | |
196 data = (data + gui.char_width - 1) / gui.char_width; | |
197 if (data < sb->size) | |
198 data = 1; | |
199 } | |
200 #endif | |
201 if (data < -1) /* page-width left */ | |
202 { | |
203 if (sb->size > 8) | |
204 data = -(sb->size - 5); | |
205 else | |
206 data = -sb->size; | |
207 } | |
208 else if (data > 1) /* page-width right */ | |
209 { | |
210 if (sb->size > 8) | |
211 data = (sb->size - 5); | |
212 else | |
213 data = sb->size; | |
214 } | |
215 } | |
216 | |
217 value = sb_info->value + data; | |
218 if (value > sb_info->max) | |
219 value = sb_info->max; | |
220 else if (value < 0) | |
221 value = 0; | |
222 | |
223 /* Update the bottom scrollbar an extra time (why is this needed?? */ | |
224 if (sb->wp == NULL) /* Bottom scrollbar */ | |
225 gui_mch_set_scrollbar_thumb(sb, value, sb->size, sb->max); | |
226 | |
227 gui_drag_scrollbar(sb, value, FALSE); | |
228 } | |
229 | |
230 /* | |
231 * Create all the Athena widgets necessary. | |
232 */ | |
233 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
234 gui_x11_create_widgets(void) |
7 | 235 { |
236 /* | |
237 * We don't have any borders handled internally by the textArea to worry | |
238 * about so only skip over the configured border width. | |
239 */ | |
240 gui.border_offset = gui.border_width; | |
241 | |
242 /* The form containing all the other widgets */ | |
243 vimForm = XtVaCreateManagedWidget("vimForm", | |
244 formWidgetClass, vimShell, | |
245 XtNborderWidth, 0, | |
246 NULL); | |
247 gui_athena_scroll_colors(vimForm); | |
248 | |
249 #ifdef FEAT_MENU | |
250 /* The top menu bar */ | |
251 menuBar = XtVaCreateManagedWidget("menuBar", | |
252 boxWidgetClass, vimForm, | |
253 XtNresizable, True, | |
254 XtNtop, XtChainTop, | |
255 XtNbottom, XtChainTop, | |
256 XtNleft, XtChainLeft, | |
257 XtNright, XtChainRight, | |
258 XtNinsertPosition, athena_calculate_ins_pos, | |
259 NULL); | |
260 gui_athena_menu_colors(menuBar); | |
261 if (gui.menu_fg_pixel != INVALCOLOR) | |
262 XtVaSetValues(menuBar, XtNborderColor, gui.menu_fg_pixel, NULL); | |
263 #endif | |
264 | |
265 #ifdef FEAT_TOOLBAR | |
266 /* Don't create it Managed, it will be managed when creating the first | |
267 * item. Otherwise an empty toolbar shows up. */ | |
268 toolBar = XtVaCreateWidget("toolBar", | |
269 boxWidgetClass, vimForm, | |
270 XtNresizable, True, | |
271 XtNtop, XtChainTop, | |
272 XtNbottom, XtChainTop, | |
273 XtNleft, XtChainLeft, | |
274 XtNright, XtChainRight, | |
275 XtNorientation, XtorientHorizontal, | |
276 XtNhSpace, 1, | |
277 XtNvSpace, 3, | |
278 XtNinsertPosition, athena_calculate_ins_pos, | |
279 NULL); | |
280 gui_athena_menu_colors(toolBar); | |
281 #endif | |
282 | |
283 /* The text area. */ | |
284 textArea = XtVaCreateManagedWidget("textArea", | |
285 coreWidgetClass, vimForm, | |
286 XtNresizable, True, | |
287 XtNtop, XtChainTop, | |
288 XtNbottom, XtChainTop, | |
289 XtNleft, XtChainLeft, | |
290 XtNright, XtChainLeft, | |
291 XtNbackground, gui.back_pixel, | |
292 XtNborderWidth, 0, | |
293 NULL); | |
294 | |
295 /* | |
296 * Install the callbacks. | |
297 */ | |
298 gui_x11_callbacks(textArea, vimForm); | |
299 | |
300 #ifdef FEAT_MENU | |
301 popupTrans = XtParseTranslationTable( | |
302 "<EnterWindow>: menu-popdownsubmenus() highlight() menu-delayedpopup()\n" | |
303 "<LeaveWindow>: unhighlight()\n" | |
304 "<BtnUp>: menu-popdownsubmenus() XtMenuPopdown() notify() unhighlight()\n" | |
305 "<Motion>: highlight() menu-delayedpopup()"); | |
306 parentTrans = XtParseTranslationTable("<LeaveWindow>: unhighlight()"); | |
307 menuTrans = XtParseTranslationTable( | |
308 "<EnterWindow>: menu-popdownsubmenus() highlight() menu-delayedpopup()\n" | |
309 "<LeaveWindow>: menu-popdownsubmenus() XtMenuPopdown() unhighlight()\n" | |
310 "<BtnUp>: notify() unhighlight()\n" | |
311 "<BtnMotion>: highlight() menu-delayedpopup()"); | |
312 supermenuTrans = XtParseTranslationTable( | |
313 "<EnterWindow>: menu-popdownsubmenus() highlight() menu-delayedpopup()\n" | |
314 "<LeaveWindow>: unhighlight()\n" | |
315 "<BtnUp>: menu-popdownsubmenus() XtMenuPopdown() notify() unhighlight()\n" | |
316 "<BtnMotion>: highlight() menu-delayedpopup()"); | |
317 | |
318 XtAppAddActions(XtWidgetToApplicationContext(vimForm), pullAction, | |
319 XtNumber(pullAction)); | |
320 #endif | |
321 | |
322 /* Pretend we don't have input focus, we will get an event if we do. */ | |
323 gui.in_focus = FALSE; | |
324 } | |
325 | |
326 #ifdef FEAT_MENU | |
327 /* | |
328 * Calculates the Pixmap based on the size of the current menu font. | |
329 */ | |
330 static Pixmap | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
331 gui_athena_create_pullright_pixmap(Widget w) |
7 | 332 { |
333 Pixmap retval; | |
334 #ifdef FONTSET_ALWAYS | |
335 XFontSet font = None; | |
336 #else | |
337 XFontStruct *font = NULL; | |
338 #endif | |
339 | |
340 #ifdef FONTSET_ALWAYS | |
341 if (gui.menu_fontset == NOFONTSET) | |
342 #else | |
343 if (gui.menu_font == NOFONT) | |
344 #endif | |
345 { | |
346 XrmValue from, to; | |
347 WidgetList children; | |
348 Cardinal num_children; | |
349 | |
350 #ifdef FONTSET_ALWAYS | |
351 from.size = strlen(from.addr = XtDefaultFontSet); | |
352 to.addr = (XtPointer)&font; | |
353 to.size = sizeof(XFontSet); | |
354 #else | |
355 from.size = strlen(from.addr = XtDefaultFont); | |
356 to.addr = (XtPointer)&font; | |
357 to.size = sizeof(XFontStruct *); | |
358 #endif | |
359 /* Assumption: The menuBar children will use the same font as the | |
360 * pulldown menu items AND they will all be of type | |
361 * XtNfont. | |
362 */ | |
363 XtVaGetValues(menuBar, XtNchildren, &children, | |
364 XtNnumChildren, &num_children, | |
365 NULL); | |
366 if (XtConvertAndStore(w ? w : | |
367 (num_children > 0) ? children[0] : menuBar, | |
368 XtRString, &from, | |
369 #ifdef FONTSET_ALWAYS | |
370 XtRFontSet, &to | |
371 #else | |
372 XtRFontStruct, &to | |
373 #endif | |
374 ) == False) | |
375 return None; | |
376 /* "font" should now contain data */ | |
377 } | |
378 else | |
379 #ifdef FONTSET_ALWAYS | |
380 font = (XFontSet)gui.menu_fontset; | |
381 #else | |
382 font = (XFontStruct *)gui.menu_font; | |
383 #endif | |
384 | |
385 { | |
386 int width, height; | |
387 GC draw_gc, undraw_gc; | |
388 XGCValues gc_values; | |
389 XPoint points[3]; | |
390 | |
391 #ifdef FONTSET_ALWAYS | |
392 height = fontset_height2(font); | |
393 #else | |
394 height = font->max_bounds.ascent + font->max_bounds.descent; | |
395 #endif | |
396 width = height - 2; | |
397 puller_width = width + 4; | |
398 retval = XCreatePixmap(gui.dpy,DefaultRootWindow(gui.dpy),width, | |
399 height, 1); | |
400 gc_values.foreground = 1; | |
401 gc_values.background = 0; | |
402 draw_gc = XCreateGC(gui.dpy, retval, | |
403 GCForeground | GCBackground, | |
404 &gc_values); | |
405 gc_values.foreground = 0; | |
406 gc_values.background = 1; | |
407 undraw_gc = XCreateGC(gui.dpy, retval, | |
408 GCForeground | GCBackground, | |
409 &gc_values); | |
410 points[0].x = 0; | |
411 points[0].y = 0; | |
412 points[1].x = width - 1; | |
413 points[1].y = (height - 1) / 2; | |
414 points[2].x = 0; | |
415 points[2].y = height - 1; | |
416 XFillRectangle(gui.dpy, retval, undraw_gc, 0, 0, height, height); | |
417 XFillPolygon(gui.dpy, retval, draw_gc, points, XtNumber(points), | |
418 Convex, CoordModeOrigin); | |
419 XFreeGC(gui.dpy, draw_gc); | |
420 XFreeGC(gui.dpy, undraw_gc); | |
421 } | |
422 return retval; | |
423 } | |
424 #endif | |
425 | |
426 /* | |
427 * Called when the GUI is not going to start after all. | |
428 */ | |
429 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
430 gui_x11_destroy_widgets(void) |
7 | 431 { |
432 textArea = NULL; | |
433 #ifdef FEAT_MENU | |
434 menuBar = NULL; | |
435 #endif | |
436 #ifdef FEAT_TOOLBAR | |
437 toolBar = NULL; | |
438 #endif | |
439 } | |
440 | |
441 #if defined(FEAT_TOOLBAR) || defined(PROTO) | |
47 | 442 # include "gui_x11_pm.h" |
443 # ifdef HAVE_X11_XPM_H | |
444 # include <X11/xpm.h> | |
445 # endif | |
446 | |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
447 static void createXpmImages(char_u *path, char **xpm, Pixmap *sen); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
448 static void get_toolbar_pixmap(vimmenu_T *menu, Pixmap *sen); |
47 | 449 |
450 /* | |
451 * Allocated a pixmap for toolbar menu "menu". | |
452 * Return in "sen". | |
453 */ | |
454 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
455 get_toolbar_pixmap(vimmenu_T *menu, Pixmap *sen) |
47 | 456 { |
457 char_u buf[MAXPATHL]; /* buffer storing expanded pathname */ | |
458 char **xpm = NULL; /* xpm array */ | |
459 | |
460 buf[0] = NUL; /* start with NULL path */ | |
461 | |
462 if (menu->iconfile != NULL) | |
463 { | |
464 /* Use the "icon=" argument. */ | |
465 gui_find_iconfile(menu->iconfile, buf, "xpm"); | |
466 createXpmImages(buf, NULL, sen); | |
467 | |
468 /* If it failed, try using the menu name. */ | |
469 if (*sen == (Pixmap)0 && gui_find_bitmap(menu->name, buf, "xpm") == OK) | |
470 createXpmImages(buf, NULL, sen); | |
471 if (*sen != (Pixmap)0) | |
472 return; | |
473 } | |
474 | |
475 if (menu->icon_builtin || gui_find_bitmap(menu->name, buf, "xpm") == FAIL) | |
476 { | |
477 if (menu->iconidx >= 0 && menu->iconidx | |
1887 | 478 < (int)(sizeof(built_in_pixmaps) / sizeof(built_in_pixmaps[0]))) |
47 | 479 xpm = built_in_pixmaps[menu->iconidx]; |
480 else | |
481 xpm = tb_blank_xpm; | |
482 } | |
483 | |
484 if (xpm != NULL || buf[0] != NUL) | |
485 createXpmImages(buf, xpm, sen); | |
486 } | |
487 | |
488 /* | |
489 * Read an Xpm file, doing color substitutions for the foreground and | |
490 * background colors. If there is an error reading a color xpm file, | |
491 * drop back and read the monochrome file. If successful, create the | |
492 * insensitive Pixmap too. | |
493 */ | |
494 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
495 createXpmImages(char_u *path, char **xpm, Pixmap *sen) |
47 | 496 { |
497 Window rootWindow; | |
498 XpmAttributes attrs; | |
499 XpmColorSymbol color[5] = | |
500 { | |
501 {"none", "none", 0}, | |
502 {"iconColor1", NULL, 0}, | |
503 {"bottomShadowColor", NULL, 0}, | |
504 {"topShadowColor", NULL, 0}, | |
505 {"selectColor", NULL, 0} | |
506 }; | |
507 int screenNum; | |
508 int status; | |
509 Pixmap mask; | |
510 Pixmap map; | |
511 | |
512 gui_mch_get_toolbar_colors( | |
513 &color[BACKGROUND].pixel, | |
514 &color[FOREGROUND].pixel, | |
515 &color[BOTTOM_SHADOW].pixel, | |
516 &color[TOP_SHADOW].pixel, | |
517 &color[HIGHLIGHT].pixel); | |
518 | |
4352 | 519 /* Setup the color substitution table */ |
47 | 520 attrs.valuemask = XpmColorSymbols; |
521 attrs.colorsymbols = color; | |
522 attrs.numsymbols = 5; | |
523 | |
524 screenNum = DefaultScreen(gui.dpy); | |
525 rootWindow = RootWindow(gui.dpy, screenNum); | |
526 | |
527 /* Create the "sensitive" pixmap */ | |
528 if (xpm != NULL) | |
529 status = XpmCreatePixmapFromData(gui.dpy, rootWindow, xpm, | |
530 &map, &mask, &attrs); | |
531 else | |
532 status = XpmReadFileToPixmap(gui.dpy, rootWindow, (char *)path, | |
533 &map, &mask, &attrs); | |
534 if (status == XpmSuccess && map != 0) | |
535 { | |
536 XGCValues gcvalues; | |
537 GC back_gc; | |
538 GC mask_gc; | |
539 | |
540 /* Need to create new Pixmaps with the mask applied. */ | |
541 gcvalues.foreground = color[BACKGROUND].pixel; | |
542 back_gc = XCreateGC(gui.dpy, map, GCForeground, &gcvalues); | |
543 mask_gc = XCreateGC(gui.dpy, map, GCForeground, &gcvalues); | |
544 XSetClipMask(gui.dpy, mask_gc, mask); | |
545 | |
546 /* Create the "sensitive" pixmap. */ | |
547 *sen = XCreatePixmap(gui.dpy, rootWindow, | |
548 attrs.width, attrs.height, | |
549 DefaultDepth(gui.dpy, screenNum)); | |
550 XFillRectangle(gui.dpy, *sen, back_gc, 0, 0, | |
551 attrs.width, attrs.height); | |
552 XCopyArea(gui.dpy, map, *sen, mask_gc, 0, 0, | |
553 attrs.width, attrs.height, 0, 0); | |
554 | |
555 XFreeGC(gui.dpy, back_gc); | |
556 XFreeGC(gui.dpy, mask_gc); | |
557 XFreePixmap(gui.dpy, map); | |
558 } | |
559 else | |
560 *sen = 0; | |
561 | |
562 XpmFreeAttributes(&attrs); | |
563 } | |
564 | |
7 | 565 void |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
566 gui_mch_set_toolbar_pos( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
567 int x, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
568 int y, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
569 int w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
570 int h) |
7 | 571 { |
572 Dimension border; | |
573 int height; | |
574 | |
575 if (!XtIsManaged(toolBar)) /* nothing to do */ | |
576 return; | |
577 XtUnmanageChild(toolBar); | |
578 XtVaGetValues(toolBar, | |
579 XtNborderWidth, &border, | |
580 NULL); | |
581 height = h - 2 * border; | |
582 if (height < 0) | |
583 height = 1; | |
584 XtVaSetValues(toolBar, | |
585 XtNhorizDistance, x, | |
586 XtNvertDistance, y, | |
587 XtNwidth, w - 2 * border, | |
588 XtNheight, height, | |
589 NULL); | |
590 XtManageChild(toolBar); | |
591 } | |
592 #endif | |
593 | |
594 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
595 gui_mch_set_text_area_pos( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
596 int x, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
597 int y, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
598 int w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
599 int h) |
7 | 600 { |
601 XtUnmanageChild(textArea); | |
602 XtVaSetValues(textArea, | |
603 XtNhorizDistance, x, | |
604 XtNvertDistance, y, | |
605 XtNwidth, w, | |
606 XtNheight, h, | |
607 NULL); | |
608 XtManageChild(textArea); | |
609 #ifdef FEAT_TOOLBAR | |
610 /* Give keyboard focus to the textArea instead of the toolbar. */ | |
611 gui_mch_reset_focus(); | |
612 #endif | |
613 } | |
614 | |
615 #ifdef FEAT_TOOLBAR | |
616 /* | |
617 * A toolbar button has been pushed; now reset the input focus | |
618 * such that the user can type page up/down etc. and have the | |
619 * input go to the editor window, not the button | |
620 */ | |
621 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
622 gui_mch_reset_focus(void) |
7 | 623 { |
624 XtSetKeyboardFocus(vimForm, textArea); | |
625 } | |
626 #endif | |
627 | |
628 | |
629 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
630 gui_x11_set_back_color(void) |
7 | 631 { |
632 if (textArea != NULL) | |
633 XtVaSetValues(textArea, | |
634 XtNbackground, gui.back_pixel, | |
635 NULL); | |
636 } | |
637 | |
638 #if defined(FEAT_MENU) || defined(PROTO) | |
639 /* | |
640 * Menu stuff. | |
641 */ | |
642 | |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
643 static char_u *make_pull_name(char_u * name); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
644 static Widget get_popup_entry(Widget w); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
645 static Widget submenu_widget(Widget); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
646 static Boolean has_submenu(Widget); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
647 static void gui_mch_submenu_change(vimmenu_T *mp, int colors); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
648 static void gui_athena_menu_font(Widget id); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
649 static Boolean gui_athena_menu_has_submenus(Widget, Widget); |
7 | 650 |
651 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
652 gui_mch_enable_menu(int flag) |
7 | 653 { |
654 if (flag) | |
655 { | |
656 XtManageChild(menuBar); | |
657 # ifdef FEAT_TOOLBAR | |
658 if (XtIsManaged(toolBar)) | |
659 { | |
660 XtVaSetValues(toolBar, | |
661 XtNvertDistance, gui.menu_height, | |
662 NULL); | |
663 XtVaSetValues(textArea, | |
664 XtNvertDistance, gui.menu_height + gui.toolbar_height, | |
665 NULL); | |
666 } | |
667 # endif | |
668 } | |
669 else | |
670 { | |
671 XtUnmanageChild(menuBar); | |
672 # ifdef FEAT_TOOLBAR | |
673 if (XtIsManaged(toolBar)) | |
674 { | |
675 XtVaSetValues(toolBar, | |
676 XtNvertDistance, 0, | |
677 NULL); | |
678 } | |
679 # endif | |
680 } | |
681 } | |
682 | |
683 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
684 gui_mch_set_menu_pos( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
685 int x, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
686 int y, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
687 int w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
688 int h) |
7 | 689 { |
690 Dimension border; | |
691 int height; | |
692 | |
693 XtUnmanageChild(menuBar); | |
694 XtVaGetValues(menuBar, XtNborderWidth, &border, NULL); | |
695 /* avoid trouble when there are no menu items, and h is 1 */ | |
696 height = h - 2 * border; | |
697 if (height < 0) | |
698 height = 1; | |
699 XtVaSetValues(menuBar, | |
700 XtNhorizDistance, x, | |
701 XtNvertDistance, y, | |
702 XtNwidth, w - 2 * border, | |
703 XtNheight, height, | |
704 NULL); | |
705 XtManageChild(menuBar); | |
706 } | |
707 | |
708 /* | |
709 * Used to calculate the insertion position of a widget with respect to its | |
710 * neighbors. | |
711 * | |
712 * Valid range of return values is: 0 (beginning of children) to | |
713 * numChildren (end of children). | |
714 */ | |
715 static Cardinal | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
716 athena_calculate_ins_pos(Widget widget) |
7 | 717 { |
718 /* Assume that if the parent of the vimmenu_T is NULL, then we can get | |
719 * to this menu by traversing "next", starting at "root_menu". | |
720 * | |
721 * This holds true for popup menus, toolbar, and toplevel menu items. | |
722 */ | |
723 | |
724 /* Popup menus: "id" is NULL. Only submenu_id is valid */ | |
725 | |
726 /* Menus that are not toplevel: "parent" will be non-NULL, "id" & | |
727 * "submenu_id" will be non-NULL. | |
728 */ | |
729 | |
730 /* Toplevel menus: "parent" is NULL, id is the widget of the menu item */ | |
731 | |
732 WidgetList children; | |
733 Cardinal num_children = 0; | |
734 int retval; | |
735 Arg args[2]; | |
736 int n = 0; | |
737 int i; | |
738 | |
739 XtSetArg(args[n], XtNchildren, &children); n++; | |
740 XtSetArg(args[n], XtNnumChildren, &num_children); n++; | |
741 XtGetValues(XtParent(widget), args, n); | |
742 | |
743 retval = num_children; | |
1887 | 744 for (i = 0; i < (int)num_children; ++i) |
7 | 745 { |
746 Widget current = children[i]; | |
747 vimmenu_T *menu = NULL; | |
748 | |
749 for (menu = (a_cur_menu->parent == NULL) | |
750 ? root_menu : a_cur_menu->parent->children; | |
751 menu != NULL; | |
752 menu = menu->next) | |
753 if (current == menu->id | |
754 && a_cur_menu->priority < menu->priority | |
755 && i < retval) | |
756 retval = i; | |
757 } | |
758 return retval; | |
759 } | |
760 | |
761 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
762 gui_mch_add_menu(vimmenu_T *menu, int idx UNUSED) |
7 | 763 { |
764 char_u *pullright_name; | |
765 Dimension height, space, border; | |
766 vimmenu_T *parent = menu->parent; | |
767 | |
768 a_cur_menu = menu; | |
769 if (parent == NULL) | |
770 { | |
771 if (menu_is_popup(menu->dname)) | |
772 { | |
773 menu->submenu_id = XtVaCreatePopupShell((char *)menu->dname, | |
774 simpleMenuWidgetClass, vimShell, | |
775 XtNinsertPosition, athena_calculate_ins_pos, | |
776 XtNtranslations, popupTrans, | |
777 NULL); | |
778 gui_athena_menu_colors(menu->submenu_id); | |
779 } | |
780 else if (menu_is_menubar(menu->dname)) | |
781 { | |
782 menu->id = XtVaCreateManagedWidget((char *)menu->dname, | |
783 menuButtonWidgetClass, menuBar, | |
784 XtNmenuName, menu->dname, | |
785 #ifdef FONTSET_ALWAYS | |
786 XtNinternational, True, | |
787 #endif | |
788 NULL); | |
789 if (menu->id == (Widget)0) | |
790 return; | |
791 gui_athena_menu_colors(menu->id); | |
792 gui_athena_menu_font(menu->id); | |
793 | |
794 menu->submenu_id = XtVaCreatePopupShell((char *)menu->dname, | |
795 simpleMenuWidgetClass, menu->id, | |
796 XtNinsertPosition, athena_calculate_ins_pos, | |
797 XtNtranslations, supermenuTrans, | |
798 NULL); | |
799 gui_athena_menu_colors(menu->submenu_id); | |
800 gui_athena_menu_font(menu->submenu_id); | |
801 | |
802 /* Don't update the menu height when it was set at a fixed value */ | |
803 if (!gui.menu_height_fixed) | |
804 { | |
805 /* | |
806 * When we add a top-level item to the menu bar, we can figure | |
807 * out how high the menu bar should be. | |
808 */ | |
809 XtVaGetValues(menuBar, | |
810 XtNvSpace, &space, | |
811 XtNborderWidth, &border, | |
812 NULL); | |
813 XtVaGetValues(menu->id, | |
814 XtNheight, &height, | |
815 NULL); | |
816 gui.menu_height = height + 2 * (space + border); | |
817 } | |
818 } | |
819 } | |
820 else if (parent->submenu_id != (Widget)0) | |
821 { | |
822 menu->id = XtVaCreateManagedWidget((char *)menu->dname, | |
823 smeBSBObjectClass, parent->submenu_id, | |
824 XtNlabel, menu->dname, | |
825 #ifdef FONTSET_ALWAYS | |
826 XtNinternational, True, | |
827 #endif | |
828 NULL); | |
829 if (menu->id == (Widget)0) | |
830 return; | |
831 if (pullerBitmap == None) | |
832 pullerBitmap = gui_athena_create_pullright_pixmap(menu->id); | |
833 | |
834 XtVaSetValues(menu->id, XtNrightBitmap, pullerBitmap, | |
835 NULL); | |
836 /* If there are other menu items that are not pulldown menus, | |
837 * we need to adjust the right margins of those, too. | |
838 */ | |
839 { | |
840 WidgetList children; | |
841 Cardinal num_children; | |
842 int i; | |
843 | |
844 XtVaGetValues(parent->submenu_id, XtNchildren, &children, | |
845 XtNnumChildren, &num_children, | |
846 NULL); | |
1887 | 847 for (i = 0; i < (int)num_children; ++i) |
7 | 848 { |
849 XtVaSetValues(children[i], | |
850 XtNrightMargin, puller_width, | |
851 NULL); | |
852 } | |
853 } | |
854 gui_athena_menu_colors(menu->id); | |
855 gui_athena_menu_font(menu->id); | |
856 | |
857 pullright_name = make_pull_name(menu->dname); | |
858 menu->submenu_id = XtVaCreatePopupShell((char *)pullright_name, | |
859 simpleMenuWidgetClass, parent->submenu_id, | |
860 XtNtranslations, menuTrans, | |
861 NULL); | |
862 gui_athena_menu_colors(menu->submenu_id); | |
863 gui_athena_menu_font(menu->submenu_id); | |
864 vim_free(pullright_name); | |
865 XtAddCallback(menu->submenu_id, XtNpopupCallback, | |
866 gui_athena_popup_callback, (XtPointer)menu); | |
867 | |
868 if (parent->parent != NULL) | |
869 XtOverrideTranslations(parent->submenu_id, parentTrans); | |
870 } | |
871 a_cur_menu = NULL; | |
872 } | |
873 | |
874 /* Used to determine whether a SimpleMenu has pulldown entries. | |
875 * | |
876 * "id" is the parent of the menu items. | |
877 * Ignore widget "ignore" in the pane. | |
878 */ | |
879 static Boolean | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
880 gui_athena_menu_has_submenus(Widget id, Widget ignore) |
7 | 881 { |
882 WidgetList children; | |
883 Cardinal num_children; | |
884 int i; | |
885 | |
886 XtVaGetValues(id, XtNchildren, &children, | |
887 XtNnumChildren, &num_children, | |
888 NULL); | |
1887 | 889 for (i = 0; i < (int)num_children; ++i) |
7 | 890 { |
891 if (children[i] == ignore) | |
892 continue; | |
893 if (has_submenu(children[i])) | |
894 return True; | |
895 } | |
896 return False; | |
897 } | |
898 | |
899 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
900 gui_athena_menu_font(Widget id) |
7 | 901 { |
902 #ifdef FONTSET_ALWAYS | |
903 if (gui.menu_fontset != NOFONTSET) | |
904 { | |
905 if (XtIsManaged(id)) | |
906 { | |
907 XtUnmanageChild(id); | |
908 XtVaSetValues(id, XtNfontSet, gui.menu_fontset, NULL); | |
909 /* We should force the widget to recalculate it's | |
910 * geometry now. */ | |
911 XtManageChild(id); | |
912 } | |
913 else | |
914 XtVaSetValues(id, XtNfontSet, gui.menu_fontset, NULL); | |
915 if (has_submenu(id)) | |
916 XtVaSetValues(id, XtNrightBitmap, pullerBitmap, NULL); | |
917 } | |
918 #else | |
919 int managed = FALSE; | |
920 | |
921 if (gui.menu_font != NOFONT) | |
922 { | |
923 if (XtIsManaged(id)) | |
924 { | |
925 XtUnmanageChild(id); | |
926 managed = TRUE; | |
927 } | |
928 | |
929 # ifdef FEAT_XFONTSET | |
930 if (gui.fontset != NOFONTSET) | |
931 XtVaSetValues(id, XtNfontSet, gui.menu_font, NULL); | |
932 else | |
933 # endif | |
934 XtVaSetValues(id, XtNfont, gui.menu_font, NULL); | |
935 if (has_submenu(id)) | |
936 XtVaSetValues(id, XtNrightBitmap, pullerBitmap, NULL); | |
937 | |
938 /* Force the widget to recalculate it's geometry now. */ | |
939 if (managed) | |
940 XtManageChild(id); | |
941 } | |
942 #endif | |
943 } | |
944 | |
945 | |
946 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
947 gui_mch_new_menu_font(void) |
7 | 948 { |
949 Pixmap oldpuller = None; | |
950 | |
951 if (menuBar == (Widget)0) | |
952 return; | |
953 | |
954 if (pullerBitmap != None) | |
955 { | |
956 oldpuller = pullerBitmap; | |
957 pullerBitmap = gui_athena_create_pullright_pixmap(NULL); | |
958 } | |
959 gui_mch_submenu_change(root_menu, FALSE); | |
960 | |
961 { | |
962 /* Iterate through the menubar menu items and get the height of | |
963 * each one. The menu bar height is set to the maximum of all | |
964 * the heights. | |
965 */ | |
966 vimmenu_T *mp; | |
967 int max_height = 9999; | |
968 | |
969 for (mp = root_menu; mp != NULL; mp = mp->next) | |
970 { | |
971 if (menu_is_menubar(mp->dname)) | |
972 { | |
973 Dimension height; | |
974 | |
975 XtVaGetValues(mp->id, | |
125 | 976 XtNheight, &height, |
7 | 977 NULL); |
978 if (height < max_height) | |
979 max_height = height; | |
980 } | |
981 } | |
982 if (max_height != 9999) | |
983 { | |
984 /* Don't update the menu height when it was set at a fixed value */ | |
985 if (!gui.menu_height_fixed) | |
986 { | |
987 Dimension space, border; | |
988 | |
989 XtVaGetValues(menuBar, | |
990 XtNvSpace, &space, | |
991 XtNborderWidth, &border, | |
992 NULL); | |
993 gui.menu_height = max_height + 2 * (space + border); | |
994 } | |
995 } | |
996 } | |
997 /* Now, to simulate the window being resized. Only, this | |
998 * will resize the window to it's current state. | |
999 * | |
1000 * There has to be a better way, but I do not see one at this time. | |
1001 * (David Harrison) | |
1002 */ | |
1003 { | |
1004 Position w, h; | |
1005 | |
1006 XtVaGetValues(vimShell, | |
1007 XtNwidth, &w, | |
1008 XtNheight, &h, | |
1009 NULL); | |
1010 gui_resize_shell(w, h | |
1011 #ifdef FEAT_XIM | |
1012 - xim_get_status_area_height() | |
1013 #endif | |
1014 ); | |
1015 } | |
811 | 1016 gui_set_shellsize(FALSE, TRUE, RESIZE_VERT); |
7 | 1017 ui_new_shellsize(); |
1018 if (oldpuller != None) | |
1019 XFreePixmap(gui.dpy, oldpuller); | |
1020 } | |
1021 | |
1022 #if defined(FEAT_BEVAL) || defined(PROTO) | |
1023 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1024 gui_mch_new_tooltip_font(void) |
7 | 1025 { |
1026 # ifdef FEAT_TOOLBAR | |
1027 vimmenu_T *menu; | |
1028 | |
1029 if (toolBar == (Widget)0) | |
1030 return; | |
1031 | |
1032 menu = gui_find_menu((char_u *)"ToolBar"); | |
1033 if (menu != NULL) | |
1034 gui_mch_submenu_change(menu, FALSE); | |
1035 # endif | |
1036 } | |
1037 | |
1038 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1039 gui_mch_new_tooltip_colors(void) |
7 | 1040 { |
1041 # ifdef FEAT_TOOLBAR | |
1042 vimmenu_T *menu; | |
1043 | |
1044 if (toolBar == (Widget)0) | |
1045 return; | |
1046 | |
1047 menu = gui_find_menu((char_u *)"ToolBar"); | |
1048 if (menu != NULL) | |
1049 gui_mch_submenu_change(menu, TRUE); | |
1050 # endif | |
1051 } | |
1052 #endif | |
1053 | |
1054 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1055 gui_mch_submenu_change( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1056 vimmenu_T *menu, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1057 int colors) /* TRUE for colors, FALSE for font */ |
7 | 1058 { |
1059 vimmenu_T *mp; | |
1060 | |
1061 for (mp = menu; mp != NULL; mp = mp->next) | |
1062 { | |
1063 if (mp->id != (Widget)0) | |
1064 { | |
1065 if (colors) | |
1066 { | |
1067 gui_athena_menu_colors(mp->id); | |
1068 #ifdef FEAT_TOOLBAR | |
1069 /* For a toolbar item: Free the pixmap and allocate a new one, | |
1070 * so that the background color is right. */ | |
1071 if (mp->image != (Pixmap)0) | |
1072 { | |
1073 XFreePixmap(gui.dpy, mp->image); | |
47 | 1074 get_toolbar_pixmap(mp, &mp->image); |
7 | 1075 if (mp->image != (Pixmap)0) |
1076 XtVaSetValues(mp->id, XtNbitmap, mp->image, NULL); | |
1077 } | |
1078 | |
1079 # ifdef FEAT_BEVAL | |
1080 /* If we have a tooltip, then we need to change it's colors */ | |
1081 if (mp->tip != NULL) | |
1082 { | |
1083 Arg args[2]; | |
1084 | |
1085 args[0].name = XtNbackground; | |
1086 args[0].value = gui.tooltip_bg_pixel; | |
1087 args[1].name = XtNforeground; | |
1088 args[1].value = gui.tooltip_fg_pixel; | |
1089 XtSetValues(mp->tip->balloonLabel, &args[0], XtNumber(args)); | |
1090 } | |
1091 # endif | |
1092 #endif | |
1093 } | |
1094 else | |
1095 { | |
1096 gui_athena_menu_font(mp->id); | |
1097 #ifdef FEAT_BEVAL | |
1098 /* If we have a tooltip, then we need to change it's font */ | |
1099 /* Assume XtNinternational == True (in createBalloonEvalWindow) | |
1100 */ | |
1101 if (mp->tip != NULL) | |
1102 { | |
1103 Arg args[1]; | |
1104 | |
1105 args[0].name = XtNfontSet; | |
1106 args[0].value = (XtArgVal)gui.tooltip_fontset; | |
1107 XtSetValues(mp->tip->balloonLabel, &args[0], XtNumber(args)); | |
1108 } | |
1109 #endif | |
1110 } | |
1111 } | |
1112 | |
1113 if (mp->children != NULL) | |
1114 { | |
1115 /* Set the colors/font for the tear off widget */ | |
1116 if (mp->submenu_id != (Widget)0) | |
1117 { | |
1118 if (colors) | |
1119 gui_athena_menu_colors(mp->submenu_id); | |
1120 else | |
1121 gui_athena_menu_font(mp->submenu_id); | |
1122 } | |
1123 /* Set the colors for the children */ | |
1124 gui_mch_submenu_change(mp->children, colors); | |
1125 } | |
1126 } | |
1127 } | |
1128 | |
1129 /* | |
1130 * Make a submenu name into a pullright name. | |
1131 * Replace '.' by '_', can't include '.' in the submenu name. | |
1132 */ | |
1133 static char_u * | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1134 make_pull_name(char_u * name) |
7 | 1135 { |
1136 char_u *pname; | |
1137 char_u *p; | |
1138 | |
1139 pname = vim_strnsave(name, STRLEN(name) + strlen("-pullright")); | |
1140 if (pname != NULL) | |
1141 { | |
1142 strcat((char *)pname, "-pullright"); | |
1143 while ((p = vim_strchr(pname, '.')) != NULL) | |
1144 *p = '_'; | |
1145 } | |
1146 return pname; | |
1147 } | |
1148 | |
1149 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1150 gui_mch_add_menu_item(vimmenu_T *menu, int idx UNUSED) |
7 | 1151 { |
1152 vimmenu_T *parent = menu->parent; | |
1153 | |
1154 a_cur_menu = menu; | |
1155 # ifdef FEAT_TOOLBAR | |
1156 if (menu_is_toolbar(parent->name)) | |
1157 { | |
1158 WidgetClass type; | |
1159 int n; | |
1160 Arg args[21]; | |
1161 | |
1162 n = 0; | |
1163 if (menu_is_separator(menu->name)) | |
1164 { | |
1165 XtSetArg(args[n], XtNlabel, ""); n++; | |
1166 XtSetArg(args[n], XtNborderWidth, 0); n++; | |
1167 } | |
1168 else | |
1169 { | |
47 | 1170 get_toolbar_pixmap(menu, &menu->image); |
7 | 1171 XtSetArg(args[n], XtNlabel, menu->dname); n++; |
1172 XtSetArg(args[n], XtNinternalHeight, 1); n++; | |
1173 XtSetArg(args[n], XtNinternalWidth, 1); n++; | |
1174 XtSetArg(args[n], XtNborderWidth, 1); n++; | |
1175 if (menu->image != 0) | |
1176 XtSetArg(args[n], XtNbitmap, menu->image); n++; | |
1177 } | |
1178 XtSetArg(args[n], XtNhighlightThickness, 0); n++; | |
1179 type = commandWidgetClass; | |
1180 /* TODO: figure out the position in the toolbar? | |
1181 * This currently works fine for the default toolbar, but | |
1182 * what if we add/remove items during later runtime? | |
1183 */ | |
1184 | |
1185 /* NOTE: "idx" isn't used here. The position is calculated by | |
1186 * athena_calculate_ins_pos(). The position it calculates | |
1187 * should be equal to "idx". | |
1188 */ | |
1189 /* TODO: Could we just store "idx" and use that as the child | |
1190 * placement? | |
1191 */ | |
1192 | |
1193 if (menu->id == NULL) | |
1194 { | |
1195 menu->id = XtCreateManagedWidget((char *)menu->dname, | |
1196 type, toolBar, args, n); | |
1197 XtAddCallback(menu->id, | |
1198 XtNcallback, gui_x11_menu_cb, menu); | |
1199 } | |
1200 else | |
1201 XtSetValues(menu->id, args, n); | |
1202 gui_athena_menu_colors(menu->id); | |
1203 | |
1204 #ifdef FEAT_BEVAL | |
1205 gui_mch_menu_set_tip(menu); | |
1206 #endif | |
1207 | |
1208 menu->parent = parent; | |
1209 menu->submenu_id = NULL; | |
1210 if (!XtIsManaged(toolBar) | |
1211 && vim_strchr(p_go, GO_TOOLBAR) != NULL) | |
1212 gui_mch_show_toolbar(TRUE); | |
1213 gui.toolbar_height = gui_mch_compute_toolbar_height(); | |
1214 return; | |
1215 } /* toolbar menu item */ | |
1216 # endif | |
1217 | |
1218 /* Add menu separator */ | |
1219 if (menu_is_separator(menu->name)) | |
1220 { | |
1221 menu->submenu_id = (Widget)0; | |
1222 menu->id = XtVaCreateManagedWidget((char *)menu->dname, | |
1223 smeLineObjectClass, parent->submenu_id, | |
1224 NULL); | |
1225 if (menu->id == (Widget)0) | |
1226 return; | |
1227 gui_athena_menu_colors(menu->id); | |
1228 } | |
1229 else | |
1230 { | |
1231 if (parent != NULL && parent->submenu_id != (Widget)0) | |
1232 { | |
1233 menu->submenu_id = (Widget)0; | |
1234 menu->id = XtVaCreateManagedWidget((char *)menu->dname, | |
1235 smeBSBObjectClass, parent->submenu_id, | |
1236 XtNlabel, menu->dname, | |
1237 #ifdef FONTSET_ALWAYS | |
1238 XtNinternational, True, | |
1239 #endif | |
1240 NULL); | |
1241 if (menu->id == (Widget)0) | |
1242 return; | |
1243 | |
1244 /* If there are other "pulldown" items in this pane, then adjust | |
2255 | 1245 * the right margin to accommodate the arrow pixmap, otherwise |
7 | 1246 * the right margin will be the same as the left margin. |
1247 */ | |
1248 { | |
1249 Dimension left_margin; | |
1250 | |
1251 XtVaGetValues(menu->id, XtNleftMargin, &left_margin, NULL); | |
1252 XtVaSetValues(menu->id, XtNrightMargin, | |
1253 gui_athena_menu_has_submenus(parent->submenu_id, NULL) ? | |
1254 puller_width : | |
1255 left_margin, | |
1256 NULL); | |
1257 } | |
1258 | |
1259 gui_athena_menu_colors(menu->id); | |
1260 gui_athena_menu_font(menu->id); | |
1261 XtAddCallback(menu->id, XtNcallback, gui_x11_menu_cb, | |
1262 (XtPointer)menu); | |
1263 } | |
1264 } | |
1265 a_cur_menu = NULL; | |
1266 } | |
1267 | |
1268 #if defined(FEAT_TOOLBAR) || defined(PROTO) | |
1269 void | |
1270 gui_mch_show_toolbar(int showit) | |
1271 { | |
1272 Cardinal numChildren; /* how many children toolBar has */ | |
1273 | |
1274 if (toolBar == (Widget)0) | |
1275 return; | |
1276 XtVaGetValues(toolBar, XtNnumChildren, &numChildren, NULL); | |
1277 if (showit && numChildren > 0) | |
1278 { | |
1279 /* Assume that we want to show the toolbar if p_toolbar contains valid | |
1280 * option settings, therefore p_toolbar must not be NULL. | |
1281 */ | |
1282 WidgetList children; | |
1283 | |
1284 XtVaGetValues(toolBar, XtNchildren, &children, NULL); | |
1285 { | |
1286 void (*action)(BalloonEval *); | |
1287 int text = 0; | |
1288 | |
1289 if (strstr((const char *)p_toolbar, "tooltips")) | |
1290 action = &gui_mch_enable_beval_area; | |
1291 else | |
1292 action = &gui_mch_disable_beval_area; | |
1293 if (strstr((const char *)p_toolbar, "text")) | |
1294 text = 1; | |
1295 else if (strstr((const char *)p_toolbar, "icons")) | |
1296 text = -1; | |
1297 if (text != 0) | |
1298 { | |
1299 vimmenu_T *toolbar; | |
1300 vimmenu_T *cur; | |
1301 | |
1302 for (toolbar = root_menu; toolbar; toolbar = toolbar->next) | |
1303 if (menu_is_toolbar(toolbar->dname)) | |
1304 break; | |
1305 /* Assumption: toolbar is NULL if there is no toolbar, | |
1306 * otherwise it contains the toolbar menu structure. | |
1307 * | |
1308 * Assumption: "numChildren" == the number of items in the list | |
1309 * of items beginning with toolbar->children. | |
1310 */ | |
1311 if (toolbar) | |
1312 { | |
1313 for (cur = toolbar->children; cur; cur = cur->next) | |
1314 { | |
1315 Arg args[2]; | |
1316 int n = 0; | |
1317 | |
1318 /* Enable/Disable tooltip (OK to enable while currently | |
1319 * enabled) | |
1320 */ | |
1321 if (cur->tip != NULL) | |
1322 (*action)(cur->tip); | |
1323 if (text == 1) | |
1324 { | |
1325 XtSetArg(args[n], XtNbitmap, None); | |
1326 n++; | |
1327 XtSetArg(args[n], XtNlabel, | |
1328 menu_is_separator(cur->name) ? "" : | |
1329 (char *)cur->dname); | |
1330 n++; | |
1331 } | |
1332 else | |
1333 { | |
1334 XtSetArg(args[n], XtNbitmap, cur->image); | |
1335 n++; | |
1336 XtSetArg(args[n], XtNlabel, (cur->image == None) ? | |
1337 menu_is_separator(cur->name) ? | |
1338 "" : | |
1339 (char *)cur->dname | |
1340 : | |
1341 (char *)None); | |
1342 n++; | |
1343 } | |
1344 if (cur->id != NULL) | |
1345 { | |
1346 XtUnmanageChild(cur->id); | |
1347 XtSetValues(cur->id, args, n); | |
1348 XtManageChild(cur->id); | |
1349 } | |
1350 } | |
1351 } | |
1352 } | |
1353 } | |
1354 gui.toolbar_height = gui_mch_compute_toolbar_height(); | |
1355 XtManageChild(toolBar); | |
1356 if (XtIsManaged(menuBar)) | |
1357 { | |
1358 XtVaSetValues(textArea, | |
1359 XtNvertDistance, gui.toolbar_height + gui.menu_height, | |
1360 NULL); | |
1361 XtVaSetValues(toolBar, | |
1362 XtNvertDistance, gui.menu_height, | |
1363 NULL); | |
1364 } | |
1365 else | |
1366 { | |
1367 XtVaSetValues(textArea, | |
1368 XtNvertDistance, gui.toolbar_height, | |
1369 NULL); | |
1370 XtVaSetValues(toolBar, | |
1371 XtNvertDistance, 0, | |
1372 NULL); | |
1373 } | |
1374 } | |
1375 else | |
1376 { | |
1377 gui.toolbar_height = 0; | |
1378 if (XtIsManaged(menuBar)) | |
1379 XtVaSetValues(textArea, | |
1380 XtNvertDistance, gui.menu_height, | |
1381 NULL); | |
1382 else | |
1383 XtVaSetValues(textArea, | |
1384 XtNvertDistance, 0, | |
1385 NULL); | |
1386 | |
1387 XtUnmanageChild(toolBar); | |
1388 } | |
811 | 1389 gui_set_shellsize(FALSE, FALSE, RESIZE_VERT); |
7 | 1390 } |
1391 | |
1392 | |
1393 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1394 gui_mch_compute_toolbar_height(void) |
7 | 1395 { |
1396 Dimension height; /* total Toolbar height */ | |
1397 Dimension whgt; /* height of each widget */ | |
1398 Dimension marginHeight; /* XmNmarginHeight of toolBar */ | |
1399 Dimension shadowThickness; /* thickness of Xtparent(toolBar) */ | |
1400 WidgetList children; /* list of toolBar's children */ | |
1401 Cardinal numChildren; /* how many children toolBar has */ | |
1402 int i; | |
1403 | |
1404 height = 0; | |
1405 shadowThickness = 0; | |
1406 marginHeight = 0; | |
1407 if (toolBar != (Widget)0) | |
1408 { | |
1409 XtVaGetValues(toolBar, | |
1410 XtNborderWidth, &shadowThickness, | |
1411 XtNvSpace, &marginHeight, | |
1412 XtNchildren, &children, | |
1413 XtNnumChildren, &numChildren, | |
1414 NULL); | |
1887 | 1415 for (i = 0; i < (int)numChildren; i++) |
7 | 1416 { |
1417 whgt = 0; | |
1418 | |
1419 XtVaGetValues(children[i], XtNheight, &whgt, NULL); | |
1420 if (height < whgt) | |
1421 height = whgt; | |
1422 } | |
1423 } | |
1424 | |
1425 return (int)(height + (marginHeight << 1) + (shadowThickness << 1)); | |
1426 } | |
1427 | |
1428 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1429 gui_mch_get_toolbar_colors( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1430 Pixel *bgp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1431 Pixel *fgp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1432 Pixel *bsp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1433 Pixel *tsp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1434 Pixel *hsp) |
7 | 1435 { |
1436 XtVaGetValues(toolBar, XtNbackground, bgp, XtNborderColor, fgp, NULL); | |
1437 *bsp = *bgp; | |
1438 *tsp = *fgp; | |
1439 *hsp = *tsp; | |
1440 } | |
1441 #endif | |
1442 | |
1443 | |
1444 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1445 gui_mch_toggle_tearoffs(int enable UNUSED) |
7 | 1446 { |
1447 /* no tearoff menus */ | |
1448 } | |
1449 | |
1450 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1451 gui_mch_new_menu_colors(void) |
7 | 1452 { |
1453 if (menuBar == (Widget)0) | |
1454 return; | |
1455 if (gui.menu_fg_pixel != INVALCOLOR) | |
1456 XtVaSetValues(menuBar, XtNborderColor, gui.menu_fg_pixel, NULL); | |
1457 gui_athena_menu_colors(menuBar); | |
1458 #ifdef FEAT_TOOLBAR | |
1459 gui_athena_menu_colors(toolBar); | |
1460 #endif | |
1461 | |
1462 gui_mch_submenu_change(root_menu, TRUE); | |
1463 } | |
1464 | |
1465 /* | |
1466 * Destroy the machine specific menu widget. | |
1467 */ | |
1468 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1469 gui_mch_destroy_menu(vimmenu_T *menu) |
7 | 1470 { |
1471 Widget parent; | |
1472 | |
1473 /* There is no item for the toolbar. */ | |
1474 if (menu->id == (Widget)0) | |
1475 return; | |
1476 | |
1477 parent = XtParent(menu->id); | |
1478 | |
1479 /* When removing the last "pulldown" menu item from a pane, adjust the | |
1480 * right margins of the remaining widgets. | |
1481 */ | |
1482 if (menu->submenu_id != (Widget)0) | |
1483 { | |
1484 /* Go through the menu items in the parent of this item and | |
1485 * adjust their margins, if necessary. | |
1486 * This takes care of the case when we delete the last menu item in a | |
1487 * pane that has a submenu. In this case, there will be no arrow | |
1488 * pixmaps shown anymore. | |
1489 */ | |
1490 { | |
1491 WidgetList children; | |
1492 Cardinal num_children; | |
1493 int i; | |
1494 Dimension right_margin = 0; | |
1495 Boolean get_left_margin = False; | |
1496 | |
1497 XtVaGetValues(parent, XtNchildren, &children, | |
1498 XtNnumChildren, &num_children, | |
1499 NULL); | |
1500 if (gui_athena_menu_has_submenus(parent, menu->id)) | |
1501 right_margin = puller_width; | |
1502 else | |
1503 get_left_margin = True; | |
1504 | |
1887 | 1505 for (i = 0; i < (int)num_children; ++i) |
7 | 1506 { |
1507 if (children[i] == menu->id) | |
1508 continue; | |
1509 if (get_left_margin == True) | |
1510 { | |
1511 Dimension left_margin; | |
1512 | |
1513 XtVaGetValues(children[i], XtNleftMargin, &left_margin, | |
1514 NULL); | |
1515 XtVaSetValues(children[i], XtNrightMargin, left_margin, | |
1516 NULL); | |
1517 } | |
1518 else | |
1519 XtVaSetValues(children[i], XtNrightMargin, right_margin, | |
1520 NULL); | |
1521 } | |
1522 } | |
1523 } | |
1524 /* Please be sure to destroy the parent widget first (i.e. menu->id). | |
1525 * | |
1526 * This code should be basically identical to that in the file gui_motif.c | |
1527 * because they are both Xt based. | |
1528 */ | |
1529 if (menu->id != (Widget)0) | |
1530 { | |
1531 Cardinal num_children; | |
1532 Dimension height, space, border; | |
1533 | |
1534 XtVaGetValues(menuBar, | |
1535 XtNvSpace, &space, | |
1536 XtNborderWidth, &border, | |
1537 NULL); | |
1538 XtVaGetValues(menu->id, | |
1539 XtNheight, &height, | |
1540 NULL); | |
1541 #if defined(FEAT_TOOLBAR) && defined(FEAT_BEVAL) | |
1542 if (parent == toolBar && menu->tip != NULL) | |
1543 { | |
1544 /* We try to destroy this before the actual menu, because there are | |
1545 * callbacks, etc. that will be unregistered during the tooltip | |
1546 * destruction. | |
1547 * | |
1548 * If you call "gui_mch_destroy_beval_area()" after destroying | |
1549 * menu->id, then the tooltip's window will have already been | |
1550 * deallocated by Xt, and unknown behaviour will ensue (probably | |
1551 * a core dump). | |
1552 */ | |
1553 gui_mch_destroy_beval_area(menu->tip); | |
1554 menu->tip = NULL; | |
1555 } | |
1556 #endif | |
1557 /* | |
1558 * This is a hack to stop the Athena simpleMenuWidget from getting a | |
1559 * BadValue error when a menu's last child is destroyed. We check to | |
1560 * see if this is the last child and if so, don't delete it. The parent | |
1561 * will be deleted soon anyway, and it will delete it's children like | |
1562 * all good widgets do. | |
1563 */ | |
1564 /* NOTE: The cause of the BadValue X Protocol Error is because when the | |
1565 * last child is destroyed, it is first unmanaged, thus causing a | |
1566 * geometry resize request from the parent Shell widget. | |
1567 * Since the Shell widget has no more children, it is resized to have | |
1568 * width/height of 0. XConfigureWindow() is then called with the | |
1569 * width/height of 0, which generates the BadValue. | |
1570 * | |
1571 * This happens in phase two of the widget destruction process. | |
1572 */ | |
1573 { | |
1574 if (parent != menuBar | |
1575 #ifdef FEAT_TOOLBAR | |
1576 && parent != toolBar | |
1577 #endif | |
1578 ) | |
1579 { | |
1580 XtVaGetValues(parent, XtNnumChildren, &num_children, NULL); | |
1581 if (num_children > 1) | |
1582 XtDestroyWidget(menu->id); | |
1583 } | |
1584 else | |
1585 XtDestroyWidget(menu->id); | |
1586 menu->id = (Widget)0; | |
1587 } | |
1588 | |
1589 if (parent == menuBar) | |
1590 { | |
1591 if (!gui.menu_height_fixed) | |
1592 gui.menu_height = height + 2 * (space + border); | |
1593 } | |
1594 #ifdef FEAT_TOOLBAR | |
1595 else if (parent == toolBar) | |
1596 { | |
1597 /* When removing last toolbar item, don't display the toolbar. */ | |
1598 XtVaGetValues(toolBar, XtNnumChildren, &num_children, NULL); | |
1599 if (num_children == 0) | |
1600 gui_mch_show_toolbar(FALSE); | |
1601 else | |
1602 gui.toolbar_height = gui_mch_compute_toolbar_height(); | |
1603 } | |
1604 #endif | |
1605 } | |
1606 if (menu->submenu_id != (Widget)0) | |
1607 { | |
1608 XtDestroyWidget(menu->submenu_id); | |
1609 menu->submenu_id = (Widget)0; | |
1610 } | |
1611 } | |
1612 | |
1613 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1614 gui_athena_menu_timeout( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1615 XtPointer client_data, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1616 XtIntervalId *id UNUSED) |
7 | 1617 { |
1618 Widget w = (Widget)client_data; | |
1619 Widget popup; | |
1620 | |
1621 timer = 0; | |
1622 if (XtIsSubclass(w,smeBSBObjectClass)) | |
1623 { | |
1624 Pixmap p; | |
1625 | |
1626 XtVaGetValues(w, XtNrightBitmap, &p, NULL); | |
1627 if ((p != None) && (p != XtUnspecifiedPixmap)) | |
1628 { | |
1629 /* We are dealing with an item that has a submenu */ | |
1630 popup = get_popup_entry(XtParent(w)); | |
1631 if (popup == (Widget)0) | |
1632 return; | |
1633 XtPopup(popup, XtGrabNonexclusive); | |
1634 } | |
1635 } | |
1636 } | |
1637 | |
1638 /* This routine is used to calculate the position (in screen coordinates) | |
1639 * where a submenu should appear relative to the menu entry that popped it | |
1640 * up. It should appear even with and just slightly to the left of the | |
1641 * rightmost end of the menu entry that caused the popup. | |
1642 * | |
1643 * This is called when XtPopup() is called. | |
1644 */ | |
1645 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1646 gui_athena_popup_callback( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1647 Widget w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1648 XtPointer client_data, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1649 XtPointer call_data UNUSED) |
7 | 1650 { |
1651 /* Assumption: XtIsSubclass(XtParent(w),simpleMenuWidgetClass) */ | |
1652 vimmenu_T *menu = (vimmenu_T *)client_data; | |
1653 Dimension width; | |
1654 Position root_x, root_y; | |
1655 | |
1656 /* First, popdown any siblings that may have menus popped up */ | |
1657 { | |
1658 vimmenu_T *i; | |
1659 | |
1660 for (i = menu->parent->children; i != NULL; i = i->next) | |
1661 { | |
1662 if (i->submenu_id != NULL && XtIsManaged(i->submenu_id)) | |
1663 XtPopdown(i->submenu_id); | |
1664 } | |
1665 } | |
1666 XtVaGetValues(XtParent(w), | |
1667 XtNwidth, &width, | |
1668 NULL); | |
1669 /* Assumption: XawSimpleMenuGetActiveEntry(XtParent(w)) == menu->id */ | |
1670 /* i.e. This IS the active entry */ | |
1671 XtTranslateCoords(menu->id,width - 5, 0, &root_x, &root_y); | |
1672 XtVaSetValues(w, XtNx, root_x, | |
1673 XtNy, root_y, | |
1674 NULL); | |
1675 } | |
1676 | |
1677 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1678 gui_athena_popdown_submenus_action( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1679 Widget w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1680 XEvent *event, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1681 String *args, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1682 Cardinal *nargs) |
7 | 1683 { |
1684 WidgetList children; | |
1685 Cardinal num_children; | |
1686 | |
1687 XtVaGetValues(w, XtNchildren, &children, | |
1688 XtNnumChildren, &num_children, | |
1689 NULL); | |
1690 for (; num_children > 0; --num_children) | |
1691 { | |
1692 Widget child = children[num_children - 1]; | |
1693 | |
1694 if (has_submenu(child)) | |
1695 { | |
1696 Widget temp_w; | |
1697 | |
1698 temp_w = submenu_widget(child); | |
1699 gui_athena_popdown_submenus_action(temp_w,event,args,nargs); | |
1700 XtPopdown(temp_w); | |
1701 } | |
1702 } | |
1703 } | |
1704 | |
1705 /* Used to determine if the given widget has a submenu that can be popped up. */ | |
1706 static Boolean | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1707 has_submenu(Widget widget) |
7 | 1708 { |
1709 if ((widget != NULL) && XtIsSubclass(widget,smeBSBObjectClass)) | |
1710 { | |
1711 Pixmap p; | |
1712 | |
1713 XtVaGetValues(widget, XtNrightBitmap, &p, NULL); | |
1714 if ((p != None) && (p != XtUnspecifiedPixmap)) | |
1715 return True; | |
1716 } | |
1717 return False; | |
1718 } | |
1719 | |
1720 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1721 gui_athena_delayed_arm_action( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1722 Widget w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1723 XEvent *event, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1724 String *args, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1725 Cardinal *nargs) |
7 | 1726 { |
1727 Dimension width, height; | |
1728 | |
1729 if (event->type != MotionNotify) | |
1730 return; | |
1731 | |
1732 XtVaGetValues(w, | |
1733 XtNwidth, &width, | |
1734 XtNheight, &height, | |
1735 NULL); | |
1736 | |
1737 if (event->xmotion.x >= (int)width || event->xmotion.y >= (int)height) | |
1738 return; | |
1739 | |
1740 { | |
1741 static Widget previous_active_widget = NULL; | |
1742 Widget current; | |
1743 | |
1744 current = XawSimpleMenuGetActiveEntry(w); | |
1745 if (current != previous_active_widget) | |
1746 { | |
1747 if (timer) | |
1748 { | |
1749 /* If the timeout hasn't been triggered, remove it */ | |
1750 XtRemoveTimeOut(timer); | |
1751 } | |
1752 gui_athena_popdown_submenus_action(w,event,args,nargs); | |
1753 if (has_submenu(current)) | |
1754 { | |
1755 XtAppAddTimeOut(XtWidgetToApplicationContext(w), 600L, | |
1756 gui_athena_menu_timeout, | |
1757 (XtPointer)current); | |
1758 } | |
1759 previous_active_widget = current; | |
1760 } | |
1761 } | |
1762 } | |
1763 | |
1764 static Widget | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1765 get_popup_entry(Widget w) |
7 | 1766 { |
1767 Widget menuw; | |
1768 | |
1769 /* Get the active entry for the current menu */ | |
1770 if ((menuw = XawSimpleMenuGetActiveEntry(w)) == (Widget)0) | |
1771 return NULL; | |
1772 | |
1773 return submenu_widget(menuw); | |
1774 } | |
1775 | |
1776 /* Given the widget that has been determined to have a submenu, return the submenu widget | |
1777 * that is to be popped up. | |
1778 */ | |
1779 static Widget | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1780 submenu_widget(Widget widget) |
7 | 1781 { |
1782 /* Precondition: has_submenu(widget) == True | |
1783 * XtIsSubclass(XtParent(widget),simpleMenuWidgetClass) == True | |
1784 */ | |
1785 | |
1786 char_u *pullright_name; | |
1787 Widget popup; | |
1788 | |
1789 pullright_name = make_pull_name((char_u *)XtName(widget)); | |
1790 popup = XtNameToWidget(XtParent(widget), (char *)pullright_name); | |
1791 vim_free(pullright_name); | |
1792 | |
1793 return popup; | |
1794 /* Postcondition: (popup != NULL) implies | |
1795 * (XtIsSubclass(popup,simpleMenuWidgetClass) == True) */ | |
1796 } | |
1797 | |
1798 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1799 gui_mch_show_popupmenu(vimmenu_T *menu) |
7 | 1800 { |
1801 int rootx, rooty, winx, winy; | |
1802 Window root, child; | |
1803 unsigned int mask; | |
1804 | |
1805 if (menu->submenu_id == (Widget)0) | |
1806 return; | |
1807 | |
1808 /* Position the popup menu at the pointer */ | |
1809 if (XQueryPointer(gui.dpy, XtWindow(vimShell), &root, &child, | |
1810 &rootx, &rooty, &winx, &winy, &mask)) | |
1811 { | |
1812 rootx -= 30; | |
1813 if (rootx < 0) | |
1814 rootx = 0; | |
1815 rooty -= 5; | |
1816 if (rooty < 0) | |
1817 rooty = 0; | |
1818 XtVaSetValues(menu->submenu_id, | |
1819 XtNx, rootx, | |
1820 XtNy, rooty, | |
1821 NULL); | |
1822 } | |
1823 | |
1824 XtOverrideTranslations(menu->submenu_id, popupTrans); | |
1825 XtPopupSpringLoaded(menu->submenu_id); | |
1826 } | |
1827 | |
1828 #endif /* FEAT_MENU */ | |
1829 | |
1830 /* | |
1831 * Set the menu and scrollbar colors to their default values. | |
1832 */ | |
1833 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1834 gui_mch_def_colors(void) |
7 | 1835 { |
1836 /* | |
1837 * Get the colors ourselves. Using the automatic conversion doesn't | |
1838 * handle looking for approximate colors. | |
1839 */ | |
1840 if (gui.in_use) | |
1841 { | |
1842 gui.menu_fg_pixel = gui_get_color((char_u *)gui.rsrc_menu_fg_name); | |
1843 gui.menu_bg_pixel = gui_get_color((char_u *)gui.rsrc_menu_bg_name); | |
1844 gui.scroll_fg_pixel = gui_get_color((char_u *)gui.rsrc_scroll_fg_name); | |
1845 gui.scroll_bg_pixel = gui_get_color((char_u *)gui.rsrc_scroll_bg_name); | |
1846 #ifdef FEAT_BEVAL | |
1847 gui.tooltip_fg_pixel = gui_get_color((char_u *)gui.rsrc_tooltip_fg_name); | |
1848 gui.tooltip_bg_pixel = gui_get_color((char_u *)gui.rsrc_tooltip_bg_name); | |
1849 #endif | |
1850 } | |
1851 } | |
1852 | |
1853 | |
1854 /* | |
1855 * Scrollbar stuff. | |
1856 */ | |
1857 | |
1858 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1859 gui_mch_set_scrollbar_thumb( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1860 scrollbar_T *sb, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1861 long val, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1862 long size, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1863 long max) |
7 | 1864 { |
1865 double v, s; | |
1866 | |
1867 if (sb->id == (Widget)0) | |
1868 return; | |
1869 | |
1870 /* | |
1871 * Athena scrollbar must go from 0.0 to 1.0. | |
1872 */ | |
1873 if (max == 0) | |
1874 { | |
1875 /* So you can't scroll it at all (normally it scrolls past end) */ | |
1876 #ifdef FEAT_GUI_NEXTAW | |
1877 XawScrollbarSetThumb(sb->id, 0.0, 1.0); | |
1878 #else | |
1879 vim_XawScrollbarSetThumb(sb->id, 0.0, 1.0, 0.0); | |
1880 #endif | |
1881 } | |
1882 else | |
1883 { | |
1884 v = (double)val / (double)(max + 1); | |
1885 s = (double)size / (double)(max + 1); | |
1886 #ifdef FEAT_GUI_NEXTAW | |
1887 XawScrollbarSetThumb(sb->id, v, s); | |
1888 #else | |
1889 vim_XawScrollbarSetThumb(sb->id, v, s, 1.0); | |
1890 #endif | |
1891 } | |
1892 } | |
1893 | |
1894 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1895 gui_mch_set_scrollbar_pos( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1896 scrollbar_T *sb, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1897 int x, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1898 int y, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1899 int w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1900 int h) |
7 | 1901 { |
1902 if (sb->id == (Widget)0) | |
1903 return; | |
1904 | |
1905 XtUnmanageChild(sb->id); | |
1906 XtVaSetValues(sb->id, | |
1907 XtNhorizDistance, x, | |
1908 XtNvertDistance, y, | |
1909 XtNwidth, w, | |
1910 XtNheight, h, | |
1911 NULL); | |
1912 XtManageChild(sb->id); | |
1913 } | |
1914 | |
1915 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1916 gui_mch_enable_scrollbar(scrollbar_T *sb, int flag) |
7 | 1917 { |
1918 if (sb->id != (Widget)0) | |
1919 { | |
1920 if (flag) | |
1921 XtManageChild(sb->id); | |
1922 else | |
1923 XtUnmanageChild(sb->id); | |
1924 } | |
1925 } | |
1926 | |
1927 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1928 gui_mch_create_scrollbar( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1929 scrollbar_T *sb, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1930 int orient) /* SBAR_VERT or SBAR_HORIZ */ |
7 | 1931 { |
1932 sb->id = XtVaCreateWidget("scrollBar", | |
1933 #ifdef FEAT_GUI_NEXTAW | |
1934 scrollbarWidgetClass, vimForm, | |
1935 #else | |
1936 vim_scrollbarWidgetClass, vimForm, | |
1937 #endif | |
1938 XtNresizable, True, | |
1939 XtNtop, XtChainTop, | |
1940 XtNbottom, XtChainTop, | |
1941 XtNleft, XtChainLeft, | |
1942 XtNright, XtChainLeft, | |
1943 XtNborderWidth, 0, | |
1944 XtNorientation, (orient == SBAR_VERT) ? XtorientVertical | |
1945 : XtorientHorizontal, | |
1946 XtNforeground, gui.scroll_fg_pixel, | |
1947 XtNbackground, gui.scroll_bg_pixel, | |
1948 NULL); | |
1949 if (sb->id == (Widget)0) | |
1950 return; | |
1951 | |
1952 XtAddCallback(sb->id, XtNjumpProc, | |
1953 gui_athena_scroll_cb_jump, (XtPointer)sb->ident); | |
1954 XtAddCallback(sb->id, XtNscrollProc, | |
1955 gui_athena_scroll_cb_scroll, (XtPointer)sb->ident); | |
1956 | |
1957 #ifdef FEAT_GUI_NEXTAW | |
1958 XawScrollbarSetThumb(sb->id, 0.0, 1.0); | |
1959 #else | |
1960 vim_XawScrollbarSetThumb(sb->id, 0.0, 1.0, 0.0); | |
1961 #endif | |
1962 } | |
1963 | |
1964 #if defined(FEAT_WINDOWS) || defined(PROTO) | |
1965 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1966 gui_mch_destroy_scrollbar(scrollbar_T *sb) |
7 | 1967 { |
1968 if (sb->id != (Widget)0) | |
1969 XtDestroyWidget(sb->id); | |
1970 } | |
1971 #endif | |
1972 | |
1973 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1974 gui_mch_set_scrollbar_colors(scrollbar_T *sb) |
7 | 1975 { |
1976 if (sb->id != (Widget)0) | |
1977 XtVaSetValues(sb->id, | |
1978 XtNforeground, gui.scroll_fg_pixel, | |
1979 XtNbackground, gui.scroll_bg_pixel, | |
1980 NULL); | |
1981 | |
1982 /* This is needed for the rectangle below the vertical scrollbars. */ | |
1983 if (sb == &gui.bottom_sbar && vimForm != (Widget)0) | |
1984 gui_athena_scroll_colors(vimForm); | |
1985 } | |
1986 | |
1987 /* | |
1988 * Miscellaneous stuff: | |
1989 */ | |
1990 Window | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1991 gui_x11_get_wid(void) |
7 | 1992 { |
1993 return XtWindow(textArea); | |
1994 } | |
1995 | |
1996 #if defined(FEAT_BROWSE) || defined(PROTO) | |
1997 /* | |
1998 * Put up a file requester. | |
1999 * Returns the selected name in allocated memory, or NULL for Cancel. | |
2000 */ | |
2001 char_u * | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2002 gui_mch_browse( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2003 int saving UNUSED, /* select file to write */ |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2004 char_u *title, /* title for the window */ |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2005 char_u *dflt, /* default name */ |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2006 char_u *ext UNUSED, /* extension added */ |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2007 char_u *initdir, /* initial directory, NULL for current dir */ |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2008 char_u *filter UNUSED) /* file name filter */ |
7 | 2009 { |
2010 Position x, y; | |
2011 char_u dirbuf[MAXPATHL]; | |
2012 | |
2013 /* Concatenate "initdir" and "dflt". */ | |
2014 if (initdir == NULL || *initdir == NUL) | |
2015 mch_dirname(dirbuf, MAXPATHL); | |
2016 else if (STRLEN(initdir) + 2 < MAXPATHL) | |
2017 STRCPY(dirbuf, initdir); | |
2018 else | |
2019 dirbuf[0] = NUL; | |
2020 if (dflt != NULL && *dflt != NUL | |
2021 && STRLEN(dirbuf) + 2 + STRLEN(dflt) < MAXPATHL) | |
2022 { | |
2023 add_pathsep(dirbuf); | |
2024 STRCAT(dirbuf, dflt); | |
2025 } | |
2026 | |
2027 /* Position the file selector just below the menubar */ | |
2028 XtTranslateCoords(vimShell, (Position)0, (Position) | |
2029 #ifdef FEAT_MENU | |
2030 gui.menu_height | |
2031 #else | |
2032 0 | |
2033 #endif | |
2034 , &x, &y); | |
2035 return (char_u *)vim_SelFile(vimShell, (char *)title, (char *)dirbuf, | |
2036 NULL, (int)x, (int)y, gui.menu_fg_pixel, gui.menu_bg_pixel, | |
2037 gui.scroll_fg_pixel, gui.scroll_bg_pixel); | |
2038 } | |
2039 #endif | |
2040 | |
2041 #if defined(FEAT_GUI_DIALOG) || defined(PROTO) | |
2042 | |
2043 static int dialogStatus; | |
2044 static Atom dialogatom; | |
2045 | |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
2046 static void keyhit_callback(Widget w, XtPointer client_data, XEvent *event, Boolean *cont); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
2047 static void butproc(Widget w, XtPointer client_data, XtPointer call_data); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
2048 static void dialog_wm_handler(Widget w, XtPointer client_data, XEvent *event, Boolean *dum); |
7 | 2049 |
2050 /* | |
2051 * Callback function for the textfield. When CR is hit this works like | |
2052 * hitting the "OK" button, ESC like "Cancel". | |
2053 */ | |
2054 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2055 keyhit_callback( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2056 Widget w UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2057 XtPointer client_data UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2058 XEvent *event, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2059 Boolean *cont UNUSED) |
7 | 2060 { |
2061 char buf[2]; | |
2062 | |
2063 if (XLookupString(&(event->xkey), buf, 2, NULL, NULL) == 1) | |
2064 { | |
2065 if (*buf == CAR) | |
2066 dialogStatus = 1; | |
2067 else if (*buf == ESC) | |
2068 dialogStatus = 0; | |
2069 } | |
2070 } | |
2071 | |
2072 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2073 butproc( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2074 Widget w UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2075 XtPointer client_data, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2076 XtPointer call_data UNUSED) |
7 | 2077 { |
2078 dialogStatus = (int)(long)client_data + 1; | |
2079 } | |
2080 | |
2081 /* | |
2082 * Function called when dialog window closed. | |
2083 */ | |
2084 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2085 dialog_wm_handler( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2086 Widget w UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2087 XtPointer client_data UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2088 XEvent *event, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2089 Boolean *dum UNUSED) |
7 | 2090 { |
2091 if (event->type == ClientMessage | |
1887 | 2092 && (Atom)((XClientMessageEvent *)event)->data.l[0] == dialogatom) |
7 | 2093 dialogStatus = 0; |
2094 } | |
2095 | |
2096 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2097 gui_mch_dialog( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2098 int type UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2099 char_u *title, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2100 char_u *message, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2101 char_u *buttons, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2102 int dfltbutton UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2103 char_u *textfield, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2104 int ex_cmd UNUSED) |
7 | 2105 { |
2106 char_u *buts; | |
2107 char_u *p, *next; | |
2108 XtAppContext app; | |
2109 XEvent event; | |
2110 Position wd, hd; | |
2111 Position wv, hv; | |
2112 Position x, y; | |
2113 Widget dialog; | |
2114 Widget dialogshell; | |
2115 Widget dialogmessage; | |
2116 Widget dialogtextfield = 0; | |
2117 Widget dialogButton; | |
2118 Widget prev_dialogButton = NULL; | |
2119 int butcount; | |
2120 int vertical; | |
2121 | |
2122 if (title == NULL) | |
2123 title = (char_u *)_("Vim dialog"); | |
2124 dialogStatus = -1; | |
2125 | |
2126 /* if our pointer is currently hidden, then we should show it. */ | |
2127 gui_mch_mousehide(FALSE); | |
2128 | |
2129 /* Check 'v' flag in 'guioptions': vertical button placement. */ | |
2130 vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL); | |
2131 | |
2132 /* The shell is created each time, to make sure it is resized properly */ | |
2133 dialogshell = XtVaCreatePopupShell("dialogShell", | |
2134 transientShellWidgetClass, vimShell, | |
2135 XtNtitle, title, | |
2136 NULL); | |
2137 if (dialogshell == (Widget)0) | |
2138 goto error; | |
2139 | |
2140 dialog = XtVaCreateManagedWidget("dialog", | |
2141 formWidgetClass, dialogshell, | |
2142 XtNdefaultDistance, 20, | |
2143 NULL); | |
2144 if (dialog == (Widget)0) | |
2145 goto error; | |
2146 gui_athena_menu_colors(dialog); | |
2147 dialogmessage = XtVaCreateManagedWidget("dialogMessage", | |
2148 labelWidgetClass, dialog, | |
2149 XtNlabel, message, | |
2150 XtNtop, XtChainTop, | |
2151 XtNbottom, XtChainTop, | |
2152 XtNleft, XtChainLeft, | |
2153 XtNright, XtChainLeft, | |
2154 XtNresizable, True, | |
2155 XtNborderWidth, 0, | |
2156 NULL); | |
2157 gui_athena_menu_colors(dialogmessage); | |
2158 | |
2159 if (textfield != NULL) | |
2160 { | |
2161 dialogtextfield = XtVaCreateManagedWidget("textfield", | |
2162 asciiTextWidgetClass, dialog, | |
2163 XtNwidth, 400, | |
2164 XtNtop, XtChainTop, | |
2165 XtNbottom, XtChainTop, | |
2166 XtNleft, XtChainLeft, | |
2167 XtNright, XtChainRight, | |
2168 XtNfromVert, dialogmessage, | |
2169 XtNresizable, True, | |
2170 XtNstring, textfield, | |
2171 XtNlength, IOSIZE, | |
2172 XtNuseStringInPlace, True, | |
2173 XtNeditType, XawtextEdit, | |
2174 XtNwrap, XawtextWrapNever, | |
2175 XtNresize, XawtextResizeHeight, | |
2176 NULL); | |
2177 XtManageChild(dialogtextfield); | |
2178 XtAddEventHandler(dialogtextfield, KeyPressMask, False, | |
2179 (XtEventHandler)keyhit_callback, (XtPointer)NULL); | |
2180 XawTextSetInsertionPoint(dialogtextfield, | |
2181 (XawTextPosition)STRLEN(textfield)); | |
2182 XtSetKeyboardFocus(dialog, dialogtextfield); | |
2183 } | |
2184 | |
2185 /* make a copy, so that we can insert NULs */ | |
2186 buts = vim_strsave(buttons); | |
2187 if (buts == NULL) | |
2188 return -1; | |
2189 | |
2190 p = buts; | |
2191 for (butcount = 0; *p; ++butcount) | |
2192 { | |
2193 for (next = p; *next; ++next) | |
2194 { | |
2195 if (*next == DLG_HOTKEY_CHAR) | |
1620 | 2196 STRMOVE(next, next + 1); |
7 | 2197 if (*next == DLG_BUTTON_SEP) |
2198 { | |
2199 *next++ = NUL; | |
2200 break; | |
2201 } | |
2202 } | |
2203 dialogButton = XtVaCreateManagedWidget("button", | |
2204 commandWidgetClass, dialog, | |
2205 XtNlabel, p, | |
2206 XtNtop, XtChainBottom, | |
2207 XtNbottom, XtChainBottom, | |
2208 XtNleft, XtChainLeft, | |
2209 XtNright, XtChainLeft, | |
2210 XtNfromVert, textfield == NULL ? dialogmessage : dialogtextfield, | |
2211 XtNvertDistance, vertical ? 4 : 20, | |
2212 XtNresizable, False, | |
2213 NULL); | |
2214 gui_athena_menu_colors(dialogButton); | |
2215 if (butcount > 0) | |
2216 XtVaSetValues(dialogButton, | |
2217 vertical ? XtNfromVert : XtNfromHoriz, prev_dialogButton, | |
2218 NULL); | |
2219 | |
2255 | 2220 XtAddCallback(dialogButton, XtNcallback, butproc, (XtPointer)(long_u)butcount); |
7 | 2221 p = next; |
2222 prev_dialogButton = dialogButton; | |
2223 } | |
2224 vim_free(buts); | |
2225 | |
2226 XtRealizeWidget(dialogshell); | |
2227 | |
2228 /* Setup for catching the close-window event, don't let it close Vim! */ | |
2229 dialogatom = XInternAtom(gui.dpy, "WM_DELETE_WINDOW", False); | |
2230 XSetWMProtocols(gui.dpy, XtWindow(dialogshell), &dialogatom, 1); | |
2231 XtAddEventHandler(dialogshell, NoEventMask, True, dialog_wm_handler, NULL); | |
2232 | |
2233 XtVaGetValues(dialogshell, | |
2234 XtNwidth, &wd, | |
2235 XtNheight, &hd, | |
2236 NULL); | |
2237 XtVaGetValues(vimShell, | |
2238 XtNwidth, &wv, | |
2239 XtNheight, &hv, | |
2240 NULL); | |
2241 XtTranslateCoords(vimShell, | |
2242 (Position)((wv - wd) / 2), | |
2243 (Position)((hv - hd) / 2), | |
2244 &x, &y); | |
2245 if (x < 0) | |
2246 x = 0; | |
2247 if (y < 0) | |
2248 y = 0; | |
2249 XtVaSetValues(dialogshell, XtNx, x, XtNy, y, NULL); | |
2250 | |
2251 /* Position the mouse pointer in the dialog, required for when focus | |
2252 * follows mouse. */ | |
2253 XWarpPointer(gui.dpy, (Window)0, XtWindow(dialogshell), 0, 0, 0, 0, 20, 40); | |
2254 | |
2255 | |
2256 app = XtWidgetToApplicationContext(dialogshell); | |
2257 | |
2258 XtPopup(dialogshell, XtGrabNonexclusive); | |
2259 | |
405 | 2260 for (;;) |
7 | 2261 { |
2262 XtAppNextEvent(app, &event); | |
2263 XtDispatchEvent(&event); | |
2264 if (dialogStatus >= 0) | |
2265 break; | |
2266 } | |
2267 | |
2268 XtPopdown(dialogshell); | |
2269 | |
2270 if (textfield != NULL && dialogStatus < 0) | |
2271 *textfield = NUL; | |
2272 | |
2273 error: | |
2274 XtDestroyWidget(dialogshell); | |
2275 | |
2276 return dialogStatus; | |
2277 } | |
2278 #endif | |
2279 | |
2280 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_MENU) | |
2281 /* | |
2282 * Set the colors of Widget "id" to the menu colors. | |
2283 */ | |
2284 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2285 gui_athena_menu_colors(Widget id) |
7 | 2286 { |
2287 if (gui.menu_bg_pixel != INVALCOLOR) | |
2288 XtVaSetValues(id, XtNbackground, gui.menu_bg_pixel, NULL); | |
2289 if (gui.menu_fg_pixel != INVALCOLOR) | |
2290 XtVaSetValues(id, XtNforeground, gui.menu_fg_pixel, NULL); | |
2291 } | |
2292 #endif | |
2293 | |
2294 /* | |
2295 * Set the colors of Widget "id" to the scroll colors. | |
2296 */ | |
2297 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2298 gui_athena_scroll_colors(Widget id) |
7 | 2299 { |
2300 if (gui.scroll_bg_pixel != INVALCOLOR) | |
2301 XtVaSetValues(id, XtNbackground, gui.scroll_bg_pixel, NULL); | |
2302 if (gui.scroll_fg_pixel != INVALCOLOR) | |
2303 XtVaSetValues(id, XtNforeground, gui.scroll_fg_pixel, NULL); | |
2304 } |