~canonical-dx-team/ubuntu/maverick/gtk+2.0/menuproxy

« back to all changes in this revision

Viewing changes to gtk/gtktearoffmenuitem.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-05-04 12:24:25 UTC
  • mfrom: (1.1.21 upstream)
  • Revision ID: james.westby@ubuntu.com-20070504122425-0m8midgzrp40y8w2
Tags: 2.10.12-1ubuntu1
* Sync with Debian
* New upstream version:
  Fixed bugs:
  - 379414 file chooser warnings when changing path in the entry
  - 418585 GtkFileChooserDefault sizing code is not DPI independent
  - 419568 Crash in search if start with special letter
  - 435062 build dies with icon cache validation
  - 379399 Segfault to call gtk_print_operation_run twice.
  - 387889 cups backend has problems when there are too many printers
  - 418531 invalid read to gtkicontheme.c gtk_icon_theme_lookup_icon...
  - 423916 crash in color scheme code
  - 424042 Segmentation fault while quickly pressing Alt+arrows
  - 415260 Protect against negative indices when setting values in G...
  - 419171 XGetVisualInfo() may not set nxvisuals
  - 128852 Gdk cursors don't look good on win32
  - 344657 Ctrl-H doesn't toggle "Show Hidden Files" setting
  - 345345 PrintOperation::paginate is not emitted for class handler
  - 347567 GtkPrintOperation::end-print is not emitted if it's cance...
  - 369112 gtk_ui_manager_add_ui should accept unnamed separator
  - 392015 Selected menu item invisible on Windows Vista
  - 399253 MS-Windows Theme Bottom Tab placement rendering glitches
  - 399425 gtk_input_dialog_fill_axes() adds child to gtkscrolledwin...
  - 403251 [patch] little memory leak in GtkPrintJob
  - 403267 [patch] memory leak in GtkPageSetupUnixDialog
  - 403470 MS-Windows Theme tab placement other than on top leaks a ...
  - 404506 Windows system fonts that have multi-byte font names cann...
  - 405089 Incorrect window placement for GtkEventBox private window
  - 405515 Minor leak in gtkfilesystemmodel.c
  - 405539 gdk_pixbuf_save() for PNG saver can return FALSE without ...
  - 415681 gdk_window_clear_area includes an extra line and column o...
  - 418219 GtkRecentChooser should apply filter before sorting and c...
  - 418403 Scroll to printer after selecting it from settings
  - 421985 _gtk_print_operation_platform_backend_launch_preview
  - 421990 gtk_print_job_get_surface
  - 421993 gtk_print_operation_init
  - 423064 Conditional jump or move depends on uninitialised value(s...
  - 423722 Fix printing header in gtk-demo
  - 424168 gtk_print_operation_run on async preview
  - 425655 Don't install gtk+-unix-print-2.0.pc on non-UNIX platforms
  - 425786 GDK segfaults if XineramaQueryScreens fails
  - 428665 Lpr Backend gets stuck in infinite loop during gtk_enumer...
  - 429902 GtkPrintOperation leaks cairo contextes
  - 431997 First delay of GdkPixbufAnimationIter is wrong
  - 433242 Inconsistent scroll arrow position calculations
  - 433972 Placing gtk.Expander inside a gtk.TextView() changes gtk....
  - 434261 _gtk_toolbar_elide_underscores incorrectly handles some s...
  - 383354 ctrl-L should make 'Location' entry disappear
  - 418673 gtk_recent_manager_add_item
  - 429732 gtk_accel_group_finalize accesses invalid memory
  - 435028 WM_CLIENT_LEADER is wrong on the leader_window
  - 431067 Background of the header window is not updated
  - 338843 add recent files support inside the ui manager
  - 148535 add drop shadow to menus, tooltips, etc. under Windows XP
* debian/control.in:
  - Conflicts on ubuntulooks (<= 0.9.11-1)
* debian/patches/15_default-fallback-icon-theme.patch:
  - patch from Debian, fallback on gnome icon theme

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* GTK - The GIMP Toolkit
 
2
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 
3
 *
 
4
 * This library is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU Lesser General Public
 
6
 * License as published by the Free Software Foundation; either
 
7
 * version 2 of the License, or (at your option) any later version.
 
8
 *
 
9
 * This library is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * Lesser General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Lesser General Public
 
15
 * License along with this library; if not, write to the
 
16
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
17
 * Boston, MA 02111-1307, USA.
 
18
 */
 
19
 
 
20
/*
 
21
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
 
22
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 
23
 * files for a list of changes.  These files are distributed with
 
24
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 
25
 */
 
26
 
 
27
#include <config.h>
 
28
 
 
29
#include "gtkmenu.h"
 
30
#include "gtktearoffmenuitem.h"
 
31
#include "gtkintl.h"
 
32
#include "gtkalias.h"
 
33
 
 
34
#define ARROW_SIZE 10
 
35
#define TEAR_LENGTH 5
 
36
#define BORDER_SPACING  3
 
37
 
 
38
static void gtk_tearoff_menu_item_size_request (GtkWidget             *widget,
 
39
                                                GtkRequisition        *requisition);
 
40
static gint gtk_tearoff_menu_item_expose     (GtkWidget             *widget,
 
41
                                              GdkEventExpose        *event);
 
42
static void gtk_tearoff_menu_item_activate   (GtkMenuItem           *menu_item);
 
43
static void gtk_tearoff_menu_item_parent_set (GtkWidget             *widget,
 
44
                                              GtkWidget             *previous);
 
45
 
 
46
G_DEFINE_TYPE (GtkTearoffMenuItem, gtk_tearoff_menu_item, GTK_TYPE_MENU_ITEM)
 
47
 
 
48
GtkWidget*
 
49
gtk_tearoff_menu_item_new (void)
 
50
{
 
51
  return g_object_new (GTK_TYPE_TEAROFF_MENU_ITEM, NULL);
 
52
}
 
53
 
 
54
static void
 
55
gtk_tearoff_menu_item_class_init (GtkTearoffMenuItemClass *klass)
 
56
{
 
57
  GtkWidgetClass *widget_class;
 
58
  GtkMenuItemClass *menu_item_class;
 
59
 
 
60
  widget_class = (GtkWidgetClass*) klass;
 
61
  menu_item_class = (GtkMenuItemClass*) klass;
 
62
 
 
63
  widget_class->expose_event = gtk_tearoff_menu_item_expose;
 
64
  widget_class->size_request = gtk_tearoff_menu_item_size_request;
 
65
  widget_class->parent_set = gtk_tearoff_menu_item_parent_set;
 
66
 
 
67
  menu_item_class->activate = gtk_tearoff_menu_item_activate;
 
68
}
 
69
 
 
70
static void
 
71
gtk_tearoff_menu_item_init (GtkTearoffMenuItem *tearoff_menu_item)
 
72
{
 
73
  tearoff_menu_item->torn_off = FALSE;
 
74
}
 
75
 
 
76
static void
 
77
gtk_tearoff_menu_item_size_request (GtkWidget      *widget,
 
78
                                    GtkRequisition *requisition)
 
79
{
 
80
  requisition->width = (GTK_CONTAINER (widget)->border_width +
 
81
                        widget->style->xthickness +
 
82
                        BORDER_SPACING) * 2;
 
83
  requisition->height = (GTK_CONTAINER (widget)->border_width +
 
84
                         widget->style->ythickness) * 2;
 
85
 
 
86
  if (GTK_IS_MENU (widget->parent) && GTK_MENU (widget->parent)->torn_off)
 
87
    {
 
88
      requisition->height += ARROW_SIZE;
 
89
    }
 
90
  else
 
91
    {
 
92
      requisition->height += widget->style->ythickness + 4;
 
93
    }
 
94
}
 
95
 
 
96
static void
 
97
gtk_tearoff_menu_item_paint (GtkWidget   *widget,
 
98
                             GdkRectangle *area)
 
99
{
 
100
  GtkMenuItem *menu_item;
 
101
  GtkShadowType shadow_type;
 
102
  gint width, height;
 
103
  gint x, y;
 
104
  gint right_max;
 
105
  GtkArrowType arrow_type;
 
106
  GtkTextDirection direction;
 
107
  
 
108
  if (GTK_WIDGET_DRAWABLE (widget))
 
109
    {
 
110
      menu_item = GTK_MENU_ITEM (widget);
 
111
 
 
112
      direction = gtk_widget_get_direction (widget);
 
113
 
 
114
      x = widget->allocation.x + GTK_CONTAINER (menu_item)->border_width;
 
115
      y = widget->allocation.y + GTK_CONTAINER (menu_item)->border_width;
 
116
      width = widget->allocation.width - GTK_CONTAINER (menu_item)->border_width * 2;
 
117
      height = widget->allocation.height - GTK_CONTAINER (menu_item)->border_width * 2;
 
118
      right_max = x + width;
 
119
 
 
120
      if (widget->state == GTK_STATE_PRELIGHT)
 
121
        {
 
122
          gint selected_shadow_type;
 
123
          
 
124
          gtk_widget_style_get (widget,
 
125
                                "selected-shadow-type", &selected_shadow_type,
 
126
                                NULL);
 
127
          gtk_paint_box (widget->style,
 
128
                         widget->window,
 
129
                         GTK_STATE_PRELIGHT,
 
130
                         selected_shadow_type,
 
131
                         area, widget, "menuitem",
 
132
                         x, y, width, height);
 
133
        }
 
134
      else
 
135
        gdk_window_clear_area (widget->window, area->x, area->y, area->width, area->height);
 
136
 
 
137
      if (GTK_IS_MENU (widget->parent) && GTK_MENU (widget->parent)->torn_off)
 
138
        {
 
139
          gint arrow_x;
 
140
 
 
141
          if (widget->state == GTK_STATE_PRELIGHT)
 
142
            shadow_type = GTK_SHADOW_IN;
 
143
          else
 
144
            shadow_type = GTK_SHADOW_OUT;
 
145
 
 
146
          if (menu_item->toggle_size > ARROW_SIZE)
 
147
            {
 
148
              if (direction == GTK_TEXT_DIR_LTR) {
 
149
                arrow_x = x + (menu_item->toggle_size - ARROW_SIZE)/2;
 
150
                arrow_type = GTK_ARROW_LEFT;
 
151
              }
 
152
              else {
 
153
                arrow_x = x + width - menu_item->toggle_size + (menu_item->toggle_size - ARROW_SIZE)/2; 
 
154
                arrow_type = GTK_ARROW_RIGHT;       
 
155
              }
 
156
              x += menu_item->toggle_size + BORDER_SPACING;
 
157
            }
 
158
          else
 
159
            {
 
160
              if (direction == GTK_TEXT_DIR_LTR) {
 
161
                arrow_x = ARROW_SIZE / 2;
 
162
                arrow_type = GTK_ARROW_LEFT;
 
163
              }
 
164
              else {
 
165
                arrow_x = x + width - 2 * ARROW_SIZE + ARROW_SIZE / 2; 
 
166
                arrow_type = GTK_ARROW_RIGHT;       
 
167
              }
 
168
              x += 2 * ARROW_SIZE;
 
169
            }
 
170
 
 
171
 
 
172
          gtk_paint_arrow (widget->style, widget->window,
 
173
                           widget->state, shadow_type,
 
174
                           NULL, widget, "tearoffmenuitem",
 
175
                           arrow_type, FALSE,
 
176
                           arrow_x, y + height / 2 - 5, 
 
177
                           ARROW_SIZE, ARROW_SIZE);
 
178
        }
 
179
 
 
180
      while (x < right_max)
 
181
        {
 
182
          gint x1, x2;
 
183
 
 
184
          if (direction == GTK_TEXT_DIR_LTR) {
 
185
            x1 = x;
 
186
            x2 = MIN (x + TEAR_LENGTH, right_max);
 
187
          }
 
188
          else {
 
189
            x1 = right_max - x;
 
190
            x2 = MAX (right_max - x - TEAR_LENGTH, 0);
 
191
          }
 
192
          
 
193
          gtk_paint_hline (widget->style, widget->window, GTK_STATE_NORMAL,
 
194
                           NULL, widget, "tearoffmenuitem",
 
195
                           x1, x2, y + (height - widget->style->ythickness) / 2);
 
196
          x += 2 * TEAR_LENGTH;
 
197
        }
 
198
    }
 
199
}
 
200
 
 
201
static gint
 
202
gtk_tearoff_menu_item_expose (GtkWidget      *widget,
 
203
                            GdkEventExpose *event)
 
204
{
 
205
  gtk_tearoff_menu_item_paint (widget, &event->area);
 
206
 
 
207
  return FALSE;
 
208
}
 
209
 
 
210
static void
 
211
gtk_tearoff_menu_item_activate (GtkMenuItem *menu_item)
 
212
{
 
213
  if (GTK_IS_MENU (GTK_WIDGET (menu_item)->parent))
 
214
    {
 
215
      GtkMenu *menu = GTK_MENU (GTK_WIDGET (menu_item)->parent);
 
216
      
 
217
      gtk_widget_queue_resize (GTK_WIDGET (menu_item));
 
218
      gtk_menu_set_tearoff_state (GTK_MENU (GTK_WIDGET (menu_item)->parent),
 
219
                                  !menu->torn_off);
 
220
    }
 
221
}
 
222
 
 
223
static void
 
224
tearoff_state_changed (GtkMenu            *menu,
 
225
                       GParamSpec         *pspec,
 
226
                       gpointer            data)
 
227
{
 
228
  GtkTearoffMenuItem *tearoff_menu_item = GTK_TEAROFF_MENU_ITEM (data);
 
229
 
 
230
  tearoff_menu_item->torn_off = gtk_menu_get_tearoff_state (menu);
 
231
}
 
232
 
 
233
static void
 
234
gtk_tearoff_menu_item_parent_set (GtkWidget *widget,
 
235
                                  GtkWidget *previous)
 
236
{
 
237
  GtkTearoffMenuItem *tearoff_menu_item = GTK_TEAROFF_MENU_ITEM (widget);
 
238
  GtkMenu *menu = GTK_IS_MENU (widget->parent) ? GTK_MENU (widget->parent) : NULL;
 
239
 
 
240
  if (previous)
 
241
    g_signal_handlers_disconnect_by_func (previous, 
 
242
                                          tearoff_state_changed, 
 
243
                                          tearoff_menu_item);
 
244
  
 
245
  if (menu)
 
246
    {
 
247
      tearoff_menu_item->torn_off = gtk_menu_get_tearoff_state (menu);
 
248
      g_signal_connect (menu, "notify::tearoff-state", 
 
249
                        G_CALLBACK (tearoff_state_changed), 
 
250
                        tearoff_menu_item);
 
251
    }  
 
252
}
 
253
 
 
254
#define __GTK_TEAROFF_MENU_ITEM_C__
 
255
#include "gtkaliasdef.c"