comparison src/native-gtk-toolbar.c @ 462:0784d089fdc9 r21-2-46

Import from CVS: tag r21-2-46
author cvs
date Mon, 13 Aug 2007 11:44:37 +0200
parents
children e38acbeb1cae
comparison
equal deleted inserted replaced
461:120ed4009e51 462:0784d089fdc9
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 }