Mercurial > hg > xemacs-beta
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 |