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: abobj_layers.c /main/3 1995/11/06 17:16:01 rswiston $
27 * @(#)abobj_layers.c 1.18 02 Feb 1995 cde_app_builder/src/ab
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 * abobj_layers.c - Implements Layered Panes
48 ***********************************************************************
51 #include <X11/Intrinsic.h>
54 #include <ab_private/trav.h>
55 #include <ab_private/obj_notify.h>
56 #include <ab_private/objxm.h>
57 #include <ab_private/abobj.h>
58 #include <ab_private/abobj_set.h>
59 #include <ab_private/abobj_edit.h>
60 #include <ab_private/x_util.h>
63 /*************************************************************************
65 ** Private Function Declarations **
67 **************************************************************************/
69 static void set_pane_attachments(
73 static int obj_destroyedOCB(
77 /*************************************************************************
81 **************************************************************************/
83 static AB_COMPASS_POINT attach_dirs[] = { AB_CP_NORTH, AB_CP_WEST,
84 AB_CP_EAST, AB_CP_SOUTH };
86 /*************************************************************************
88 ** Function Definitions **
90 **************************************************************************/
93 abobj_handle_layered_pane(
98 static BOOL first_time = True;
102 AB_ATTACH_TYPE atype;
110 obj_add_destroy_callback(obj_destroyedOCB, "LAYERS");
114 pane = obj_get_root(pane);
115 pane_parent = obj_get_parent(pane);
117 x_get_widget_rect(objxm_get_widget(pane), &p_rect);
119 if (!obj_is_layers(pane_parent)) /* Create New Layered pane */
122 pobj = objxm_comp_get_subobj(obj_get_root(pane_parent),
125 /* Create Layers Object to hold all layered panes.
126 * Insert the layer obj in the same position as its
129 pos = obj_get_child_num(pane);
130 layers = obj_create(AB_TYPE_LAYERS, NULL);
131 obj_insert_child(pobj, layers, pos);
133 obj_set_unique_name(layers, "layers");
135 obj_set_width(layers, (int)p_rect.width);
136 obj_set_height(layers, (int)p_rect.height);
138 /* If the layer is being parented off of a paned window
139 * then the paned window will take care of positioning
140 * the layer object, so we don't need to set the x,y
141 * values. Same applies to the attachments for the new
144 if (!obj_is_paned_win(pane_parent))
146 obj_set_x(layers, obj_get_x(pane));
147 obj_set_y(layers, obj_get_y(pane));
149 /* Copy original Pane's attachments to the Layers object */
150 for (i=0; i < XtNumber(attach_dirs); i++)
152 atype = obj_get_attach_type(pane, attach_dirs[i]);
153 aval = obj_get_attach_value(pane,attach_dirs[i]);
154 aoffset = obj_get_attach_offset(pane, attach_dirs[i]);
155 obj_set_attachment(layers, attach_dirs[i], atype, aval, aoffset);
160 /* Set the correct position for the layer object,
161 * so that when it is instantiated, it ends up in
162 * the right position in the paned window.
164 objxm_obj_set_ui_arg(layers, AB_ARG_INT,
165 XmNpositionIndex, (short) pos);
168 /* Reset pane's attachment's to be to all sides of the Layers object */
169 set_pane_attachments(pane);
171 obj_reparent(pane, layers);
172 obj_clear_flag(pane, InstantiatedFlag);
173 abobj_show_tree(layers, FALSE);
175 else /* Layers already exist */
176 layers = pane_parent;
178 obj_set_width(newobj, (int)p_rect.width);
179 obj_set_height(newobj, (int)p_rect.height);
180 obj_set_x(newobj, 0);
181 obj_set_y(newobj, 0);
182 set_pane_attachments(newobj);
184 obj_clear_flag(pane, VisibleFlag);
185 XtUnmanageChild(objxm_get_widget(pane));
186 obj_set_flag(newobj, VisibleFlag);
192 abobj_layer_show_next(
198 ABObj old_top = NULL;
199 ABObj new_top = NULL;
201 if (layers == NULL || !obj_is_layers(layers))
204 /* If there is only one pane, do nothing */
205 if (obj_get_num_salient_children(layers) <= 1)
208 for (trav_open(&trav, layers, AB_TRAV_SALIENT_CHILDREN);
209 (pane = trav_next(&trav)) != NULL; )
211 /* Search for currently visible pane and mark it */
212 if (obj_has_flag(pane, VisibleFlag))
214 else if (old_top != NULL) /* previous pane is visible */
222 if (new_top == NULL) /* wraparound to first pane */
223 new_top = obj_get_salient_child(layers, 0);
226 abobj_deselect(old_top);
228 XtManageChild(objxm_get_widget(new_top));
229 obj_set_flag(new_top, VisibleFlag);
233 XtUnmanageChild(objxm_get_widget(old_top));
234 obj_clear_flag(old_top, VisibleFlag);
236 abobj_select(new_top);
242 abobj_layer_set_size(
250 Widget szWidget, xyWidget;
251 XRectangle sz_rect, xy_rect;
255 util_dprintf(3,"abobj_layer_set_size: %s: %d x %d\n",
256 obj_get_name(layers), new_width, new_height);
258 /* If a dimension is -1, then that dimension is not being modified */
260 new_width = obj_get_width(layers);
261 if (new_height == -1)
262 new_height = obj_get_height(layers);
265 abobj_set_pixel_size(layers, new_width, new_height, 0);
267 for (trav_open(&trav, layers, AB_TRAV_SALIENT_CHILDREN);
268 (pane = trav_next(&trav)) != NULL; )
270 if (obj_has_border_frame(pane))
272 szObj = objxm_comp_get_subobj(pane, AB_CFG_SIZE_OBJ);
273 xyObj = objxm_comp_get_subobj(pane, AB_CFG_POSITION_OBJ);
275 szWidget = objxm_get_widget(szObj);
276 xyWidget = objxm_get_widget(xyObj);
278 x_get_widget_rect(szWidget, &sz_rect);
279 x_get_widget_rect(xyWidget, &xy_rect);
280 border_w = ((int)(xy_rect.width - sz_rect.width))/2;
285 if ((obj_is_text(pane) || obj_is_term_pane(pane)) &&
286 obj_get_num_columns(pane) != -1)
287 /* TextPane, TermPane with Character-based Sizing */
288 abobj_set_text_size(pane, new_width, new_height);
290 /* If Pane has "Fit Contents" size-policy, then don't set new size */
291 else if (obj_get_width(pane) != -1 && obj_get_height(pane) != -1)
292 abobj_set_pixel_size(pane, new_width, new_height, border_w);
298 * Manage the visible pane in the layer, and unmanage the rest
301 abobj_layer_manage_visible(
308 if (layer == NULL || !obj_is_layers(layer))
311 /* manage the visible pane, unmanage the rest */
312 for (trav_open(&trav, layer, AB_TRAV_SALIENT_CHILDREN);
313 (pane = trav_next(&trav)) != NULL; )
315 if (obj_has_flag(pane, VisibleFlag))
317 if (!XtIsManaged(objxm_get_widget(pane)))
318 XtManageChild(objxm_get_widget(pane));
322 if (XtIsManaged(objxm_get_widget(pane)))
323 XtUnmanageChild(objxm_get_widget(pane));
333 * Make all 4 sides of pane attached to Layers object
336 set_pane_attachments(
340 obj_set_attachment(pane, AB_CP_NORTH, AB_ATTACH_GRIDLINE, 0, 0);
341 obj_set_attachment(pane, AB_CP_WEST, AB_ATTACH_GRIDLINE, 0, 0);
342 obj_set_attachment(pane, AB_CP_EAST, AB_ATTACH_GRIDLINE, (void*)100, 0);
343 obj_set_attachment(pane, AB_CP_SOUTH, AB_ATTACH_GRIDLINE, (void*)100, 0);
348 * obj-callback: object is being destroyed - remove from Prop dialog lists
352 ObjEvDestroyInfo info
355 static ABObj pane = NULL;
358 AB_ATTACH_TYPE atype;
363 if (obj_get_parent(info->obj) == NULL)
366 layers = obj_get_root(obj_get_parent(info->obj));
368 if (obj_is_layers(layers))
370 /* A Pane inside the Layers has been destroyed...*/
373 /* If it was the one currently visible, then show the next one
375 if (obj_has_flag(pane, VisibleFlag))
376 abobj_layer_show_next(layers);
378 if (obj_get_num_salient_children(layers) == 1)
380 /* Since there is only 1 pane left, we no longer need the layers.
381 * So, reparent the last pane to the layer's parent and destroy
384 last_pane = obj_get_child(layers, 0);
387 * Update undo buffer to depend on this last pane for undo
388 * instead of the parent (layer) which is about to be nuked
390 abobj_setup_undo_cut_layer(layers, last_pane);
392 /* Reparenting the last layer causes the obj_notify function to
393 * flush its queue, which in turn causes this function to be
394 * called again with the same object to destroy. Therefore we
395 * need to track when we are in the reparent phase so that we
396 * don't get into an infinite loop...
398 obj_unparent(last_pane);
399 obj_append_child(obj_get_parent(layers), last_pane);
401 /* Copy layers object's attachments back to the last pane
402 * so that it remains positioned in the same spot.
404 for (i=0; i < XtNumber(attach_dirs); i++)
406 atype = obj_get_attach_type(layers, attach_dirs[i]);
407 aval = obj_get_attach_value(layers,attach_dirs[i]);
408 aoffset = obj_get_attach_offset(layers, attach_dirs[i]);
409 obj_set_attachment(last_pane, attach_dirs[i], atype, aval, aoffset);
412 obj_clear_flag(last_pane, InstantiatedFlag);
413 abobj_show_tree(last_pane, FALSE);