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: \
|
|
52 abort (); \
|
|
53 } \
|
|
54 } while (0)
|
|
55
|
|
56 static void
|
|
57 gtk_clear_toolbar (struct frame *f, enum toolbar_pos pos);
|
|
58
|
|
59 static void
|
|
60 gtk_toolbar_callback (GtkWidget *w, gpointer user_data)
|
|
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))
|
|
155 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1);
|
|
156 else
|
|
157 instance = Qnil;
|
|
158
|
|
159 if (IMAGE_INSTANCEP(instance))
|
|
160 {
|
|
161 GtkWidget *pixmapwid;
|
|
162 GdkPixmap *pixmap;
|
|
163 GdkBitmap *mask;
|
|
164 char *tooltip = NULL;
|
|
165
|
|
166 if (STRINGP (tb->help_string))
|
|
167 tooltip = XSTRING_DATA (tb->help_string);
|
|
168
|
|
169 pixmap = XIMAGE_INSTANCE_GTK_PIXMAP(instance);
|
|
170 mask = XIMAGE_INSTANCE_GTK_MASK(instance);
|
|
171 pixmapwid = gtk_pixmap_new (pixmap, mask);
|
|
172
|
|
173 gtk_widget_set_usize (pixmapwid, tb->width, tb->height);
|
|
174
|
|
175 gtk_toolbar_append_item (GTK_TOOLBAR(toolbar), NULL, tooltip, NULL,
|
|
176 pixmapwid, gtk_toolbar_callback, (gpointer) tb);
|
|
177 }
|
|
178 }
|
|
179 cur_x += vert ? 0 : tb->width;
|
|
180 cur_y += vert ? tb->height : 0;
|
|
181 /* Who's idea was it to use a linked list for toolbar buttons? */
|
|
182 button = tb->next;
|
|
183 }
|
|
184
|
|
185 SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 1);
|
|
186
|
|
187 x -= vert ? 3 : 2;
|
|
188 y -= vert ? 2 : 3;
|
|
189
|
|
190 gtk_fixed_put (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)), FRAME_GTK_TOOLBAR_WIDGET (f)[pos],x, y);
|
|
191 gtk_widget_show_all (FRAME_GTK_TOOLBAR_WIDGET (f)[pos]);
|
|
192 }
|
|
193
|
|
194 static void
|
|
195 gtk_clear_toolbar (struct frame *f, enum toolbar_pos pos)
|
|
196 {
|
|
197 FRAME_GTK_TOOLBAR_CHECKSUM (f, pos) = 0;
|
|
198 SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 0);
|
|
199 if (FRAME_GTK_TOOLBAR_WIDGET(f)[pos])
|
|
200 gtk_widget_destroy (FRAME_GTK_TOOLBAR_WIDGET(f)[pos]);
|
|
201 }
|
|
202
|
|
203 static void
|
|
204 gtk_output_frame_toolbars (struct frame *f)
|
|
205 {
|
|
206 if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f))
|
|
207 gtk_output_toolbar (f, TOP_TOOLBAR);
|
|
208 else if (f->top_toolbar_was_visible)
|
|
209 gtk_clear_toolbar (f, TOP_TOOLBAR);
|
|
210
|
|
211 if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f))
|
|
212 gtk_output_toolbar (f, BOTTOM_TOOLBAR);
|
|
213 else if (f->bottom_toolbar_was_visible)
|
|
214 gtk_clear_toolbar (f, LEFT_TOOLBAR);
|
|
215
|
|
216 if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f))
|
|
217 gtk_output_toolbar (f, LEFT_TOOLBAR);
|
|
218 else if (f->left_toolbar_was_visible)
|
|
219 gtk_clear_toolbar (f, LEFT_TOOLBAR);
|
|
220
|
|
221 if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f))
|
|
222 gtk_output_toolbar (f, RIGHT_TOOLBAR);
|
|
223 else if (f->right_toolbar_was_visible)
|
|
224 gtk_clear_toolbar (f, RIGHT_TOOLBAR);
|
|
225 }
|
|
226
|
|
227 static void
|
|
228 gtk_initialize_frame_toolbars (struct frame *f)
|
|
229 {
|
|
230 stderr_out ("We should draw toolbars\n");
|
|
231 }
|
|
232
|
|
233
|
|
234 /************************************************************************/
|
|
235 /* initialization */
|
|
236 /************************************************************************/
|
|
237
|
|
238 void
|
|
239 console_type_create_toolbar_gtk (void)
|
|
240 {
|
|
241 CONSOLE_HAS_METHOD (gtk, output_frame_toolbars);
|
|
242 CONSOLE_HAS_METHOD (gtk, initialize_frame_toolbars);
|
|
243 }
|