462
|
1 /* toolbar implementation -- GTK interface.
|
|
2 Copyright (C) 2000 Aaron Lehmann
|
|
3
|
|
4 This file is part of XEmacs.
|
|
5
|
|
6 XEmacs is free software; you can redistribute it and/or modify it
|
|
7 under the terms of the GNU General Public License as published by the
|
|
8 Free Software Foundation; either version 2, or (at your option) any
|
|
9 later version.
|
|
10
|
|
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
|
|
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
14 for more details.
|
|
15
|
|
16 You should have received a copy of the GNU General Public License
|
|
17 along with XEmacs; see the file COPYING. If not, write to
|
|
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
19 Boston, MA 02111-1307, USA. */
|
|
20
|
|
21 /* Synched up with: Not in FSF. */
|
|
22
|
|
23 #include <config.h>
|
|
24 #include "lisp.h"
|
|
25
|
|
26 #include "console-gtk.h"
|
|
27 #include "glyphs-gtk.h"
|
|
28 #include "objects-gtk.h"
|
|
29
|
|
30 #include "faces.h"
|
|
31 #include "frame.h"
|
|
32 #include "toolbar.h"
|
|
33 #include "window.h"
|
|
34
|
|
35 #define SET_TOOLBAR_WAS_VISIBLE_FLAG(frame, pos, flag) \
|
|
36 do { \
|
|
37 switch (pos) \
|
|
38 { \
|
|
39 case TOP_TOOLBAR: \
|
|
40 (frame)->top_toolbar_was_visible = flag; \
|
|
41 break; \
|
|
42 case BOTTOM_TOOLBAR: \
|
|
43 (frame)->bottom_toolbar_was_visible = flag; \
|
|
44 break; \
|
|
45 case LEFT_TOOLBAR: \
|
|
46 (frame)->left_toolbar_was_visible = flag; \
|
|
47 break; \
|
|
48 case RIGHT_TOOLBAR: \
|
|
49 (frame)->right_toolbar_was_visible = flag; \
|
|
50 break; \
|
|
51 default: \
|
2500
|
52 ABORT (); \
|
462
|
53 } \
|
|
54 } while (0)
|
|
55
|
|
56 static void
|
|
57 gtk_clear_toolbar (struct frame *f, enum toolbar_pos pos);
|
|
58
|
|
59 static void
|
2286
|
60 gtk_toolbar_callback (GtkWidget *UNUSED (w), gpointer user_data)
|
462
|
61 {
|
|
62 struct toolbar_button *tb = (struct toolbar_button *) user_data;
|
|
63
|
|
64 call0 (tb->callback);
|
|
65 }
|
|
66
|
|
67
|
|
68 static void
|
|
69 gtk_output_toolbar (struct frame *f, enum toolbar_pos pos)
|
|
70 {
|
|
71 GtkWidget *toolbar;
|
|
72 Lisp_Object button, window, glyph, instance;
|
|
73 unsigned int checksum = 0;
|
|
74 struct window *w;
|
|
75 int x, y, bar_width, bar_height, vert;
|
|
76 int cur_x, cur_y;
|
|
77
|
|
78 window = FRAME_LAST_NONMINIBUF_WINDOW (f);
|
|
79 w = XWINDOW (window);
|
|
80
|
|
81 get_toolbar_coords (f, pos, &x, &y, &bar_width, &bar_height, &vert, 0);
|
|
82
|
|
83 /* Get the toolbar and delete the old widgets in it */
|
|
84 button = FRAME_TOOLBAR_BUTTONS (f, pos);
|
|
85
|
|
86 /* First loop over all of the buttons to determine how many there
|
|
87 are. This loop will also make sure that all instances are
|
|
88 instantiated so when we actually output them they will come up
|
|
89 immediately. */
|
|
90 while (!NILP (button))
|
|
91 {
|
|
92 struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
|
|
93 checksum = HASH4 (checksum,
|
|
94 internal_hash (get_toolbar_button_glyph(w, tb), 0),
|
|
95 internal_hash (tb->callback, 0),
|
|
96 0 /* width */);
|
|
97 button = tb->next;
|
|
98 }
|
|
99
|
|
100 /* Only do updates if the toolbar has changed, or this is the first
|
|
101 time we have drawn it in this position
|
|
102 */
|
|
103 if (FRAME_GTK_TOOLBAR_WIDGET (f)[pos] &&
|
|
104 FRAME_GTK_TOOLBAR_CHECKSUM (f, pos) == checksum)
|
|
105 {
|
|
106 return;
|
|
107 }
|
|
108
|
|
109 /* Loop through buttons and add them to our toolbar.
|
|
110 This code ignores the button dimensions as we let GTK handle that :)
|
|
111 Attach the toolbar_button struct to the toolbar button so we know what
|
|
112 function to use as a callback. */
|
|
113
|
|
114 {
|
|
115 gtk_clear_toolbar (f, pos);
|
|
116 FRAME_GTK_TOOLBAR_WIDGET (f)[pos] = toolbar =
|
|
117 gtk_toolbar_new (((pos == TOP_TOOLBAR) || (pos == BOTTOM_TOOLBAR)) ?
|
|
118 GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL,
|
|
119 GTK_TOOLBAR_BOTH);
|
|
120 }
|
|
121
|
|
122 if (NILP (w->toolbar_buttons_captioned_p))
|
|
123 gtk_toolbar_set_style (toolbar, GTK_TOOLBAR_ICONS);
|
|
124 else
|
|
125 gtk_toolbar_set_style (toolbar, GTK_TOOLBAR_BOTH);
|
|
126
|
|
127 FRAME_GTK_TOOLBAR_CHECKSUM(f, pos) = checksum;
|
|
128 button = FRAME_TOOLBAR_BUTTONS (f, pos);
|
|
129
|
|
130 cur_x = 0;
|
|
131 cur_y = 0;
|
|
132
|
|
133 while (!NILP (button))
|
|
134 {
|
|
135 struct toolbar_button *tb = XTOOLBAR_BUTTON (button);
|
|
136
|
|
137 if (tb->blank)
|
|
138 {
|
|
139 /* It is a blank space... we do not pay attention to the
|
|
140 size, because the GTK toolbar does not allow us to
|
|
141 specify different spacings. *sigh*
|
|
142 */
|
|
143 gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
|
|
144 }
|
|
145 else
|
|
146 {
|
|
147 /* It actually has a glyph associated with it! What WILL
|
|
148 they think of next?
|
|
149 */
|
|
150 glyph = tb->up_glyph;
|
|
151
|
|
152 /* #### It is currently possible for users to trash us by directly
|
|
153 changing the toolbar glyphs. Avoid crashing in that case. */
|
|
154 if (GLYPHP (glyph))
|
793
|
155 instance = glyph_image_instance (glyph, window,
|
|
156 ERROR_ME_DEBUG_WARN, 1);
|
462
|
157 else
|
|
158 instance = Qnil;
|
|
159
|
|
160 if (IMAGE_INSTANCEP(instance))
|
|
161 {
|
|
162 GtkWidget *pixmapwid;
|
|
163 GdkPixmap *pixmap;
|
|
164 GdkBitmap *mask;
|
|
165 char *tooltip = NULL;
|
|
166
|
|
167 if (STRINGP (tb->help_string))
|
|
168 tooltip = XSTRING_DATA (tb->help_string);
|
|
169
|
|
170 pixmap = XIMAGE_INSTANCE_GTK_PIXMAP(instance);
|
|
171 mask = XIMAGE_INSTANCE_GTK_MASK(instance);
|
|
172 pixmapwid = gtk_pixmap_new (pixmap, mask);
|
|
173
|
|
174 gtk_widget_set_usize (pixmapwid, tb->width, tb->height);
|
|
175
|
|
176 gtk_toolbar_append_item (GTK_TOOLBAR(toolbar), NULL, tooltip, NULL,
|
|
177 pixmapwid, gtk_toolbar_callback, (gpointer) tb);
|
|
178 }
|
|
179 }
|
|
180 cur_x += vert ? 0 : tb->width;
|
|
181 cur_y += vert ? tb->height : 0;
|
|
182 /* Who's idea was it to use a linked list for toolbar buttons? */
|
|
183 button = tb->next;
|
|
184 }
|
|
185
|
|
186 SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 1);
|
|
187
|
|
188 x -= vert ? 3 : 2;
|
|
189 y -= vert ? 2 : 3;
|
|
190
|
|
191 gtk_fixed_put (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)), FRAME_GTK_TOOLBAR_WIDGET (f)[pos],x, y);
|
|
192 gtk_widget_show_all (FRAME_GTK_TOOLBAR_WIDGET (f)[pos]);
|
|
193 }
|
|
194
|
|
195 static void
|
|
196 gtk_clear_toolbar (struct frame *f, enum toolbar_pos pos)
|
|
197 {
|
|
198 FRAME_GTK_TOOLBAR_CHECKSUM (f, pos) = 0;
|
|
199 SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 0);
|
|
200 if (FRAME_GTK_TOOLBAR_WIDGET(f)[pos])
|
|
201 gtk_widget_destroy (FRAME_GTK_TOOLBAR_WIDGET(f)[pos]);
|
|
202 }
|
|
203
|
|
204 static void
|
|
205 gtk_output_frame_toolbars (struct frame *f)
|
|
206 {
|
|
207 if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f))
|
|
208 gtk_output_toolbar (f, TOP_TOOLBAR);
|
|
209 else if (f->top_toolbar_was_visible)
|
|
210 gtk_clear_toolbar (f, TOP_TOOLBAR);
|
|
211
|
|
212 if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f))
|
|
213 gtk_output_toolbar (f, BOTTOM_TOOLBAR);
|
|
214 else if (f->bottom_toolbar_was_visible)
|
|
215 gtk_clear_toolbar (f, LEFT_TOOLBAR);
|
|
216
|
|
217 if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f))
|
|
218 gtk_output_toolbar (f, LEFT_TOOLBAR);
|
|
219 else if (f->left_toolbar_was_visible)
|
|
220 gtk_clear_toolbar (f, LEFT_TOOLBAR);
|
|
221
|
|
222 if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f))
|
|
223 gtk_output_toolbar (f, RIGHT_TOOLBAR);
|
|
224 else if (f->right_toolbar_was_visible)
|
|
225 gtk_clear_toolbar (f, RIGHT_TOOLBAR);
|
|
226 }
|
|
227
|
|
228 static void
|
2286
|
229 gtk_initialize_frame_toolbars (struct frame *UNUSED (f))
|
462
|
230 {
|
|
231 stderr_out ("We should draw toolbars\n");
|
|
232 }
|
|
233
|
|
234
|
|
235 /************************************************************************/
|
|
236 /* initialization */
|
|
237 /************************************************************************/
|
|
238
|
|
239 void
|
|
240 console_type_create_toolbar_gtk (void)
|
|
241 {
|
|
242 CONSOLE_HAS_METHOD (gtk, output_frame_toolbars);
|
|
243 CONSOLE_HAS_METHOD (gtk, initialize_frame_toolbars);
|
|
244 }
|