aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog13
-rw-r--r--src/gtkutil.c252
2 files changed, 109 insertions, 156 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index e0201b2ab1a..d03b16a7092 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,16 @@
12011-01-01 Chong Yidong <cyd@stupidchicken.com>
2
3 * gtkutil.c (xg_get_tool_bar_widgets): Use NULL for a missing
4 image or label in the container.
5 (xg_make_tool_item): Replace VERT_ONLY arg with HORIZ, TEXT_IMAGE.
6 (xg_show_toolbar_item): Function deleted.
7 (xg_tool_item_stale_p): New function.
8 (update_frame_tool_bar): Calculate tool-bar style once per call.
9 Instead of hiding text labels, omit them. Don't use
10 xg_show_toolbar_item; create new GtkToolItems from scratch if
11 necessary, instead of trying to re-use them. This avoids an
12 annoying animation when changing tool-bars.
13
12010-12-31 Jan Djärv <jan.h.d@swipnet.se> 142010-12-31 Jan Djärv <jan.h.d@swipnet.se>
2 15
3 * nsfns.m (ns_set_name_as_filename): Always use buffer name for 16 * nsfns.m (ns_set_name_as_filename): Always use buffer name for
diff --git a/src/gtkutil.c b/src/gtkutil.c
index a6cfbf002b3..fb003749493 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -3664,7 +3664,8 @@ xg_get_tool_bar_widgets (GtkWidget *vb, GtkWidget **wimage)
3664{ 3664{
3665 GList *clist = gtk_container_get_children (GTK_CONTAINER (vb)); 3665 GList *clist = gtk_container_get_children (GTK_CONTAINER (vb));
3666 GtkWidget *c1 = (GtkWidget *) clist->data; 3666 GtkWidget *c1 = (GtkWidget *) clist->data;
3667 GtkWidget *c2 = (GtkWidget *) clist->next->data; 3667 GtkWidget *c2 = clist->next ? (GtkWidget *) clist->next->data : NULL;
3668
3668 *wimage = GTK_IS_IMAGE (c1) ? c1 : c2; 3669 *wimage = GTK_IS_IMAGE (c1) ? c1 : c2;
3669 g_list_free (clist); 3670 g_list_free (clist);
3670 return GTK_IS_LABEL (c1) ? c1 : c2; 3671 return GTK_IS_LABEL (c1) ? c1 : c2;
@@ -4039,28 +4040,17 @@ xg_make_tool_item (FRAME_PTR f,
4039 GtkWidget *wimage, 4040 GtkWidget *wimage,
4040 GtkWidget **wbutton, 4041 GtkWidget **wbutton,
4041 const char *label, 4042 const char *label,
4042 int i, 4043 int i, int horiz, int text_image)
4043 int vert_only)
4044{ 4044{
4045 GtkToolItem *ti = gtk_tool_item_new (); 4045 GtkToolItem *ti = gtk_tool_item_new ();
4046 Lisp_Object style = Ftool_bar_get_system_style (); 4046 GtkWidget *vb = horiz ? gtk_hbox_new (FALSE, 0) : gtk_vbox_new (FALSE, 0);
4047 int both_horiz = EQ (style, Qboth_horiz);
4048 int text_image = EQ (style, Qtext_image_horiz);
4049
4050 GtkWidget *vb = both_horiz || text_image
4051 ? gtk_hbox_new (FALSE, 0) : gtk_vbox_new (FALSE, 0);
4052 GtkWidget *wb = gtk_button_new (); 4047 GtkWidget *wb = gtk_button_new ();
4053 GtkWidget *weventbox = gtk_event_box_new (); 4048 GtkWidget *weventbox = gtk_event_box_new ();
4054 4049
4055 /* We are not letting Gtk+ alter display on this, we only keep it here 4050 if (wimage && !text_image)
4056 so we can get it later in xg_show_toolbar_item. */
4057 gtk_tool_item_set_is_important (ti, !vert_only);
4058
4059 if (wimage && ! text_image)
4060 gtk_box_pack_start (GTK_BOX (vb), wimage, TRUE, TRUE, 0); 4051 gtk_box_pack_start (GTK_BOX (vb), wimage, TRUE, TRUE, 0);
4061 4052 if (label)
4062 gtk_box_pack_start (GTK_BOX (vb), gtk_label_new (label), TRUE, TRUE, 0); 4053 gtk_box_pack_start (GTK_BOX (vb), gtk_label_new (label), TRUE, TRUE, 0);
4063
4064 if (wimage && text_image) 4054 if (wimage && text_image)
4065 gtk_box_pack_start (GTK_BOX (vb), wimage, TRUE, TRUE, 0); 4055 gtk_box_pack_start (GTK_BOX (vb), wimage, TRUE, TRUE, 0);
4066 4056
@@ -4121,58 +4111,49 @@ xg_make_tool_item (FRAME_PTR f,
4121 return ti; 4111 return ti;
4122} 4112}
4123 4113
4124static void 4114static int
4125xg_show_toolbar_item (GtkToolItem *ti) 4115xg_tool_item_stale_p (GtkWidget *wbutton, const char *stock_name,
4116 const char *icon_name, const struct image *img,
4117 const char *label, int horiz)
4126{ 4118{
4127 Lisp_Object style = Ftool_bar_get_system_style (); 4119 gpointer old;
4128 int both_horiz = EQ (style, Qboth_horiz);
4129 int text_image = EQ (style, Qtext_image_horiz);
4130
4131 int horiz = both_horiz || text_image;
4132 int vert_only = ! gtk_tool_item_get_is_important (ti);
4133 int show_label = ! EQ (style, Qimage) && ! (vert_only && horiz);
4134 int show_image = ! EQ (style, Qtext);
4135
4136 GtkWidget *weventbox = XG_BIN_CHILD (ti);
4137 GtkWidget *wbutton = XG_BIN_CHILD (weventbox);
4138 GtkWidget *vb = XG_BIN_CHILD (wbutton);
4139 GtkWidget *wimage; 4120 GtkWidget *wimage;
4121 GtkWidget *vb = XG_BIN_CHILD (wbutton);
4140 GtkWidget *wlbl = xg_get_tool_bar_widgets (vb, &wimage); 4122 GtkWidget *wlbl = xg_get_tool_bar_widgets (vb, &wimage);
4141 GtkWidget *new_box = NULL;
4142
4143 if (GTK_IS_VBOX (vb) && horiz)
4144 new_box = gtk_hbox_new (FALSE, 0);
4145 else if (GTK_IS_HBOX (vb) && !horiz && show_label && show_image)
4146 new_box = gtk_vbox_new (FALSE, 0);
4147 4123
4148 if (!new_box && horiz) 4124 /* Check if the tool icon matches. */
4149 gtk_box_reorder_child (GTK_BOX (vb), wlbl, text_image ? 0 : 1); 4125 if (stock_name)
4150 else if (new_box)
4151 { 4126 {
4152 g_object_ref (G_OBJECT (wimage)); 4127 old = g_object_get_data (G_OBJECT (wimage),
4153 g_object_ref (G_OBJECT (wlbl)); 4128 XG_TOOL_BAR_STOCK_NAME);
4154 gtk_container_remove (GTK_CONTAINER (vb), wimage); 4129 if (!old || strcmp (old, stock_name))
4155 gtk_container_remove (GTK_CONTAINER (vb), wlbl); 4130 return 1;
4156 gtk_widget_destroy (GTK_WIDGET (vb));
4157 if (! text_image)
4158 gtk_box_pack_start (GTK_BOX (new_box), wimage, TRUE, TRUE, 0);
4159 gtk_box_pack_start (GTK_BOX (new_box), wlbl, TRUE, TRUE, 0);
4160 if (text_image)
4161 gtk_box_pack_start (GTK_BOX (new_box), wimage, TRUE, TRUE, 0);
4162 gtk_container_add (GTK_CONTAINER (wbutton), new_box);
4163 g_object_unref (G_OBJECT (wimage));
4164 g_object_unref (G_OBJECT (wlbl));
4165 vb = new_box;
4166 } 4131 }
4132 else if (icon_name)
4133 {
4134 old = g_object_get_data (G_OBJECT (wimage),
4135 XG_TOOL_BAR_ICON_NAME);
4136 if (!old || strcmp (old, icon_name))
4137 return 1;
4138 }
4139 else
4140 {
4141 Pixmap old_img
4142 = (Pixmap) g_object_get_data (G_OBJECT (wimage),
4143 XG_TOOL_BAR_IMAGE_DATA);
4144 if (old_img != img->pixmap)
4145 return 1;
4146 }
4147
4148 /* Check button configuration and label. */
4149 if ((horiz ? GTK_IS_VBOX (vb) : GTK_IS_HBOX (vb))
4150 || (label ? (wlbl == NULL) : (wlbl != NULL)))
4151 return 1;
4167 4152
4168 if (show_label) gtk_widget_show (wlbl); 4153 /* Ensure label is correct. */
4169 else gtk_widget_hide (wlbl); 4154 if (label)
4170 if (show_image) gtk_widget_show (wimage); 4155 gtk_label_set_text (GTK_LABEL (wlbl), label);
4171 else gtk_widget_hide (wimage); 4156 return 0;
4172 gtk_widget_show (GTK_WIDGET (weventbox));
4173 gtk_widget_show (GTK_WIDGET (vb));
4174 gtk_widget_show (GTK_WIDGET (wbutton));
4175 gtk_widget_show (GTK_WIDGET (ti));
4176} 4157}
4177 4158
4178static int 4159static int
@@ -4225,7 +4206,7 @@ xg_update_tool_bar_sizes (FRAME_PTR f)
4225void 4206void
4226update_frame_tool_bar (FRAME_PTR f) 4207update_frame_tool_bar (FRAME_PTR f)
4227{ 4208{
4228 int i; 4209 int i, j;
4229 struct x_output *x = f->output_data.x; 4210 struct x_output *x = f->output_data.x;
4230 int hmargin = 0, vmargin = 0; 4211 int hmargin = 0, vmargin = 0;
4231 GtkToolbar *wtoolbar; 4212 GtkToolbar *wtoolbar;
@@ -4233,6 +4214,9 @@ update_frame_tool_bar (FRAME_PTR f)
4233 GtkTextDirection dir; 4214 GtkTextDirection dir;
4234 int pack_tool_bar = x->handlebox_widget == NULL; 4215 int pack_tool_bar = x->handlebox_widget == NULL;
4235 4216
4217 Lisp_Object style;
4218 int text_image, horiz;
4219
4236 if (! FRAME_GTK_WIDGET (f)) 4220 if (! FRAME_GTK_WIDGET (f))
4237 return; 4221 return;
4238 4222
@@ -4268,7 +4252,11 @@ update_frame_tool_bar (FRAME_PTR f)
4268 wtoolbar = GTK_TOOLBAR (x->toolbar_widget); 4252 wtoolbar = GTK_TOOLBAR (x->toolbar_widget);
4269 dir = gtk_widget_get_direction (GTK_WIDGET (wtoolbar)); 4253 dir = gtk_widget_get_direction (GTK_WIDGET (wtoolbar));
4270 4254
4271 for (i = 0; i < f->n_tool_bar_items; ++i) 4255 style = Ftool_bar_get_system_style ();
4256 text_image = EQ (style, Qtext_image_horiz);
4257 horiz = EQ (style, Qboth_horiz) || text_image;
4258
4259 for (i = j = 0; i < f->n_tool_bar_items; ++i)
4272 { 4260 {
4273 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P)); 4261 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
4274 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P)); 4262 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
@@ -4284,11 +4272,14 @@ update_frame_tool_bar (FRAME_PTR f)
4284 Lisp_Object rtl; 4272 Lisp_Object rtl;
4285 GtkWidget *wbutton = NULL; 4273 GtkWidget *wbutton = NULL;
4286 Lisp_Object specified_file; 4274 Lisp_Object specified_file;
4287 const char *label = (STRINGP (PROP (TOOL_BAR_ITEM_LABEL))
4288 ? SSDATA (PROP (TOOL_BAR_ITEM_LABEL)) : "");
4289 int vert_only = ! NILP (PROP (TOOL_BAR_ITEM_VERT_ONLY)); 4275 int vert_only = ! NILP (PROP (TOOL_BAR_ITEM_VERT_ONLY));
4276 const char *label
4277 = (EQ (style, Qimage) || (vert_only && horiz)) ? NULL
4278 : STRINGP (PROP (TOOL_BAR_ITEM_LABEL))
4279 ? SSDATA (PROP (TOOL_BAR_ITEM_LABEL))
4280 : "";
4290 4281
4291 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), i); 4282 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), j);
4292 4283
4293 /* If this is a separator, use a gtk separator item. */ 4284 /* If this is a separator, use a gtk separator item. */
4294 if (EQ (PROP (TOOL_BAR_ITEM_TYPE), Qt)) 4285 if (EQ (PROP (TOOL_BAR_ITEM_TYPE), Qt))
@@ -4299,9 +4290,9 @@ update_frame_tool_bar (FRAME_PTR f)
4299 gtk_container_remove (GTK_CONTAINER (wtoolbar), 4290 gtk_container_remove (GTK_CONTAINER (wtoolbar),
4300 GTK_WIDGET (ti)); 4291 GTK_WIDGET (ti));
4301 ti = gtk_separator_tool_item_new (); 4292 ti = gtk_separator_tool_item_new ();
4302 gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, i); 4293 gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, j);
4303 } 4294 }
4304 gtk_widget_show (GTK_WIDGET (ti)); 4295 j++;
4305 continue; 4296 continue;
4306 } 4297 }
4307 4298
@@ -4313,14 +4304,15 @@ update_frame_tool_bar (FRAME_PTR f)
4313 ti = NULL; 4304 ti = NULL;
4314 } 4305 }
4315 4306
4316 if (ti) 4307 if (ti) wbutton = XG_BIN_CHILD (XG_BIN_CHILD (ti));
4317 wbutton = XG_BIN_CHILD (XG_BIN_CHILD (ti));
4318 4308
4319 /* Ignore invalid image specifications. */ 4309 /* Ignore invalid image specifications. */
4320 image = PROP (TOOL_BAR_ITEM_IMAGES); 4310 image = PROP (TOOL_BAR_ITEM_IMAGES);
4321 if (!valid_image_p (image)) 4311 if (!valid_image_p (image))
4322 { 4312 {
4323 if (wbutton) gtk_widget_hide (wbutton); 4313 if (ti)
4314 gtk_container_remove (GTK_CONTAINER (wtoolbar),
4315 GTK_WIDGET (ti));
4324 continue; 4316 continue;
4325 } 4317 }
4326 4318
@@ -4356,16 +4348,13 @@ update_frame_tool_bar (FRAME_PTR f)
4356 4348
4357 if (stock_name == NULL && icon_name == NULL) 4349 if (stock_name == NULL && icon_name == NULL)
4358 { 4350 {
4359 /* No stock image, or stock item not known. Try regular image. */ 4351 /* No stock image, or stock item not known. Try regular
4360 4352 image. If image is a vector, choose it according to the
4361 /* If image is a vector, choose the image according to the
4362 button state. */ 4353 button state. */
4363 if (dir == GTK_TEXT_DIR_RTL 4354 if (dir == GTK_TEXT_DIR_RTL
4364 && !NILP (rtl = PROP (TOOL_BAR_ITEM_RTL_IMAGE)) 4355 && !NILP (rtl = PROP (TOOL_BAR_ITEM_RTL_IMAGE))
4365 && STRINGP (rtl)) 4356 && STRINGP (rtl))
4366 { 4357 image = find_rtl_image (f, image, rtl);
4367 image = find_rtl_image (f, image, rtl);
4368 }
4369 4358
4370 if (VECTORP (image)) 4359 if (VECTORP (image))
4371 { 4360 {
@@ -4391,21 +4380,31 @@ update_frame_tool_bar (FRAME_PTR f)
4391 if (img->load_failed_p || img->pixmap == None) 4380 if (img->load_failed_p || img->pixmap == None)
4392 { 4381 {
4393 if (ti) 4382 if (ti)
4394 gtk_widget_hide_all (GTK_WIDGET (ti)); 4383 gtk_container_remove (GTK_CONTAINER (wtoolbar),
4395 else 4384 GTK_WIDGET (ti));
4396 {
4397 /* Insert an empty (non-image) button */
4398 ti = xg_make_tool_item (f, NULL, NULL, "", i, 0);
4399 gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, i);
4400 }
4401 continue; 4385 continue;
4402 } 4386 }
4403 } 4387 }
4404 4388
4389 /* If there is an existing widget, check if it's stale; if so,
4390 remove it and make a new tool item from scratch. */
4391 if (ti && xg_tool_item_stale_p (wbutton, stock_name, icon_name,
4392 img, label, horiz))
4393 {
4394 gtk_container_remove (GTK_CONTAINER (wtoolbar),
4395 GTK_WIDGET (ti));
4396 ti = NULL;
4397 }
4398
4405 if (ti == NULL) 4399 if (ti == NULL)
4406 { 4400 {
4407 GtkWidget *w; 4401 GtkWidget *w;
4408 if (stock_name) 4402
4403 /* Save the image so we can see if an update is needed the
4404 next time we call xg_tool_item_match_p. */
4405 if (EQ (style, Qtext))
4406 w = NULL;
4407 else if (stock_name)
4409 { 4408 {
4410 w = gtk_image_new_from_stock (stock_name, icon_size); 4409 w = gtk_image_new_from_stock (stock_name, icon_size);
4411 g_object_set_data_full (G_OBJECT (w), XG_TOOL_BAR_STOCK_NAME, 4410 g_object_set_data_full (G_OBJECT (w), XG_TOOL_BAR_STOCK_NAME,
@@ -4422,93 +4421,34 @@ update_frame_tool_bar (FRAME_PTR f)
4422 else 4421 else
4423 { 4422 {
4424 w = xg_get_image_for_pixmap (f, img, x->widget, NULL); 4423 w = xg_get_image_for_pixmap (f, img, x->widget, NULL);
4425 /* Save the image so we can see if an update is needed when
4426 this function is called again. */
4427 g_object_set_data (G_OBJECT (w), XG_TOOL_BAR_IMAGE_DATA, 4424 g_object_set_data (G_OBJECT (w), XG_TOOL_BAR_IMAGE_DATA,
4428 (gpointer)img->pixmap); 4425 (gpointer)img->pixmap);
4429 } 4426 }
4430 4427
4431 gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin); 4428 if (w) gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin);
4432 ti = xg_make_tool_item (f, w, &wbutton, label, i, vert_only); 4429 ti = xg_make_tool_item (f, w, &wbutton, label, i, horiz, text_image);
4433 gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, i); 4430 gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, j);
4434 gtk_widget_set_sensitive (wbutton, enabled_p);
4435 }
4436 else
4437 {
4438 GtkWidget *vb = XG_BIN_CHILD (wbutton);
4439 GtkWidget *wimage;
4440 GtkWidget *wlbl = xg_get_tool_bar_widgets (vb, &wimage);
4441
4442 Pixmap old_img = (Pixmap) g_object_get_data (G_OBJECT (wimage),
4443 XG_TOOL_BAR_IMAGE_DATA);
4444 gpointer old_stock_name = g_object_get_data (G_OBJECT (wimage),
4445 XG_TOOL_BAR_STOCK_NAME);
4446 gpointer old_icon_name = g_object_get_data (G_OBJECT (wimage),
4447 XG_TOOL_BAR_ICON_NAME);
4448 gtk_label_set_text (GTK_LABEL (wlbl), label);
4449 gtk_tool_item_set_is_important (ti, !vert_only);
4450 if (stock_name &&
4451 (! old_stock_name || strcmp (old_stock_name, stock_name) != 0))
4452 {
4453 gtk_image_set_from_stock (GTK_IMAGE (wimage),
4454 stock_name, icon_size);
4455 g_object_set_data_full (G_OBJECT (wimage), XG_TOOL_BAR_STOCK_NAME,
4456 (gpointer) xstrdup (stock_name),
4457 (GDestroyNotify) xfree);
4458 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_IMAGE_DATA,
4459 NULL);
4460 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME,
4461 NULL);
4462 }
4463 else if (icon_name &&
4464 (! old_icon_name || strcmp (old_icon_name, icon_name) != 0))
4465 {
4466 gtk_image_set_from_icon_name (GTK_IMAGE (wimage),
4467 icon_name, icon_size);
4468 g_object_set_data_full (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME,
4469 (gpointer) xstrdup (icon_name),
4470 (GDestroyNotify) xfree);
4471 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_IMAGE_DATA,
4472 NULL);
4473 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_STOCK_NAME,
4474 NULL);
4475 }
4476 else if (img && old_img != img->pixmap)
4477 {
4478 (void) xg_get_image_for_pixmap (f, img, x->widget,
4479 GTK_IMAGE (wimage));
4480 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_IMAGE_DATA,
4481 (gpointer)img->pixmap);
4482
4483 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_STOCK_NAME,
4484 NULL);
4485 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME,
4486 NULL);
4487 }
4488
4489 gtk_misc_set_padding (GTK_MISC (wimage), hmargin, vmargin);
4490
4491 gtk_widget_set_sensitive (wbutton, enabled_p);
4492 } 4431 }
4493 xg_show_toolbar_item (ti);
4494 4432
4495#undef PROP 4433#undef PROP
4434
4435 gtk_widget_set_sensitive (wbutton, enabled_p);
4436 j++;
4496 } 4437 }
4497 4438
4498 /* Remove buttons not longer needed. We just hide them so they 4439 /* Remove buttons not longer needed. */
4499 can be reused later on. */
4500 do 4440 do
4501 { 4441 {
4502 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), i++); 4442 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), j++);
4503 if (ti) gtk_widget_hide_all (GTK_WIDGET (ti)); 4443 if (ti)
4444 gtk_container_remove (GTK_CONTAINER (wtoolbar), GTK_WIDGET (ti));
4504 } while (ti != NULL); 4445 } while (ti != NULL);
4505 4446
4506 if (f->n_tool_bar_items != 0) 4447 if (f->n_tool_bar_items != 0)
4507 { 4448 {
4508 if (pack_tool_bar) 4449 if (pack_tool_bar)
4509 xg_pack_tool_bar (f, f->tool_bar_position); 4450 xg_pack_tool_bar (f, f->tool_bar_position);
4510 gtk_widget_show (x->toolbar_widget); 4451 gtk_widget_show_all (GTK_WIDGET (x->handlebox_widget));
4511 gtk_widget_show (x->handlebox_widget);
4512 if (xg_update_tool_bar_sizes (f)) 4452 if (xg_update_tool_bar_sizes (f))
4513 xg_height_or_width_changed (f); 4453 xg_height_or_width_changed (f);
4514 } 4454 }