Mercurial > hg > xemacs-beta
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/native-gtk-toolbar.c Mon Aug 13 11:44:37 2007 +0200 @@ -0,0 +1,243 @@ +/* toolbar implementation -- GTK interface. + Copyright (C) 2000 Aaron Lehmann + +This file is part of XEmacs. + +XEmacs is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +XEmacs is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with XEmacs; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Synched up with: Not in FSF. */ + +#include <config.h> +#include "lisp.h" + +#include "console-gtk.h" +#include "glyphs-gtk.h" +#include "objects-gtk.h" + +#include "faces.h" +#include "frame.h" +#include "toolbar.h" +#include "window.h" + +#define SET_TOOLBAR_WAS_VISIBLE_FLAG(frame, pos, flag) \ + do { \ + switch (pos) \ + { \ + case TOP_TOOLBAR: \ + (frame)->top_toolbar_was_visible = flag; \ + break; \ + case BOTTOM_TOOLBAR: \ + (frame)->bottom_toolbar_was_visible = flag; \ + break; \ + case LEFT_TOOLBAR: \ + (frame)->left_toolbar_was_visible = flag; \ + break; \ + case RIGHT_TOOLBAR: \ + (frame)->right_toolbar_was_visible = flag; \ + break; \ + default: \ + abort (); \ + } \ + } while (0) + +static void +gtk_clear_toolbar (struct frame *f, enum toolbar_pos pos); + +static void +gtk_toolbar_callback (GtkWidget *w, gpointer user_data) +{ + struct toolbar_button *tb = (struct toolbar_button *) user_data; + + call0 (tb->callback); +} + + +static void +gtk_output_toolbar (struct frame *f, enum toolbar_pos pos) +{ + GtkWidget *toolbar; + Lisp_Object button, window, glyph, instance; + unsigned int checksum = 0; + struct window *w; + int x, y, bar_width, bar_height, vert; + int cur_x, cur_y; + + window = FRAME_LAST_NONMINIBUF_WINDOW (f); + w = XWINDOW (window); + + get_toolbar_coords (f, pos, &x, &y, &bar_width, &bar_height, &vert, 0); + + /* Get the toolbar and delete the old widgets in it */ + button = FRAME_TOOLBAR_BUTTONS (f, pos); + + /* First loop over all of the buttons to determine how many there + are. This loop will also make sure that all instances are + instantiated so when we actually output them they will come up + immediately. */ + while (!NILP (button)) + { + struct toolbar_button *tb = XTOOLBAR_BUTTON (button); + checksum = HASH4 (checksum, + internal_hash (get_toolbar_button_glyph(w, tb), 0), + internal_hash (tb->callback, 0), + 0 /* width */); + button = tb->next; + } + + /* Only do updates if the toolbar has changed, or this is the first + time we have drawn it in this position + */ + if (FRAME_GTK_TOOLBAR_WIDGET (f)[pos] && + FRAME_GTK_TOOLBAR_CHECKSUM (f, pos) == checksum) + { + return; + } + + /* Loop through buttons and add them to our toolbar. + This code ignores the button dimensions as we let GTK handle that :) + Attach the toolbar_button struct to the toolbar button so we know what + function to use as a callback. */ + + { + gtk_clear_toolbar (f, pos); + FRAME_GTK_TOOLBAR_WIDGET (f)[pos] = toolbar = + gtk_toolbar_new (((pos == TOP_TOOLBAR) || (pos == BOTTOM_TOOLBAR)) ? + GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, + GTK_TOOLBAR_BOTH); + } + + if (NILP (w->toolbar_buttons_captioned_p)) + gtk_toolbar_set_style (toolbar, GTK_TOOLBAR_ICONS); + else + gtk_toolbar_set_style (toolbar, GTK_TOOLBAR_BOTH); + + FRAME_GTK_TOOLBAR_CHECKSUM(f, pos) = checksum; + button = FRAME_TOOLBAR_BUTTONS (f, pos); + + cur_x = 0; + cur_y = 0; + + while (!NILP (button)) + { + struct toolbar_button *tb = XTOOLBAR_BUTTON (button); + + if (tb->blank) + { + /* It is a blank space... we do not pay attention to the + size, because the GTK toolbar does not allow us to + specify different spacings. *sigh* + */ + gtk_toolbar_append_space (GTK_TOOLBAR (toolbar)); + } + else + { + /* It actually has a glyph associated with it! What WILL + they think of next? + */ + glyph = tb->up_glyph; + + /* #### It is currently possible for users to trash us by directly + changing the toolbar glyphs. Avoid crashing in that case. */ + if (GLYPHP (glyph)) + instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1); + else + instance = Qnil; + + if (IMAGE_INSTANCEP(instance)) + { + GtkWidget *pixmapwid; + GdkPixmap *pixmap; + GdkBitmap *mask; + char *tooltip = NULL; + + if (STRINGP (tb->help_string)) + tooltip = XSTRING_DATA (tb->help_string); + + pixmap = XIMAGE_INSTANCE_GTK_PIXMAP(instance); + mask = XIMAGE_INSTANCE_GTK_MASK(instance); + pixmapwid = gtk_pixmap_new (pixmap, mask); + + gtk_widget_set_usize (pixmapwid, tb->width, tb->height); + + gtk_toolbar_append_item (GTK_TOOLBAR(toolbar), NULL, tooltip, NULL, + pixmapwid, gtk_toolbar_callback, (gpointer) tb); + } + } + cur_x += vert ? 0 : tb->width; + cur_y += vert ? tb->height : 0; + /* Who's idea was it to use a linked list for toolbar buttons? */ + button = tb->next; + } + + SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 1); + + x -= vert ? 3 : 2; + y -= vert ? 2 : 3; + + gtk_fixed_put (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)), FRAME_GTK_TOOLBAR_WIDGET (f)[pos],x, y); + gtk_widget_show_all (FRAME_GTK_TOOLBAR_WIDGET (f)[pos]); +} + +static void +gtk_clear_toolbar (struct frame *f, enum toolbar_pos pos) +{ + FRAME_GTK_TOOLBAR_CHECKSUM (f, pos) = 0; + SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 0); + if (FRAME_GTK_TOOLBAR_WIDGET(f)[pos]) + gtk_widget_destroy (FRAME_GTK_TOOLBAR_WIDGET(f)[pos]); +} + +static void +gtk_output_frame_toolbars (struct frame *f) +{ + if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f)) + gtk_output_toolbar (f, TOP_TOOLBAR); + else if (f->top_toolbar_was_visible) + gtk_clear_toolbar (f, TOP_TOOLBAR); + + if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f)) + gtk_output_toolbar (f, BOTTOM_TOOLBAR); + else if (f->bottom_toolbar_was_visible) + gtk_clear_toolbar (f, LEFT_TOOLBAR); + + if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f)) + gtk_output_toolbar (f, LEFT_TOOLBAR); + else if (f->left_toolbar_was_visible) + gtk_clear_toolbar (f, LEFT_TOOLBAR); + + if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f)) + gtk_output_toolbar (f, RIGHT_TOOLBAR); + else if (f->right_toolbar_was_visible) + gtk_clear_toolbar (f, RIGHT_TOOLBAR); +} + +static void +gtk_initialize_frame_toolbars (struct frame *f) +{ + stderr_out ("We should draw toolbars\n"); +} + + +/************************************************************************/ +/* initialization */ +/************************************************************************/ + +void +console_type_create_toolbar_gtk (void) +{ + CONSOLE_HAS_METHOD (gtk, output_frame_toolbars); + CONSOLE_HAS_METHOD (gtk, initialize_frame_toolbars); +}