comparison src/glyphs-gtk.c @ 2168:95fee4a1420e

[xemacs-hg @ 2004-07-07 12:00:58 by malcolmp] Working GK tab_control widget. Other GTK widgets drawn with the correct location and size.
author malcolmp
date Wed, 07 Jul 2004 12:01:07 +0000
parents 16489ca72b3d
children 4ec724310f33
comparison
equal deleted inserted replaced
2167:54e1ecdc5778 2168:95fee4a1420e
60 #include "imgproc.h" 60 #include "imgproc.h"
61 #include "insdel.h" 61 #include "insdel.h"
62 #include "lstream.h" 62 #include "lstream.h"
63 #include "opaque.h" 63 #include "opaque.h"
64 #include "window.h" 64 #include "window.h"
65 #include "elhash.h"
66 #include "events.h"
65 67
66 #include "console-gtk-impl.h" 68 #include "console-gtk-impl.h"
67 #include "glyphs-gtk.h" 69 #include "glyphs-gtk.h"
68 #include "objects-gtk-impl.h" 70 #include "objects-gtk-impl.h"
69 #include "ui-gtk.h" 71 #include "ui-gtk.h"
73 #include <setjmp.h> 75 #include <setjmp.h>
74 76
75 #if defined (HAVE_XPM) 77 #if defined (HAVE_XPM)
76 #include <X11/xpm.h> 78 #include <X11/xpm.h>
77 #endif 79 #endif
80
81 /* Widget callback hash table callback slot. */
82 #define WIDGET_GLYPH_SLOT 0
78 83
79 DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing); 84 DECLARE_IMAGE_INSTANTIATOR_FORMAT (nothing);
80 DECLARE_IMAGE_INSTANTIATOR_FORMAT (string); 85 DECLARE_IMAGE_INSTANTIATOR_FORMAT (string);
81 DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string); 86 DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
82 DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit); 87 DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit);
1949 else /* must be a widget */ 1954 else /* must be a widget */
1950 { 1955 {
1951 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p)); 1956 struct frame *f = XFRAME (IMAGE_INSTANCE_FRAME (p));
1952 GtkWidget *wid = IMAGE_INSTANCE_GTK_CLIPWIDGET (p); 1957 GtkWidget *wid = IMAGE_INSTANCE_GTK_CLIPWIDGET (p);
1953 GtkAllocation a; 1958 GtkAllocation a;
1959 int moving;
1954 1960
1955 if (!wid) return; 1961 if (!wid) return;
1956 1962
1957 a.x = x + IMAGE_INSTANCE_GTK_WIDGET_XOFFSET (p); 1963 a.x = x + IMAGE_INSTANCE_GTK_WIDGET_XOFFSET (p);
1958 a.y = y + IMAGE_INSTANCE_GTK_WIDGET_YOFFSET (p); 1964 a.y = y + IMAGE_INSTANCE_GTK_WIDGET_YOFFSET (p);
1959 a.width = dga->width; 1965 a.width = dga->width;
1960 a.height = dga->height; 1966 a.height = dga->height;
1961 1967
1968 /* Is the widget cganging position? */
1969 moving = (a.x != wid->allocation.x) ||
1970 (a.y != wid->allocation.y);
1971
1962 if ((a.width != wid->allocation.width) || 1972 if ((a.width != wid->allocation.width) ||
1963 (a.height != wid->allocation.height)) 1973 (a.height != wid->allocation.height) ||
1974 moving)
1964 { 1975 {
1965 gtk_widget_size_allocate (IMAGE_INSTANCE_GTK_CLIPWIDGET (p), &a); 1976 gtk_widget_size_allocate (IMAGE_INSTANCE_GTK_CLIPWIDGET (p), &a);
1966 } 1977 }
1967 1978
1968 /* #### FIXME DAMMIT */ 1979 if (moving)
1969 if ((wid->allocation.x != -dga->xoffset) ||
1970 (wid->allocation.y != -dga->yoffset))
1971 { 1980 {
1972 guint32 old_flags = GTK_WIDGET_FLAGS (FRAME_GTK_TEXT_WIDGET (f)); 1981 guint32 old_flags = GTK_WIDGET_FLAGS (FRAME_GTK_TEXT_WIDGET (f));
1973 1982
1974 /* Fucking GtkFixed widget queues a resize when you add a widget. 1983 /* GtkFixed widget queues a resize when you add a widget.
1975 ** But only if it is visible. 1984 ** But only if it is visible.
1976 ** losers. 1985 ** losers.
1977 */ 1986 */
1978 GTK_WIDGET_FLAGS(FRAME_GTK_TEXT_WIDGET (f)) &= ~GTK_VISIBLE; 1987 GTK_WIDGET_FLAGS(FRAME_GTK_TEXT_WIDGET (f)) &= ~GTK_VISIBLE;
1988
1979 if (IMAGE_INSTANCE_GTK_ALREADY_PUT(p)) 1989 if (IMAGE_INSTANCE_GTK_ALREADY_PUT(p))
1980 { 1990 {
1981 gtk_fixed_move (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)), 1991 gtk_fixed_move (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)),
1982 wid, 1992 wid,
1983 -dga->xoffset, -dga->yoffset); 1993 a.x, a.y);
1984 } 1994 }
1985 else 1995 else
1986 { 1996 {
1987 IMAGE_INSTANCE_GTK_ALREADY_PUT(p) = TRUE; 1997 IMAGE_INSTANCE_GTK_ALREADY_PUT(p) = TRUE;
1988 gtk_fixed_put (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)), 1998 gtk_fixed_put (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)),
1989 wid, 1999 wid,
1990 -dga->xoffset, -dga->yoffset); 2000 a.x, a.y);
1991 } 2001 }
2002
1992 GTK_WIDGET_FLAGS(FRAME_GTK_TEXT_WIDGET (f)) = old_flags; 2003 GTK_WIDGET_FLAGS(FRAME_GTK_TEXT_WIDGET (f)) = old_flags;
1993 } 2004 }
1994 else 2005 else
1995 { 2006 {
1996 if (IMAGE_INSTANCE_GTK_ALREADY_PUT(p)) 2007 if (IMAGE_INSTANCE_GTK_ALREADY_PUT(p))
2001 { 2012 {
2002 /* Must make sure we have put the image at least once! */ 2013 /* Must make sure we have put the image at least once! */
2003 IMAGE_INSTANCE_GTK_ALREADY_PUT(p) = TRUE; 2014 IMAGE_INSTANCE_GTK_ALREADY_PUT(p) = TRUE;
2004 gtk_fixed_put (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)), 2015 gtk_fixed_put (GTK_FIXED (FRAME_GTK_TEXT_WIDGET (f)),
2005 wid, 2016 wid,
2006 -dga->xoffset, -dga->yoffset); 2017 a.x, a.y);
2007 } 2018 }
2008 } 2019 }
2009 2020
2010 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p)) 2021 if (!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (p))
2011 { 2022 {
2091 || 2102 ||
2092 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p) 2103 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)
2093 || 2104 ||
2094 IMAGE_INSTANCE_TEXT_CHANGED (p)) 2105 IMAGE_INSTANCE_TEXT_CHANGED (p))
2095 { 2106 {
2107 GtkRequisition r;
2108 GtkAllocation a = IMAGE_INSTANCE_GTK_CLIPWIDGET (p)->allocation;
2109
2096 assert (IMAGE_INSTANCE_GTK_WIDGET_ID (p) && 2110 assert (IMAGE_INSTANCE_GTK_WIDGET_ID (p) &&
2097 IMAGE_INSTANCE_GTK_CLIPWIDGET (p)) ; 2111 IMAGE_INSTANCE_GTK_CLIPWIDGET (p)) ;
2098 2112
2099 /* #### Resize the widget! */ 2113 a.width = r.width = IMAGE_INSTANCE_WIDTH (p);
2100 /* gtk_widget_size_allocate () */ 2114 a.height = r.height = IMAGE_INSTANCE_HEIGHT (p);
2115
2116 /* Force the widget's preferred and actual size to what we say it shall
2117 be. */
2118 gtk_widget_size_request (IMAGE_INSTANCE_GTK_CLIPWIDGET (p), &r);
2119 gtk_widget_size_allocate (IMAGE_INSTANCE_GTK_CLIPWIDGET (p), &a);
2101 } 2120 }
2102 2121
2103 /* Adjust offsets within the frame. */ 2122 /* Adjust offsets within the frame. */
2104 if (XFRAME (IMAGE_INSTANCE_FRAME (p))->size_changed) 2123 if (XFRAME (IMAGE_INSTANCE_FRAME (p))->size_changed)
2105 { 2124 {
2252 2271
2253 /* #### HACK!!!! We should make this do the right thing if we 2272 /* #### HACK!!!! We should make this do the right thing if we
2254 ** really need a clip widget! 2273 ** really need a clip widget!
2255 */ 2274 */
2256 IMAGE_INSTANCE_GTK_CLIPWIDGET (ii) = w; 2275 IMAGE_INSTANCE_GTK_CLIPWIDGET (ii) = w;
2276
2277 /* The current theme may produce a widget of a different size that what we
2278 expect so force reconsideration of the widget's size. */
2279 IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 1;
2257 2280
2258 return (Qt); 2281 return (Qt);
2259 } 2282 }
2260 2283
2261 static void 2284 static void
2301 FAKE_GTK_WIDGET_INSTANTIATOR(native_layout); 2324 FAKE_GTK_WIDGET_INSTANTIATOR(native_layout);
2302 FAKE_GTK_WIDGET_INSTANTIATOR(button); 2325 FAKE_GTK_WIDGET_INSTANTIATOR(button);
2303 FAKE_GTK_WIDGET_INSTANTIATOR(progress_gauge); 2326 FAKE_GTK_WIDGET_INSTANTIATOR(progress_gauge);
2304 FAKE_GTK_WIDGET_INSTANTIATOR(edit_field); 2327 FAKE_GTK_WIDGET_INSTANTIATOR(edit_field);
2305 FAKE_GTK_WIDGET_INSTANTIATOR(combo_box); 2328 FAKE_GTK_WIDGET_INSTANTIATOR(combo_box);
2306 FAKE_GTK_WIDGET_INSTANTIATOR(tab_control);
2307 FAKE_GTK_WIDGET_INSTANTIATOR(label); 2329 FAKE_GTK_WIDGET_INSTANTIATOR(label);
2330 /* Note: tab_control has a custom instantiator (see below) */
2331
2332 /*
2333 Ask the widget to return it's preferred size. This device method must
2334 defined for all widgets that also have format specific version of
2335 query_geometry defined in glyphs-widget.c. This is because those format
2336 specific versions return sizes that are appropriate for the X widgets. For
2337 GTK, the size of a widget can change at runtime due to the user changing
2338 their theme.
2339
2340 This method can be called before the widget is instantiated. This is
2341 because instantiate_image_instantiator() is tying to be helpful to other
2342 toolkits and supply sane geometry values to them. This is not appropriate
2343 for GTK and can be ignored.
2344
2345 This method can be used by all widgets.
2346 */
2347 static void
2348 gtk_widget_query_geometry (Lisp_Object image_instance,
2349 int* width, int* height,
2350 enum image_instance_geometry disp, Lisp_Object domain)
2351 {
2352 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
2353
2354 if (p->data != NULL)
2355 {
2356 GtkWidget *w = IMAGE_INSTANCE_GTK_CLIPWIDGET (p);
2357 GtkRequisition r;
2358
2359 gtk_widget_size_request(w, &r);
2360 *height= r.height;
2361 *width = r.width;
2362 }
2363 }
2364
2365
2366 /* Button functions. */
2308 2367
2309 /* Update a button's clicked state. */ 2368 /* Update a button's clicked state. */
2310 static void 2369 static void
2311 gtk_button_redisplay (Lisp_Object image_instance) 2370 gtk_button_redisplay (Lisp_Object image_instance)
2312 { 2371 {
2345 return Qnil; 2404 return Qnil;
2346 } 2405 }
2347 return Qunbound; 2406 return Qunbound;
2348 } 2407 }
2349 2408
2409
2410 /* Progress gauge functions. */
2411
2350 /* set the properties of a progress gauge */ 2412 /* set the properties of a progress gauge */
2351 static void 2413 static void
2352 gtk_progress_gauge_redisplay (Lisp_Object image_instance) 2414 gtk_progress_gauge_redisplay (Lisp_Object image_instance)
2353 { 2415 {
2354 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); 2416 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2362 f = XFLOATINT (val); 2424 f = XFLOATINT (val);
2363 2425
2364 gtk_progress_set_value (GTK_PROGRESS (IMAGE_INSTANCE_SUBWINDOW_ID (ii)), 2426 gtk_progress_set_value (GTK_PROGRESS (IMAGE_INSTANCE_SUBWINDOW_ID (ii)),
2365 f); 2427 f);
2366 } 2428 }
2429 }
2430
2431
2432 /* Tab Control functions. */
2433
2434 /*
2435 Register a widget's callbacks with the frame's hashtable. The hashtable is
2436 weak so deregistration is handled automatically. Tab controls have per-tab
2437 callback list functions and the GTK callback architecture is not
2438 sufficiently flexible to deal with this. Instead, the functions are
2439 registered here and the id is passed through the callback loop.
2440 */
2441 static int
2442 gtk_register_gui_item (Lisp_Object image_instance, Lisp_Object gui,
2443 Lisp_Object domain)
2444 {
2445 struct frame *f = XFRAME(DOMAIN_FRAME(domain));
2446 int id = gui_item_id_hash(FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE(f),
2447 gui, WIDGET_GLYPH_SLOT);
2448
2449 Fputhash(make_int(id), image_instance,
2450 FRAME_GTK_WIDGET_INSTANCE_HASH_TABLE (f));
2451 Fputhash(make_int(id), XGUI_ITEM (gui)->callback,
2452 FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE (f));
2453 Fputhash(make_int(id), XGUI_ITEM (gui)->callback_ex,
2454 FRAME_GTK_WIDGET_CALLBACK_EX_HASH_TABLE (f));
2455 return id;
2456 }
2457
2458 /*
2459 Append the given item as a tab to the notebook. Callbacks, etc are all
2460 setup.
2461 */
2462 static void
2463 gtk_add_tab_item(Lisp_Object image_instance,
2464 GtkNotebook* nb, Lisp_Object item,
2465 Lisp_Object domain, int i)
2466 {
2467 Lisp_Object name;
2468 int hash_id = 0;
2469 char *c_name = NULL;
2470 GtkWidget* box;
2471
2472 if (GUI_ITEMP (item))
2473 {
2474 Lisp_Gui_Item *pgui = XGUI_ITEM (item);
2475
2476 if (!STRINGP (pgui->name))
2477 pgui->name = eval_within_redisplay (pgui->name);
2478
2479 if (!STRINGP (pgui->name)) {
2480 warn_when_safe (Qredisplay, Qwarning,
2481 "Name does not evaluate to string");
2482
2483 return;
2484 }
2485
2486 hash_id = gtk_register_gui_item (image_instance, item, domain);
2487 name = pgui->name;
2488 }
2489 else
2490 {
2491 CHECK_STRING (item);
2492 name = item;
2493 }
2494
2495 TO_EXTERNAL_FORMAT (LISP_STRING, name,
2496 C_STRING_ALLOCA, c_name,
2497 Qctext);
2498
2499 /* Dummy widget that the notbook wants to display when a tab is selected. */
2500 box = gtk_vbox_new (FALSE, 3);
2501
2502 /*
2503 Store the per-tab callback data id in the tab. The callback functions
2504 themselves could have been stored in the widget but this avoids having to
2505 worry about the garbage collector running between here and the callback
2506 function.
2507 */
2508 gtk_object_set_data(GTK_OBJECT(box), GTK_DATA_TAB_HASHCODE_IDENTIFIER,
2509 (gpointer) hash_id);
2510
2511 gtk_notebook_append_page (nb, box, gtk_label_new (c_name));
2512 }
2513
2514 /* Signal handler for the switch-page signal. */
2515 static void gtk_tab_control_callback(GtkNotebook *notebook,
2516 GtkNotebookPage *page,
2517 gint page_num,
2518 gpointer user_data)
2519 {
2520 /*
2521 This callback is called for every selection, not just user selection.
2522 We're only interested in user selection, which occurs outside of
2523 redisplay.
2524 */
2525
2526 if (!in_display)
2527 {
2528 Lisp_Object image_instance, callback, callback_ex;
2529 Lisp_Object frame, event;
2530 int update_subwindows_p = 0;
2531 struct frame *f = gtk_widget_to_frame(GTK_WIDGET(notebook));
2532 int id;
2533
2534 if (!f)
2535 return;
2536 frame = wrap_frame (f);
2537
2538 id = (int) gtk_object_get_data(GTK_OBJECT(page->child),
2539 GTK_DATA_TAB_HASHCODE_IDENTIFIER);
2540 image_instance = Fgethash(make_int_verify(id),
2541 FRAME_GTK_WIDGET_INSTANCE_HASH_TABLE(f), Qnil);
2542 callback = Fgethash(make_int(id),
2543 FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE(f), Qnil);
2544 callback_ex = Fgethash(make_int(id),
2545 FRAME_GTK_WIDGET_CALLBACK_EX_HASH_TABLE(f), Qnil);
2546 update_subwindows_p = 1;
2547
2548 /* It is possible for a widget action to cause it to get out of
2549 sync with its instantiator. Thus it is necessary to signal
2550 this possibility. */
2551 if (IMAGE_INSTANCEP (image_instance))
2552 XIMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (image_instance) = 1;
2553
2554 if (!NILP (callback_ex) && !UNBOUNDP (callback_ex))
2555 {
2556 event = Fmake_event (Qnil, Qnil);
2557
2558 XSET_EVENT_TYPE (event, misc_user_event);
2559 XSET_EVENT_CHANNEL (event, frame);
2560 XSET_EVENT_MISC_USER_FUNCTION (event, Qeval);
2561 XSET_EVENT_MISC_USER_OBJECT (event, list4 (Qfuncall, callback_ex, image_instance, event));
2562 }
2563 else if (NILP (callback) || UNBOUNDP (callback))
2564 event = Qnil;
2565 else
2566 {
2567 Lisp_Object fn, arg;
2568
2569 event = Fmake_event (Qnil, Qnil);
2570
2571 get_gui_callback (callback, &fn, &arg);
2572 XSET_EVENT_TYPE (event, misc_user_event);
2573 XSET_EVENT_CHANNEL (event, frame);
2574 XSET_EVENT_MISC_USER_FUNCTION (event, fn);
2575 XSET_EVENT_MISC_USER_OBJECT (event, arg);
2576 }
2577
2578 if (!NILP (event))
2579 enqueue_dispatch_event (event);
2580
2581 /* The result of this evaluation could cause other instances to change so
2582 enqueue an update callback to check this. */
2583 if (update_subwindows_p && !NILP (event))
2584 enqueue_magic_eval_event (update_widget_instances, frame);
2585 }
2586 }
2587
2588 /* Create a tab_control widget. The special handling of the individual tabs
2589 means that the normal instantiation code cannot be used. */
2590 static void
2591 gtk_tab_control_instantiate (Lisp_Object image_instance,
2592 Lisp_Object instantiator,
2593 Lisp_Object pointer_fg,
2594 Lisp_Object pointer_bg,
2595 int dest_mask, Lisp_Object domain)
2596 {
2597 Lisp_Object rest;
2598 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
2599 int i = 0;
2600 int selected = 0;
2601 GtkNotebook *nb;
2602
2603 /* The normal instantiation is still needed. */
2604 gtk_widget_instantiate (image_instance, instantiator, pointer_fg,
2605 pointer_bg, dest_mask, domain);
2606
2607 nb = GTK_NOTEBOOK (IMAGE_INSTANCE_GTK_CLIPWIDGET (ii));
2608
2609 /* Add items to the tab, find the current selection */
2610 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
2611 {
2612 gtk_add_tab_item (image_instance, nb, XCAR (rest), domain, i);
2613
2614 if (gui_item_selected_p (XCAR (rest)))
2615 selected = i;
2616
2617 i++;
2618 }
2619
2620 gtk_notebook_set_page(nb, selected);
2621
2622 /* Call per-tab lisp callback when a tab is pressed. */
2623 gtk_signal_connect (GTK_OBJECT (nb), "switch-page",
2624 GTK_SIGNAL_FUNC (gtk_tab_control_callback), NULL);
2367 } 2625 }
2368 2626
2369 /* Set the properties of a tab control */ 2627 /* Set the properties of a tab control */
2370 static void 2628 static void
2371 gtk_tab_control_redisplay (Lisp_Object image_instance) 2629 gtk_tab_control_redisplay (Lisp_Object image_instance)
2380 one of the pending set. This stops horrendous rebuilding - 2638 one of the pending set. This stops horrendous rebuilding -
2381 and hence flicker - of the tabs each time you click on 2639 and hence flicker - of the tabs each time you click on
2382 one. */ 2640 one. */
2383 if (tab_control_order_only_changed (image_instance)) 2641 if (tab_control_order_only_changed (image_instance))
2384 { 2642 {
2643 int i = 0;
2385 Lisp_Object rest, selected = 2644 Lisp_Object rest, selected =
2386 gui_item_list_find_selected 2645 gui_item_list_find_selected
2387 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ? 2646 (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ?
2388 XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) : 2647 XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) :
2389 XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))); 2648 XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
2392 { 2651 {
2393 if (gui_item_equal_sans_selected (XCAR (rest), selected, 0)) 2652 if (gui_item_equal_sans_selected (XCAR (rest), selected, 0))
2394 { 2653 {
2395 Lisp_Object old_selected =gui_item_list_find_selected 2654 Lisp_Object old_selected =gui_item_list_find_selected
2396 (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))); 2655 (XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
2397
2398 /* Need to focus on the widget... */
2399 stderr_out ("Hey, change the tab-focus you boob...\n");
2400 2656
2401 /* Pick up the new selected item. */ 2657 /* Pick up the new selected item. */
2402 XGUI_ITEM (old_selected)->selected = 2658 XGUI_ITEM (old_selected)->selected =
2403 XGUI_ITEM (XCAR (rest))->selected; 2659 XGUI_ITEM (XCAR (rest))->selected;
2404 XGUI_ITEM (XCAR (rest))->selected = 2660 XGUI_ITEM (XCAR (rest))->selected =
2405 XGUI_ITEM (selected)->selected; 2661 XGUI_ITEM (selected)->selected;
2406 /* We're not actually changing the items anymore. */ 2662 /* We're not actually changing the items anymore. */
2407 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0; 2663 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
2408 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil; 2664 IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
2665
2666 gtk_notebook_set_page(GTK_NOTEBOOK (IMAGE_INSTANCE_GTK_CLIPWIDGET (ii)),
2667 i);
2409 break; 2668 break;
2410 } 2669 }
2670
2671 i++;
2411 } 2672 }
2412 } 2673 }
2413 else 2674 else
2414 { 2675 {
2415 /* More than just the order has changed... let's get busy! */ 2676 /* More than just the order has changed... let's get busy! */
2416 GtkNotebook *nb = GTK_NOTEBOOK (IMAGE_INSTANCE_GTK_CLIPWIDGET (ii)); 2677 GtkNotebook *nb = GTK_NOTEBOOK (IMAGE_INSTANCE_GTK_CLIPWIDGET (ii));
2417 guint num_pages = g_list_length (nb->children); 2678 guint num_pages = g_list_length (nb->children);
2418 Lisp_Object rest; 2679 Lisp_Object rest;
2419 2680 int i;
2681
2682 /* Why is there no API to remove everything from a notebook? */
2420 if (num_pages >= 0) 2683 if (num_pages >= 0)
2421 { 2684 {
2422 int i;
2423 for (i = num_pages; i >= 0; --i) 2685 for (i = num_pages; i >= 0; --i)
2424 { 2686 {
2425 gtk_notebook_remove_page (nb, i); 2687 gtk_notebook_remove_page (nb, i);
2426 } 2688 }
2427 } 2689 }
2428 2690
2429 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii))) 2691 i = 0;
2692
2693 LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
2430 { 2694 {
2431 Lisp_Gui_Item *pgui = XGUI_ITEM (XCAR (rest)); 2695 gtk_add_tab_item(image_instance, nb, XCAR(rest),
2432 char *c_name = NULL; 2696 IMAGE_INSTANCE_FRAME(ii), i);
2433
2434 if (!STRINGP (pgui->name))
2435 pgui->name = eval_within_redisplay (pgui->name);
2436
2437 if (!STRINGP (pgui->name))
2438 warn_when_safe (Qredisplay, Qwarning,
2439 "Name does not evaluate to string");
2440 else
2441 {
2442 TO_EXTERNAL_FORMAT (LISP_STRING, pgui->name,
2443 C_STRING_ALLOCA, c_name,
2444 Qctext);
2445
2446 gtk_notebook_append_page (nb,
2447 gtk_vbox_new (FALSE, 3),
2448 gtk_label_new (c_name));
2449 }
2450 } 2697 }
2451 2698
2452 /* Show all the new widgets we just added... */ 2699 /* Show all the new widgets we just added... */
2453 gtk_widget_show_all (GTK_WIDGET (nb)); 2700 gtk_widget_show_all (GTK_WIDGET (nb));
2454 } 2701 }
2539 /* button widget */ 2786 /* button widget */
2540 INITIALIZE_DEVICE_IIFORMAT (gtk, button); 2787 INITIALIZE_DEVICE_IIFORMAT (gtk, button);
2541 IIFORMAT_HAS_DEVMETHOD (gtk, button, property); 2788 IIFORMAT_HAS_DEVMETHOD (gtk, button, property);
2542 IIFORMAT_HAS_DEVMETHOD (gtk, button, instantiate); 2789 IIFORMAT_HAS_DEVMETHOD (gtk, button, instantiate);
2543 IIFORMAT_HAS_DEVMETHOD (gtk, button, redisplay); 2790 IIFORMAT_HAS_DEVMETHOD (gtk, button, redisplay);
2791 IIFORMAT_HAS_SHARED_DEVMETHOD (gtk, button, query_geometry, widget);
2544 /* general widget methods. */ 2792 /* general widget methods. */
2545 INITIALIZE_DEVICE_IIFORMAT (gtk, widget); 2793 INITIALIZE_DEVICE_IIFORMAT (gtk, widget);
2546 IIFORMAT_HAS_DEVMETHOD (gtk, widget, property); 2794 IIFORMAT_HAS_DEVMETHOD (gtk, widget, property);
2795 IIFORMAT_HAS_DEVMETHOD (gtk, widget, query_geometry);
2547 2796
2548 /* progress gauge */ 2797 /* progress gauge */
2549 INITIALIZE_DEVICE_IIFORMAT (gtk, progress_gauge); 2798 INITIALIZE_DEVICE_IIFORMAT (gtk, progress_gauge);
2550 IIFORMAT_HAS_DEVMETHOD (gtk, progress_gauge, redisplay); 2799 IIFORMAT_HAS_DEVMETHOD (gtk, progress_gauge, redisplay);
2551 IIFORMAT_HAS_DEVMETHOD (gtk, progress_gauge, instantiate); 2800 IIFORMAT_HAS_DEVMETHOD (gtk, progress_gauge, instantiate);
2801 IIFORMAT_HAS_SHARED_DEVMETHOD (gtk, progress_gauge, query_geometry, widget);
2552 /* text field */ 2802 /* text field */
2553 INITIALIZE_DEVICE_IIFORMAT (gtk, edit_field); 2803 INITIALIZE_DEVICE_IIFORMAT (gtk, edit_field);
2554 IIFORMAT_HAS_DEVMETHOD (gtk, edit_field, instantiate); 2804 IIFORMAT_HAS_DEVMETHOD (gtk, edit_field, instantiate);
2555 INITIALIZE_DEVICE_IIFORMAT (gtk, combo_box); 2805 INITIALIZE_DEVICE_IIFORMAT (gtk, combo_box);
2556 IIFORMAT_HAS_DEVMETHOD (gtk, combo_box, instantiate); 2806 IIFORMAT_HAS_DEVMETHOD (gtk, combo_box, instantiate);
2557 IIFORMAT_HAS_SHARED_DEVMETHOD (gtk, combo_box, redisplay, tab_control); 2807 IIFORMAT_HAS_SHARED_DEVMETHOD (gtk, combo_box, redisplay, tab_control);
2558 /* tab control widget */ 2808 /* tab control widget */
2559 INITIALIZE_DEVICE_IIFORMAT (gtk, tab_control); 2809 INITIALIZE_DEVICE_IIFORMAT (gtk, tab_control);
2560 IIFORMAT_HAS_DEVMETHOD (gtk, tab_control, instantiate); 2810 IIFORMAT_HAS_DEVMETHOD (gtk, tab_control, instantiate);
2561 IIFORMAT_HAS_DEVMETHOD (gtk, tab_control, redisplay); 2811 IIFORMAT_HAS_DEVMETHOD (gtk, tab_control, redisplay);
2812 IIFORMAT_HAS_SHARED_DEVMETHOD (gtk, tab_control, query_geometry, widget);
2562 /* label */ 2813 /* label */
2563 INITIALIZE_DEVICE_IIFORMAT (gtk, label); 2814 INITIALIZE_DEVICE_IIFORMAT (gtk, label);
2564 IIFORMAT_HAS_DEVMETHOD (gtk, label, instantiate); 2815 IIFORMAT_HAS_DEVMETHOD (gtk, label, instantiate);
2565 #endif 2816 #endif
2566 2817