2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
25 * $XConsortium: pal_create.c /main/4 1996/07/25 09:19:49 mustafa $
27 * @(#)pal_create.c 1.102 19 May 1995
29 * RESTRICTED CONFIDENTIAL INFORMATION:
31 * The information in this document is subject to special
32 * restrictions in a confidential disclosure agreement between
33 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
34 * document outside HP, IBM, Sun, USL, SCO, or Univel without
35 * Sun's specific written approval. This document and all copies
36 * and derivative works thereof must be returned or destroyed at
39 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
45 ***********************************************************************
46 * pal_create.c - Implements object creation (dragging & dropping items
49 ***********************************************************************
52 #include <X11/Intrinsic.h>
54 #include <Xm/BulletinB.h>
55 #include <Xm/CascadeB.h>
59 #include <Xm/ToggleB.h>
60 #include <Xm/SelectioB.h>
62 #include <Dt/SpinBox.h>
63 #include <Dt/ComboBox.h>
64 #include <ab_private/trav.h>
65 #include <ab_private/objxm.h>
66 #include <ab_private/brws.h>
67 #include <ab_private/proj.h>
68 #include <ab_private/abobj.h>
69 #include <ab_private/abobj_set.h>
70 #include <ab_private/abobj_edit.h>
71 #include <ab_private/ab.h>
72 #include <ab_private/pal.h>
73 #include <ab_private/prop.h>
74 #include <ab_private/ui_util.h>
75 #include <ab_private/x_util.h>
76 #include "dtbuilder.h"
77 #include "palette_ui.h"
79 const int AB_max_item_height = 64;
80 const int AB_max_item_width = 256;
83 * Default (x,y) positions of objects when dragged out
84 * from palette. This is only used when the objects are not
85 * dropped onto the interface created, but dropped instead
88 #define AB_DEFAULT_X 0
89 #define AB_DEFAULT_Y 0
91 /*************************************************************************
93 ** Private Function Declarations **
95 **************************************************************************/
96 static void palitem_update_type(
102 static void palitem_select_event(
108 static void palitem_drag_action(
113 static void palitem_release_event(
119 static void create_obj_action(
124 static char *locate_obj_parent(
132 static Boolean initiate_drag(
140 static XImage *build_item_image(
143 static void image_copy(
151 ABObj locate_obj_at_rootxy(
159 /*************************************************************************
163 **************************************************************************/
164 static Widget palette_widget = NULL;
165 static Cursor drag_cursor;
166 static int drag_cursor_xhot;
167 static int drag_cursor_yhot;
168 static Boolean drag_on = FALSE;
170 /*************************************************************************
172 ** Function Definitions **
174 **************************************************************************/
176 * Set up palette item(widget) to handle select-drag operation
179 pal_enable_item_drag(
184 static int st_subtype;
186 st_subtype = subtype;
187 XtInsertEventHandler(widget, ButtonPressMask, FALSE,
188 palitem_select_event, (XtPointer)&st_subtype, XtListHead);
189 XtInsertEventHandler(widget, ButtonReleaseMask, FALSE,
190 palitem_release_event, (XtPointer)&st_subtype, XtListHead);
191 XtAddEventHandler(widget, EnterWindowMask|LeaveWindowMask, FALSE,
192 palitem_update_type, (XtPointer)&st_subtype);
194 /* We need to keep track of the main palette widget
195 * for drag-behavior purposes
199 if ((palette_widget = dtb_palette_ab_palette_main.palette_cpanel) == NULL)
201 if (util_get_verbosity() > 2)
202 fprintf(stderr,"pal_enable_item_drag: couldn't find \"%s\"\n",
203 XtName(dtb_palette_ab_palette_main.palette_cpanel));
204 palette_widget = XtParent(XtParent(widget));
211 XtPointer clientData,
213 Boolean *cont_dispatch
216 PalItemInfo *palitem;
217 int subtype = *((int*)clientData);
221 XtVaGetValues(w, XmNuserData, &palitem, NULL);
223 if (event->type == EnterNotify)
225 objname = palitem->name;
227 for(i=0; i < palitem->num_subinfo; i++)
228 if (palitem->subinfo[i].subtype == subtype)
230 objname = palitem->subinfo[i].subname;
234 ab_update_stat_region(AB_STATUS_OBJ_TYPE, objname);
236 else /* LeaveNotify */
237 ab_update_stat_region(AB_STATUS_OBJ_TYPE, " ");
242 * EventHandler: ButtonPress activated on palette item
245 palitem_select_event(
247 XtPointer clientData,
249 Boolean *cont_dispatch
252 XButtonEvent *bevent;
253 int subtype = *((int*)clientData);
255 if (event->type != ButtonPress)
258 bevent = (XButtonEvent*)event;
259 *cont_dispatch = FALSE;
261 if (AB_builder_mode != MODE_BUILD)
264 if (bevent->button == 1 ||
265 (AB_btn1_transfer != True && bevent->button == 2))
266 palitem_drag_action(w, subtype, event);
271 * Action Proc: Palette item has been selected - begin drag
281 Display *dpy = XtDisplay(widget);
283 if (event->type == ButtonPress)
285 XButtonEvent *bevent = (XButtonEvent*)event;
290 if (!initiate_drag(widget, subtype, &x, &y, &drag_cursor_xhot, &drag_cursor_yhot))
293 if (util_get_verbosity() > 2)
294 fprintf(stderr, "palitem_drag_action: couldn't begin drag\n");
303 * EventHandler: ButtonRelease activated on palette item
306 palitem_release_event(
308 XtPointer clientData,
310 Boolean *cont_dispatch
313 XButtonEvent *bevent;
314 int subtype = *((int*)clientData);
316 if (event->type != ButtonRelease)
319 bevent = (XButtonEvent*)event;
320 *cont_dispatch = FALSE;
322 if (AB_builder_mode != MODE_BUILD)
325 if (bevent->button == 1 ||
326 (AB_btn1_transfer != True && bevent->button == 2))
327 create_obj_action(w, subtype, event);
333 * Action Proc: Palette item has been released; if drag was taking
334 * place, release the pointer grab and create object
343 ABObj project = proj_get_project();
345 ABObj obj_parent = NULL;
346 PalItemInfo *palitem;
349 BOOL ModuleCreated = FALSE;
350 XmString xm_buf = (XmString) NULL;
352 dpy = XtDisplay(widget);
356 XUngrabPointer(dpy, CurrentTime);
357 XFreeCursor(dpy, drag_cursor);
361 if (event->type == ButtonRelease)
365 XButtonEvent *bevent = (XButtonEvent *)event;
366 XtVaGetValues(widget, XmNuserData, &palitem, NULL);
368 /* Creation may take awhile, so set busy cursor */
369 xy_win = x_xwin_at_rootxy(AB_toplevel, bevent->x_root,
370 bevent->y_root, &wx, &wy);
371 ab_set_busy_cursor(TRUE);
372 ui_set_busy_cursor(xy_win, TRUE);
374 obj = obj_create(palitem->type, NULL);
376 if (palitem->type == AB_TYPE_SCALE)
377 obj_set_read_only(obj, subtype);
379 if (subtype != AB_NO_SUBTYPE)
380 obj_set_subtype(obj, subtype);
382 if (errmsg = locate_obj_parent(obj, widget, bevent->x_root,
383 bevent->y_root, &obj_parent, &ModuleCreated))
386 if (!util_streq(errmsg, ""))
388 xm_buf = XmStringCreateLocalized(errmsg);
389 dtb_palette_error_msg_initialize(&dtb_palette_error_msg);
390 (void)dtb_show_modal_message(dtb_get_toplevel_widget(),
391 &dtb_palette_error_msg, xm_buf, NULL, NULL);
392 XmStringFree(xm_buf);
397 if (pal_initialize_obj(obj) == ERROR)
398 fprintf(stderr, "create_obj_action: couldn't initialize object\n");
399 else if (abobj_show_tree(obj, TRUE) == -1)
400 fprintf(stderr,"create_obj_action: couldn't show object\n");
403 /* set the initial visiblity of new layers to false */
404 if (obj_is_layers(obj_parent))
405 obj_set_is_initially_visible(obj, FALSE);
407 /* Deselect any objects that happen to be selected */
408 abobj_deselect_all(project);
409 aob_deselect_all_objects(project);
411 /* Make the new obj selected */
414 /* Set the dirty bit on the module */
415 abobj_set_save_needed(obj_get_module(obj), TRUE);
417 /* If the window is the first one dragged out and
418 * its parent (the module) has not been named yet,
419 * popup the module name dialog. The only time a
420 * module will have not been named by the user is
421 * when it is created at the time the first window
422 * is dragged from the palette.
424 if( obj_is_window(obj) && ModuleCreated )
426 /* Pop up the name dialog */
427 proj_show_name_dlg(obj_parent, objxm_get_widget(obj));
431 * Once an object is successfully dragged out from the
432 * palette, disable undo. Object creation is not undo-able.
437 /* Restore to original cursor */
438 ab_set_busy_cursor(FALSE);
439 ui_set_busy_cursor(xy_win, FALSE);
444 * Make a cursor from the palette item's image & cursor
445 * and grab the cursor...
458 static unsigned int max_c_width = 0; /* The maximum cursor size */
459 static unsigned int max_c_height = 0;
460 static Pixmap item_pixmap = NULL;/* pixmap for cursor */
461 static GC p_gc = NULL; /* GC used for pixmap creation */
462 char *server_vendor = NULL;
463 PalItemInfo *palitem; /* palette obj */
464 PalSubtypeInfo *palitem_subptr = NULL;
465 Widget item_widget = w; /* widget used for cursor image */
466 XRectangle w_rect; /* widget width,height,x,y */
467 int c_width, c_height; /* cursor width & height */
468 int cc_width, cc_height;/* copycursor width & height */
473 if (max_c_width == 0) /* Need to Query server's Cursor constraints */
475 server_vendor = XServerVendor(XtDisplay(w));
477 if (strcmp(server_vendor, "Sun Microsystems, Inc.") == 0)
480 * On a Sun X server, a call to XQueryBestSize() will return a limit
481 * based on a *hardware* cursor; this is misleading because the
482 * server actually supports a much larger software cursor (only limited
483 * by the screen size); therefore set the limit based on screen size.
485 max_c_width = WidthOfScreen(XtScreen(w));
486 max_c_height = HeightOfScreen(XtScreen(w));
489 /* Ask for a big size to get the maximum */
490 XQueryBestSize(XtDisplay(w), CursorShape, XtWindow(w), 1000, 1000,
491 &max_c_width, &max_c_height);
493 util_dprintf(0, "For Server(%s) Max Cursor size = %dx%d\n",
494 server_vendor, max_c_width, max_c_height);
496 * Need to leave room for the outlining of the object's image
497 * which is taken care of in x_create_stencil_cursor().
504 XmNuserData, &palitem,
505 XtNwidth, &(w_rect.width),
506 XtNheight, &(w_rect.height),
511 * Create Drag Cursor containing item's image
515 * If item is a choice setting or textfield, need to
516 * use the parent container's image for the cursor;
517 * also must translate the cursor x,y position to
518 * the parent's rectangle coordinates
521 * For SpinBox, this is done if the widget passed
522 * is not a subclass of spinbox. (We cannot assume
523 * what these widgets are composed of).
525 if ((palitem->type == AB_TYPE_CHOICE &&
526 XtIsSubclass(w, xmToggleButtonWidgetClass)) ||
527 (palitem->type == AB_TYPE_CONTAINER &&
528 XtIsSubclass(w, xmCascadeButtonWidgetClass)) ||
529 (palitem->type == AB_TYPE_TEXT_FIELD &&
530 (XtIsSubclass(w, xmLabelWidgetClass) ||
531 XtIsSubclass(w, xmTextFieldWidgetClass))) ||
532 (palitem->type == AB_TYPE_SPIN_BOX &&
533 !XtIsSubclass(w, dtSpinBoxWidgetClass)) ||
534 (palitem->type == AB_TYPE_COMBO_BOX &&
535 !XtIsSubclass(w, dtComboBoxWidgetClass)) ||
536 (palitem->type == AB_TYPE_SCALE &&
537 !XtIsSubclass(w, xmScaleWidgetClass)))
539 item_widget = XtParent(w);
544 XtVaGetValues(item_widget,
545 XmNuserData, (XtArgVal)&palitem,
546 XtNwidth, (XtArgVal)&(w_rect.width),
547 XtNheight, (XtArgVal)&(w_rect.height),
551 dpy = (Display *)XtDisplay(item_widget);
552 win = (Window) XtWindow(item_widget);
554 cc_width = AB_cp_cursor_width;
555 cc_height = AB_cp_cursor_height;
557 if (dtb_app_resource_rec.use_small_drag_cursor == FALSE)
559 c_width = AB_max_item_width + cc_width + 4;
560 c_height = AB_max_item_height + cc_height + 4;
562 else /* Need Drag Cursor <= 32x32 */
569 * Ensure cursor is within server limits
570 * Note that on some servers (HP, IBM) the cursor limitation
571 * will cause some object drag-cursors to be cropped.
572 * Unfortunately, for 1.0, there is nothing we can do about
575 if (c_width > max_c_width)
576 c_width = max_c_width;
577 if (c_height > max_c_height)
578 c_height = max_c_height;
580 if (!p_gc) /* First-time thru: Create Cursor pixmaps & GC */
583 Pixel fg_pixel, bg_pixel;
585 item_pixmap = XCreatePixmap(dpy, win, c_width, c_height, 1);
587 fg_pixel = BlackPixelOfScreen(XtScreen(item_widget));
588 bg_pixel = WhitePixelOfScreen(XtScreen(item_widget));
590 values.foreground = fg_pixel;
591 values.background = bg_pixel;
592 p_gc = XCreateGC(dpy, item_pixmap, GCForeground|GCBackground, &values);
595 /* Find the appropriate palette pixmap for the object subtype */
596 for (i=0; i < palitem->num_subinfo; i++)
597 if (palitem->subinfo[i].subtype == subtype)
599 palitem_subptr = &(palitem->subinfo[i]);
603 /* This should never happen! */
604 if (palitem_subptr == NULL)
606 util_dprintf(0,"initiate_drag: could not find palette object subtype info\n");
610 if (!palitem_subptr->pixmap)
614 item_image = build_item_image(item_widget);
615 /* no error recovery here. Do we care? */
617 palitem_subptr->pmwidth = w_rect.width + 4;
618 palitem_subptr->pmheight = w_rect.height + 4;
619 palitem_subptr->pixmap = XCreatePixmap(dpy, win, palitem_subptr->pmwidth,
620 palitem_subptr->pmheight, 1);
622 XSetFunction(dpy, p_gc, GXclear);
623 XFillRectangle(dpy, palitem_subptr->pixmap, p_gc, 0, 0,
624 w_rect.width + 4, w_rect.height + 4);
626 XSetFunction(dpy, p_gc, GXcopy);
627 XPutImage(dpy, palitem_subptr->pixmap, p_gc, item_image, 0, 0,
628 2, 2, item_image->width, item_image->height);
630 XDestroyImage(item_image);
633 XSetFunction(dpy, p_gc, GXclear);
634 XFillRectangle(dpy, item_pixmap, p_gc, 0, 0, c_width, c_height);
636 XSetFunction(dpy, p_gc, GXcopy);
637 if (dtb_app_resource_rec.use_small_drag_cursor == FALSE)
639 /* Copy the item's image pixmap onto the cursor_pixmap */
640 XCopyArea(dpy, palitem_subptr->pixmap, item_pixmap, p_gc, 0, 0,
641 c_width, c_height, 0, 0);
646 else /* dtb_app_resource_rec.use_small_drag_cursor == TRUE */
651 /* Render a simple shape describing basic type of
652 * object is being dragged....
654 switch(palitem->type)
656 case AB_TYPE_BASE_WINDOW:
664 case AB_TYPE_CONTAINER:
665 case AB_TYPE_DRAWING_AREA:
666 case AB_TYPE_TEXT_PANE:
667 case AB_TYPE_TERM_PANE:
673 default: /* Controls */
679 XDrawRectangle(dpy, item_pixmap, p_gc, 0, 0, rw, rh);
681 XDrawLine(dpy, item_pixmap, p_gc, 0, 4, rw, 4);
685 /* overlay image of copycursor on item image */
686 XSetFunction(dpy, p_gc, GXor);
687 x_graphics_op(dpy, item_pixmap, p_gc, *xhot, *yhot,
688 cc_width, cc_height, AB_cp_cursor_pixmap);
691 * Ensure hot-spot is within server cursor size
695 if (*yhot > c_height)
696 *yhot = c_height - 4;
698 drag_cursor = x_create_stencil_cursor(item_widget, item_pixmap,
699 c_width, c_height, *xhot, *yhot);
701 if (XGrabPointer(dpy, win, FALSE,
702 ButtonReleaseMask | PointerMotionMask,
703 GrabModeAsync, GrabModeAsync, None, drag_cursor,
704 CurrentTime) == GrabSuccess)
707 XFreeCursor(dpy, drag_cursor);
714 * Get a 1-bit image of the palette item
726 XWindowAttributes attr;
727 char *new_image_data;
730 * Get the item's bounding rect and other associated information.
732 x_get_widget_rect(widget, &w_rect);
734 win = (Window)XtWindow(widget);
735 dpy = (Display *)XtDisplay(widget);
738 * Get the item's image and it's attributes (including visual).
740 get_image = XGetImage(dpy,
749 XGetWindowAttributes(dpy, win, &attr);
752 * Create a new blank image.
754 new_image_data = (char *)XtMalloc((w_rect.width * w_rect.height) * sizeof(char));
755 new_image = XCreateImage(dpy,
767 * Copy the specified planes from the "get" image to the new image.
769 image_copy(widget, get_image, new_image, w_rect.width, 0, 0);
771 XDestroyImage(get_image);
777 * Copy item's outline image to a 1 bit image
789 register int i, j, k, pix;
792 Pixel bshadow, tshadow;
796 * Only draw bits that are not part of the background and, if
797 * color, the depression color (BG2).
799 XtVaGetValues(widget,
800 XtNbackground, &background,
801 XtNforeground, &foreground,
802 XmNbottomShadowColor, &bshadow,
803 XmNtopShadowColor, &tshadow,
806 black = BlackPixelOfScreen(XtScreen(widget));
807 white = WhitePixelOfScreen(XtScreen(widget));
809 for (i = 0; i < from_image->height; i++)
811 for (j = get_x, k = put_x; j < image_width; j++, k++)
813 pix = XGetPixel(from_image, j, i);
814 if ((pix == foreground ||
820 XPutPixel(to_image, k, i, black);
822 XPutPixel(to_image, k, i, white);
828 * Figure out which ui object the palette item was dropped on
840 ABObj project = proj_get_project();
841 ABObj module = proj_get_cur_module();
842 ABObj obj_parent = (ABObj) NULL;
843 Display *dpy = (Display *)XtDisplay(widget);
845 DTB_MODAL_ANSWER answer = DTB_ANSWER_NONE;
846 STRING errmsg = (STRING) NULL;
847 STRING i18n_msg = (STRING) NULL;
849 *ModuleCreated = FALSE;
851 if (obj_is_window(obj))
853 if (x_rootxy_inside_widget(palette_widget, x, y))
856 if ( module == NULL )
858 obj_parent = obj_create(AB_TYPE_MODULE, project);
859 obj_set_name(obj_parent, "module");
860 abobj_show_tree(obj_parent, FALSE);
861 proj_set_cur_module(obj_parent);
862 *ModuleCreated = TRUE;
868 obj_append_child(obj_parent, obj);
870 obj->x = x - drag_cursor_xhot;
871 obj->y = y - drag_cursor_yhot;
875 obj_parent = locate_obj_at_rootxy(x, y, &w_x, &w_y);
877 obj->x = w_x - drag_cursor_xhot;
878 obj->y = w_y - drag_cursor_yhot;
880 /* If not dropped on an object, but is still within
881 * palette, just ignore the drag...
883 if (obj_parent == NULL &&
884 x_rootxy_inside_widget(palette_widget, x, y))
887 if (obj_is_menubar(obj))
893 if (obj_parent != NULL)
896 while(!(obj_is_window(winobj) && !obj_is_sub(winobj)))
897 winobj = obj_get_parent(winobj);
899 if (!obj_is_base_win(winobj))
901 else /* Check to make sure there isn't already a Menubar for
905 for (trav_open(&trav, winobj, AB_TRAV_UI);
906 (nobj = trav_next(&trav)) != NULL; )
907 if (obj_is_menubar(nobj))
909 i18n_msg = catgets(Dtb_project_catd, 100, 11,
910 "There is already a Menubar for this window.");
912 /* If we have an old buffer lying around, free it */
913 if (errmsg != (STRING) NULL)
916 errmsg = (STRING) util_malloc(strlen(i18n_msg) + 1);
917 strcpy(errmsg, i18n_msg);
921 obj_parent = objxm_comp_get_subobj(winobj, AB_CFG_MENU_PARENT_OBJ);
924 if (obj_parent == NULL)
926 i18n_msg = catgets(Dtb_project_catd, 100, 15,
927 "Menubars must be dropped on a Main Window.");
929 /* If we have an old buffer lying around, free it */
930 if (errmsg != (STRING) NULL)
933 errmsg = (STRING) util_malloc(strlen(i18n_msg) + 1);
934 strcpy(errmsg, i18n_msg);
939 else if (obj_is_container(obj) && !obj_is_control_panel(obj))
941 if (obj_parent == NULL ||
942 (!(obj_is_container(obj_parent) &&
943 obj_is_sub(obj_parent) &&
944 obj_is_window(obj_get_root(obj_parent)) &&
945 !obj_is_file_chooser(obj_parent))))
947 i18n_msg = catgets(Dtb_project_catd, 100, 12,
948 "Containers must be dropped on\na Main Window or Custom Dialog.");
949 /* If we have an old buffer lying around, free it */
950 if (errmsg != (STRING) NULL)
953 errmsg = (STRING) util_malloc(strlen(i18n_msg) + 1);
954 strcpy(errmsg, i18n_msg);
958 else if (obj_is_pane(obj))
960 if (obj_parent != NULL &&
961 (obj_is_pane(obj_parent) &&
962 !obj_is_window(obj_get_root(obj_parent))))
964 ABObj grandparent = NULL;
965 ABObj great_grandparent = NULL;
966 grandparent = obj_get_parent(obj_get_root(obj_parent));
967 great_grandparent = obj_get_parent(grandparent);
969 /* The child is a textpane, termpane, or drawing area
970 * and the parent (object being dropped upon) is a
971 * control pane that is not part of a panedWindow.
973 if (!obj_is_control_panel(obj) &&
974 obj_is_control_panel(obj_parent) &&
975 !obj_is_paned_win(grandparent))
977 /* If the parent of obj_parent is a layered pane
978 * then we have to check if the layered pane is
979 * a child of a panedwindow. If so, then we should
980 * ask the user whether he wants to make the pane
981 * a child of the control pane, a new layer, or
982 * a new pane in the paned window.
984 if (obj_is_layers(grandparent) &&
985 obj_is_paned_win(great_grandparent))
987 dtb_palette_chld_layr_pw_msg_initialize(
988 &dtb_palette_chld_layr_pw_msg);
989 answer = dtb_show_modal_message(
990 (Widget)obj_parent->ui_handle,
991 &dtb_palette_chld_layr_pw_msg,
995 /* Create as a child of the control pane */
996 case DTB_ANSWER_ACTION1:
999 /* Create as a new layer */
1000 case DTB_ANSWER_ACTION2:
1001 obj_parent = abobj_handle_layered_pane(obj, obj_parent);
1004 /* Create as a new pane in the paned window */
1005 case DTB_ANSWER_ACTION3:
1006 obj_parent = great_grandparent;
1009 case DTB_ANSWER_CANCEL:
1015 /* Popup Modal Message and wait for answer */
1016 dtb_palette_chld_or_layr_msg_initialize(
1017 &dtb_palette_chld_or_layr_msg);
1018 answer = dtb_show_modal_message(
1019 (Widget)obj_parent->ui_handle,
1020 &dtb_palette_chld_or_layr_msg,
1024 case DTB_ANSWER_ACTION1: /* As Child */
1027 case DTB_ANSWER_ACTION2: /* As Layered Pane */
1028 obj_parent = abobj_handle_layered_pane(obj, obj_parent);
1031 case DTB_ANSWER_CANCEL:
1036 /* The child is a control pane or the parent is
1037 * not a control pane (i.e. a textpane child of
1038 * a control pane). The parent is not part of a
1041 else if (!obj_is_paned_win(grandparent))
1043 /* If Pane was dropped on a Pane which is a NORMAL child of
1044 * a Control Pane, then use the Control Pane as the actual
1045 * parent instead of the pane.
1047 if (obj_is_control_panel(obj_get_root(grandparent)))
1049 obj_parent = grandparent;
1052 /* Check if the grandparent is a layered pane.
1053 * If so, then we have to check it is part of
1054 * a panedwindow. If it is, then we need to
1055 * ask the user whether to create the pane as
1056 * a layered pane or a new pane in the paned
1059 if (obj_is_layers(grandparent) &&
1060 obj_is_paned_win(great_grandparent))
1062 dtb_palette_layr_pw_msg_initialize(
1063 &dtb_palette_layr_pw_msg);
1064 answer = dtb_show_modal_message(
1065 (Widget)obj_parent->ui_handle,
1066 &dtb_palette_layr_pw_msg,
1070 case DTB_ANSWER_ACTION1: /* Layered Pane */
1071 obj_parent = abobj_handle_layered_pane(obj, obj_parent);
1074 case DTB_ANSWER_ACTION2: /* PanedWindow Pane */
1075 obj_parent = grandparent;
1078 case DTB_ANSWER_CANCEL:
1081 case DTB_ANSWER_HELP:
1087 /* Popup Modal Message and wait for answer */
1088 dtb_palette_layered_pane_msg_initialize(
1089 &dtb_palette_layered_pane_msg);
1090 answer = dtb_show_modal_message(
1091 (Widget)obj_parent->ui_handle,
1092 &dtb_palette_layered_pane_msg,
1096 case DTB_ANSWER_ACTION2: /* Layered Pane */
1097 obj_parent = abobj_handle_layered_pane(obj, obj_parent);
1100 case DTB_ANSWER_CANCEL: /* Cancel */
1105 /* A termpane, textpane, or draw area is being dropped
1106 * on another pane (not control pane) and that pane
1107 * is inside a paned window.
1111 * The object being dragged is a control pane and
1112 * the parent is part of a panedWindow.
1114 else if (!obj_is_control_panel(obj_parent) ||
1115 obj_is_control_panel(obj))
1117 dtb_palette_layr_pw_msg_initialize(
1118 &dtb_palette_layr_pw_msg);
1119 answer = dtb_show_modal_message(
1120 (Widget)obj_parent->ui_handle,
1121 &dtb_palette_layr_pw_msg,
1125 case DTB_ANSWER_ACTION1: /* Layered Pane */
1126 obj_parent = abobj_handle_layered_pane(obj, obj_parent);
1129 case DTB_ANSWER_ACTION2: /* PanedWindow Pane */
1130 obj_parent = grandparent;
1133 case DTB_ANSWER_CANCEL:
1136 case DTB_ANSWER_HELP:
1140 /* The obj is a textpane, termpane, or draw area
1141 * and the parent of obj_parent is a panedWindow.
1145 dtb_palette_chld_layr_pw_msg_initialize(
1146 &dtb_palette_chld_layr_pw_msg);
1147 answer = dtb_show_modal_message(
1148 (Widget)obj_parent->ui_handle,
1149 &dtb_palette_chld_layr_pw_msg,
1153 /* Create as a child of the control pane */
1154 case DTB_ANSWER_ACTION1:
1157 /* Create as a new layer */
1158 case DTB_ANSWER_ACTION2:
1159 obj_parent = abobj_handle_layered_pane(obj, obj_parent);
1162 /* Create as a new pane in the paned window */
1163 case DTB_ANSWER_ACTION3:
1164 obj_parent = obj_get_parent(obj_parent);
1167 case DTB_ANSWER_CANCEL:
1173 * Dropping panes onto a group
1175 else if (obj_parent != NULL && obj_is_group(obj_parent))
1177 if (obj_is_control_panel(obj))
1179 i18n_msg = catgets(Dtb_project_catd, 100, 59,
1180 "Control Panes must be dropped on a Main Window,\nCustom Dialog, or another pane.");
1182 /* If we have an old buffer lying around, free it */
1184 if (errmsg != (STRING) NULL)
1187 errmsg = (STRING) util_malloc(strlen(i18n_msg) + 1);
1188 strcpy(errmsg, i18n_msg);
1193 dtb_palette_child_of_group_msg_initialize(
1194 &dtb_palette_child_of_group_msg);
1195 answer = dtb_show_modal_message(
1196 (Widget)obj_parent->ui_handle,
1197 &dtb_palette_child_of_group_msg,
1201 /* OK - Create as a child of group */
1202 case DTB_ANSWER_ACTION1:
1205 case DTB_ANSWER_CANCEL:
1210 else if (obj_parent == NULL ||
1211 (!(obj_is_container(obj_parent) &&
1212 !obj_is_menubar(obj_parent))))
1214 i18n_msg = catgets(Dtb_project_catd, 100, 13,
1215 "Panes must be dropped on a Main Window,\nCustom Dialog, or another pane.");
1217 /* If we have an old buffer lying around, free it */
1219 if (errmsg != (STRING) NULL)
1222 errmsg = (STRING) util_malloc(strlen(i18n_msg) + 1);
1223 strcpy(errmsg, i18n_msg);
1228 else if (obj_is_control(obj))
1230 if (obj_parent == NULL ||
1231 (!obj_is_control_panel(obj_get_root(obj_parent)) &&
1232 !obj_is_group(obj_get_root(obj_parent))))
1234 i18n_msg = catgets(Dtb_project_catd, 100, 14,
1235 "Controls must be dropped on\na Control Pane or Group.");
1236 /* If we have an old buffer lying around, free it */
1237 if (errmsg != (STRING) NULL)
1240 errmsg = (STRING) util_malloc(strlen(i18n_msg) + 1);
1241 strcpy(errmsg, i18n_msg);
1248 i18n_msg = catgets(Dtb_project_catd, 100, 16,
1249 "Unknown object type.");
1251 /* If we have an old buffer lying around, free it */
1252 if (errmsg != (STRING) NULL)
1255 errmsg = (STRING) util_malloc(strlen(i18n_msg) + 1);
1256 strcpy(errmsg, i18n_msg);
1260 obj_append_child(obj_parent, obj);
1263 *parentptr = obj_parent;
1269 locate_obj_at_rootxy(
1276 ABObj project = proj_get_project();
1277 ABObj obj = project;
1285 window = x_xwin_at_rootxy(AB_toplevel, x, y, p_wx, p_wy);
1289 for (trav_open(&trav, obj, AB_TRAV_UI);
1290 (obj = trav_next(&trav)) != NULL; )
1292 widget = (Widget)obj->ui_handle;
1294 if (widget != NULL &&
1295 XtIsRealized(widget) &&
1296 XtWindow(widget) == window)
1303 * Are we in the draw area of any browser window ?
1305 if (aob_is_browser_win(project, window))
1310 * Get the ABObj that the ptr is currently above
1312 browser_obj = aob_get_object_from_xy(project, window, *p_wx, *p_wy);
1317 * Return the config parent of the ABObj.
1318 * This needs to be done because the ABObj shown on the
1319 * browser and the ABObj of the interface objects as
1320 * seen by the user are different things.
1322 * Also, since we are dealing with browser coordinates
1323 * here (and not precise positions on the parent obj),
1324 * set the position (x,y) to some default.
1326 * drag_cursor_[x,y]hot is added here because it is
1327 * subtracted later to determine the exact position
1330 *p_wx = AB_DEFAULT_X + drag_cursor_xhot;
1331 *p_wy = AB_DEFAULT_Y + drag_cursor_yhot;
1332 return (objxm_comp_get_subobj(browser_obj, AB_CFG_PARENT_OBJ));