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: brws_utils.c /main/4 1996/10/02 10:59:00 drk $
27 * @(#)brws_utils.c 1.54 29 Mar 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.
48 #include <Xm/DrawingA.h>
49 #include <ab_private/util.h>
50 #include <ab_private/obj.h>
51 #include <ab_private/trav.h>
52 #include <ab_private/brwsP.h>
53 #include <ab_private/proj.h>
54 #include <ab_private/x_util.h>
55 #include <ab_private/istr.h>
57 static ABBrowser get_browser_for_win(
62 static void select_node(
66 static void deselect_node(
70 static void toggle_select_node(
78 static int collapsed_fn(
82 static void r_deselect_all_nodes(
87 static void draw_area_snap (
91 static Boolean clipWindowWorkProc(
95 static void clipwindowEventHandler(
97 XtPointer client_data,
99 Boolean *cont_dispatch
102 static void clipwindowResizeCB(
104 XtPointer client_data,
108 static char *ab_browser_project_name = "*module_name";
115 if (BRWS_NODE_STATE_IS_SET(vnode, BRWS_NODE_SELECTED))
126 if (!BRWS_NODE_STATE_IS_SET(module, BRWS_NODE_EXPANDED))
139 ABBrowser cur_browser;
145 cur_browser = (ABBrowser)project->info.project.browsers;
149 draw_area = brws_draw_area(cur_browser->module);
151 if ( draw_area && (w == XtWindow(draw_area)) )
154 cur_browser = cur_browser->next;
157 return ((ABBrowser)NULL);
166 return(get_browser_for_win(project, w) != NULL);
170 aob_get_object_from_xy(
177 ABBrowser cur_browser;
183 cur_browser = get_browser_for_win(project, w);
184 if (cur_browser != NULL)
186 found_node = vwr_locate_node(cur_browser->module, x, y);
190 return((AB_OBJ *)found_node->obj_data);
198 * Searches for the ViewerNode on the AB_OBJ corresponding to the
220 bnodes = (*m->get_viewer_data)(obj);
222 for (found = bnodes; found && (found->browser != v); found = found->next);
228 * Returns project from browser object
231 aob_project_from_browser(
235 return (b ? (AB_OBJ *)b->obj_data : NULL);
239 * Returns browser properties
242 aob_browser_properties(
246 return (b ? (BrowserProperties *)b->properties : NULL);
250 * Copies the properties of one browser to another
258 BrowserProperties *from_prop,
263 from_prop = aob_browser_properties(from);
264 to_prop = aob_browser_properties(to);
266 * These are the only ones that matter now
268 to_prop->orientation = from_prop->orientation;
269 to_prop->elements_shown = from_prop->elements_shown;
273 * Get the UI handle from a browser
281 return (b ? (BrowserUiObjects *)b->ui_handle : NULL);
285 * Get the shell widget for a browser
293 BrowserUiObjects *ui;
298 ui = aob_ui_from_browser(b);
300 return(ui ? ui->shell : NULL);
304 * Get the draw area widget for a browser
319 return ((Widget)(*m->get_drawarea)(b));
323 * Get the elements of a browser node
333 return ((ViewerNodeElm *)bnode->elements);
337 * Get the bit vector which contains info on
338 * what node elements of the bnodes are to be shown
341 browser_get_elm_shown
346 BrowserProperties *props;
348 props = aob_browser_properties(b);
350 return(props ? props->elements_shown : (unsigned long)NULL);
354 * Return the count of node elements that are
355 * shown for the browser
358 browser_num_elm_shown
364 unsigned long elm_shown;
366 elm_shown = browser_get_elm_shown(b);
368 for (i = 0; i < BRWS_NUM_ELM; ++i)
370 count += (elm_shown & 1);
372 elm_shown = elm_shown >> 1;
380 * Browser node selection
390 AB_OBJ *root_obj = obj;
391 VNode selected_nodes;
399 * Is this necessary ?
401 root_obj = obj_get_root(obj);
406 selected_nodes = (VNode)root_obj->browser_data;
412 * Get project/browser list
413 project = obj_get_project(obj);
414 b_list = (ABBrowser)project->info.project.browsers;
417 while (selected_nodes)
420 aob_browser_properties(selected_nodes->browser);
423 select_node(selected_nodes);
425 selected_nodes = selected_nodes->next;
430 * Browser node de-selection
440 AB_OBJ *root_obj = obj;
441 VNode selected_nodes;
449 * Is this necessary ?
451 root_obj = obj_get_root(obj);
456 selected_nodes = (VNode)root_obj->browser_data;
462 * Get project/browser list
463 project = obj_get_project(obj);
464 b_list = (ABBrowser)project->info.project.browsers;
467 while (selected_nodes)
470 aob_browser_properties(selected_nodes->browser);
473 deselect_node(selected_nodes);
475 selected_nodes = selected_nodes->next;
485 AB_OBJ *root_obj = obj;
486 VNode selected_nodes;
492 root_obj = obj_get_root(obj);
497 selected_nodes = (VNode)root_obj->browser_data;
502 while(selected_nodes)
505 aob_browser_properties(selected_nodes->browser);
508 toggle_select_node(selected_nodes);
510 selected_nodes = selected_nodes->next;
515 aob_deselect_all_objects(
524 browsers = (ABBrowser)project->info.project.browsers;
528 aob_deselect_all_nodes(browsers->module, TRUE);
529 browsers = browsers->next;
546 v = selected_node->browser;
549 BRWS_NODE_SET_STATE(selected_node, BRWS_NODE_SELECTED);
551 obj = (AB_OBJ *)selected_node->obj_data;
553 if (!brwsP_node_is_collapsed(selected_node))
554 (*m->render_node)(selected_node, TRUE);
570 v = selected_node->browser;
573 BRWS_NODE_UNSET_STATE(selected_node, BRWS_NODE_SELECTED);
575 obj = (AB_OBJ *)selected_node->obj_data;
577 if (!brwsP_node_is_collapsed(selected_node))
578 (*m->render_node)(selected_node, FALSE);
583 * Deselect all the nodes in the tree.
584 * The flag argument is to determine whether immediate refreshing
588 aob_deselect_all_nodes
594 r_deselect_all_nodes(b->current_tree, flag);
611 b = selected_node->browser;
613 obj = (AB_OBJ *)selected_node->obj_data;
614 draw_area = brws_draw_area(b);
616 if (BRWS_NODE_STATE_IS_SET(selected_node, BRWS_NODE_SELECTED))
618 BRWS_NODE_UNSET_STATE(selected_node, BRWS_NODE_SELECTED);
619 (*m->render_node)(selected_node, FALSE);
623 BRWS_NODE_SET_STATE(selected_node, BRWS_NODE_SELECTED);
624 (*m->render_node)(selected_node, TRUE);
629 * Recusively deselect all the nodes in the tree.
640 VNode *selected_nodes = NULL;
641 int i, num_child, num_selected = 0;
646 vwr_get_cond(tree, &selected_nodes,
647 &num_selected, select_fn);
649 m = BNODE_METHODS(tree);
651 for (i=0; i < num_selected; ++i)
654 * Make node state unselected
656 BRWS_NODE_UNSET_STATE(selected_nodes[i], BRWS_NODE_SELECTED);
659 * If flag is set, and node is expanded (== not collapsed),
660 * re-render node in unselected state
662 if (flag && !brwsP_node_is_collapsed(selected_nodes[i]))
663 (*m->render_node)(selected_nodes[i], FALSE);
667 util_free(selected_nodes);
676 BrowserUiObjects *ui;
677 DtbBrwsMainwindowInfo instance;
678 AB_OBJ *module_obj = NULL;
682 char *module_name = NULL;
688 shell = aob_ui_shell(b);
691 module_obj = (ABObj)b->tree->obj_data;
695 if (obj_get_file(module_obj) != NULL)
697 char *fullpath, *filename;
699 fullpath = obj_get_file(module_obj);
702 * Check return value of strrchr before adding 1 to it
704 if (filename = strrchr(fullpath, '/'))
705 module_name = (STRING)strdup(filename + 1);
707 module_name = (STRING)strdup(fullpath);
712 module_name = util_strsafe(obj_get_name(module_obj));
718 xmlabel = XmStringCreateLocalized(module_name);
720 sprintf(title, "Module Browser - %s", module_name);
724 xmlabel = XmStringCreateLocalized(" ");
725 sprintf(title, "Module Browser");
728 XtVaSetValues(shell, XtNtitle, title, NULL);
730 ui = aob_ui_from_browser(b);
731 instance = (DtbBrwsMainwindowInfo)ui->ip;
732 project_label = instance->module_name;
734 XtVaSetValues(project_label, XmNlabelString, xmlabel, NULL);
736 XmStringFree(xmlabel);
743 * obj - which object to preview in the browser
744 * browser_window - which browser window to do the priviewing in
747 * that x_conn_fullscreen_init() was called before this function
748 * is called and x_conn_fullscreen_cleanup() will be called after
749 * this function is called.
754 Window browser_window
757 #define AB_BROWSER_PREVIEW_MARGIN 2
762 Window root, child_win;
765 if (!obj || !browser_window)
768 bnode = (VNode)obj->browser_data;
770 draw_area = brws_draw_area(b);
773 * Search for the relevant bnode
774 * - there may be more than one browser visible
776 while(bnode && (browser_window != XtWindow(draw_area)))
782 draw_area = brws_draw_area(b);
789 dpy = XtDisplay(draw_area);
790 root = RootWindow(dpy, DefaultScreen(dpy));
792 XTranslateCoordinates(dpy, browser_window, root,
793 bnode->x, bnode->y, &root_x, &root_y, &child_win);
795 root_x -= AB_BROWSER_PREVIEW_MARGIN;
796 root_y -= AB_BROWSER_PREVIEW_MARGIN;
798 x_fullscreen_preview_box(draw_area, root,
801 root_x + bnode->width +
802 AB_BROWSER_PREVIEW_MARGIN +
803 AB_BROWSER_PREVIEW_MARGIN,
804 root_y + bnode->height +
805 AB_BROWSER_PREVIEW_MARGIN +
806 AB_BROWSER_PREVIEW_MARGIN);
808 #undef AB_BROWSER_PREVIEW_MARGIN
817 VNode update_nodes = NULL;
824 update_nodes = (VNode)obj->browser_data;
828 vwr_init_elements(update_nodes);
830 v = update_nodes->browser;
832 if (obj_is_module(obj))
834 brws_set_module_name(v);
840 update_nodes = update_nodes->next;
845 * brws_get_browser_for_obj()
846 * Returns the browser for the passed obj.
847 * The browser list is searched for the module that contains the passed
848 * object. If none is found, a new browser is created, populated with
849 * the module and it is returned.
851 * If obj is NULL, an empty browser is searched for.
854 brws_get_browser_for_obj(
860 ABBrowser cur_b = NULL,
862 ABObj project = proj_get_project();
866 module = obj_get_module(obj);
867 proj = obj_get_project(obj);
868 b_list = proj ? (ABBrowser)proj->info.project.browsers : NULL;
872 b_list = project ? (ABBrowser)project->info.project.browsers : NULL;
875 for (cur_b = b_list; cur_b; cur_b = cur_b->next)
877 if (cur_b->project->tree &&
878 ((AB_OBJ *)cur_b->project->tree->obj_data == module))
884 cur_b = brws_create();
885 cur_b->next = b_list;
887 b_list->previous = cur_b;
890 project->info.project.browsers = cur_b;
893 brws_add_objects_to_browser(cur_b, module);
900 * brws_get_browser_shell_for_obj()
901 * Returns the browser shell for the passed obj.
902 * The browser list is searched for the module that contains the passed
903 * object. If found, its shell is returned.
906 brws_get_browser_shell_for_obj(
912 ABBrowser cur_b = NULL,
914 ABObj project = proj_get_project();
919 module = obj_get_module(obj);
920 proj = obj_get_project(obj);
921 b_list = proj ? (ABBrowser)proj->info.project.browsers : NULL;
923 for (cur_b = b_list; cur_b; cur_b = cur_b->next)
925 if (cur_b->project->tree &&
926 ((AB_OBJ *)cur_b->project->tree->obj_data == module))
933 return(aob_ui_shell(cur_b->module));
941 if (BRWS_NODE_STATE_IS_SET(vnode, BRWS_NODE_SELECTED))
948 * Synch up the toplevel and detailed view of browser
949 * The browser consists of the toplevel view and the
950 * detailed view. The toplevel view is used to control
951 * what is displayed in the detailed view. Selecting a node
952 * in the toplevel view (a basewindow for example), will
953 * show the node and it's children in the detailed view.
955 * If the 'select_at_least_one' flag is TRUE, and
956 * there are no nodes selected in the toplevel view,
957 * the first node will be selected, making the corresponding
958 * node in the detailed view visible.
959 * If the 'select_at_least_one' is FALSE, no special action
965 short select_at_least_one
970 VNode toplevel_child,
981 * Get toplevel/detailed view
983 toplevel = ab->project;
984 detailed = ab->module;
986 if (!toplevel || !detailed)
989 m = toplevel->methods;
992 * Any nodes currently selected in toplevel view ?
994 vwr_num_cond(toplevel->current_tree, &num_selected, brwsP_select_fn);
997 * Get child count of toplevel view
999 num_child = (*m->get_num_children)(toplevel->current_tree);
1002 * For every node in toplevel view
1004 for (i=0, toplevel_child = (*m->get_child)(toplevel->current_tree, 0);
1006 toplevel_child = (*m->get_child)(toplevel->current_tree, ++i))
1010 if (!toplevel_child)
1014 * Get ABObj of current toplevel child node
1016 cur_obj = (ABObj)toplevel_child->obj_data;
1019 * From the ABObj, get the corresponding node in detailed
1022 detailed_child = aob_find_bnode(cur_obj, detailed);
1024 if (!detailed_child)
1027 if (BRWS_NODE_STATE_IS_SET(toplevel_child, BRWS_NODE_SELECTED))
1030 * Node in toplevel view is selected.
1031 * Make node in detailed view visible.
1033 BRWS_NODE_SET_STATE(detailed_child, BRWS_NODE_VISIBLE);
1038 * Node in toplevel view is not selected.
1040 * If 'select_at_least_one' flag set...
1041 * Check first if there are no nodes selected.
1042 * If there are none, make the first non selected node
1043 * in the toplevel view selected and make the corresponding
1044 * node in the detailed view visible.
1046 if (select_at_least_one && !num_selected)
1048 BRWS_NODE_SET_STATE(toplevel_child, BRWS_NODE_SELECTED);
1049 BRWS_NODE_SET_STATE(detailed_child, BRWS_NODE_VISIBLE);
1055 * Make node in detailed view not visible
1057 BRWS_NODE_UNSET_STATE(detailed_child, BRWS_NODE_VISIBLE);
1066 * brwsP_node_is_collapsed()
1067 * Returns TRUE if node is collapsed, FALSE otherwise.
1068 * Note: on error conditions, TRUE is returned.
1071 brwsP_node_is_collapsed
1084 obj = (AB_OBJ *)node->obj_data;
1086 fprintf(stderr, "brwsP_node_is_collapsed(%s), viewer = %p\n",
1091 if (!(v = node->browser))
1094 if (!(m = v->methods))
1097 while (parent = (*m->get_parent)(node))
1099 if (!BRWS_NODE_STATE_IS_SET(parent, BRWS_NODE_EXPANDED))
1102 obj = (AB_OBJ *)parent->obj_data;
1105 fprintf(stderr, "parent node %s is collapsed\n", obj_get_name(obj));
1117 * brwsP_node_is_visible()
1118 * Returns TRUE if node is visible, FALSE otherwise.
1119 * Note: on error conditions, TRUE is returned.
1122 brwsP_node_is_visible
1135 if (!BRWS_NODE_STATE_IS_SET(node, BRWS_NODE_VISIBLE))
1138 obj = (AB_OBJ *)node->obj_data;
1140 fprintf(stderr, "brwsP_node_is_visible(%s), viewer = %p\n",
1145 if (!(v = node->browser))
1148 if (!(m = v->methods))
1151 while (parent = (*m->get_parent)(node))
1153 if (!BRWS_NODE_STATE_IS_SET(parent, BRWS_NODE_VISIBLE))
1156 obj = (AB_OBJ *)parent->obj_data;
1159 fprintf(stderr, "parent node %s is not visible\n", obj_get_name(obj));
1171 * brwsP_make_drawarea_snap()
1172 * Make the passed draw area 'snap' to be the size of it's parent
1173 * whenever it's parent is resized.
1174 * This function tries to take advantage of the fact that the parent
1175 * in most cases is the clipwindow of a scrolled window which is
1176 * also a draw area widget. In this case, a resize callback is
1177 * registered. In other cases, an event handler is registered.
1180 brwsP_make_drawarea_snap(
1187 if (!v || !draw_area)
1190 clipwindow = XtParent(draw_area);
1192 if (XmIsDrawingArea(clipwindow)) {
1193 XtAddCallback(clipwindow, XmNresizeCallback,
1194 clipwindowResizeCB, (XtPointer)v);
1198 XtAddEventHandler(clipwindow,
1199 StructureNotifyMask, False,
1200 clipwindowEventHandler, (XtPointer)v);
1205 * Resize callback for parent of draw area
1210 XtPointer client_data,
1215 * Defer munging until we're out of the ScrolledWindow Resize callback
1217 XtAppAddWorkProc(XtWidgetToApplicationContext(w), clipWindowWorkProc, client_data);
1221 * Event handler for parent of draw area
1224 clipwindowEventHandler(
1226 XtPointer client_data,
1228 Boolean *cont_dispatch
1231 if (event->type != ConfigureNotify)
1235 * Defer munging until we're out of the ScrolledWindow Event Handler
1237 XtAppAddWorkProc(XtWidgetToApplicationContext(widget),
1238 clipWindowWorkProc, client_data);
1243 * Work proc for clip window
1244 * - make draw area snap to clip window's size.
1248 XtPointer client_data
1251 draw_area_snap((Vwr)client_data);
1258 * Make size of draw area snap to size of clipwindow.
1259 * The clipwindow is the direct parent of the draw area.
1260 * The preferred/minimum size of the draw area is stored in
1261 * the viewer properties. This is the size needed to render
1262 * whatever graphics is needed.
1265 * if clipwindow_width > min_width
1266 * make draw area width == clip window width
1268 * if draw area width > minimum width (i.e. preferred width)
1269 * make draw area width == minimum width
1271 * Same logic used for height
1278 Widget clipwindow = NULL,
1280 Dimension cw_width = 0,
1285 BrowserProps props = NULL;
1293 * Get viewer properties
1295 if (!(props = aob_browser_properties(v)))
1299 * Get draw area and clip window
1301 if (!(draw_area = brws_draw_area(v)))
1304 if (!(clipwindow = XtParent(draw_area)))
1308 * Get clipwindow width/height, draw area
1309 * width/height/border width
1311 XtVaGetValues(clipwindow,
1312 XmNwidth, &cw_width,
1313 XmNheight, &cw_height,
1315 XtVaGetValues(draw_area,
1316 XmNborderWidth, &da_borderWidth,
1317 XmNwidth, &da_width,
1318 XmNheight, &da_height,
1321 if ((Dimension)cw_width > props->min_width)
1324 * Clip window width is more than minimum width
1325 * -> expand draw area
1326 * The dimension that we actually use must be offset by the
1327 * border width to ensure a perfect fit in the clip window.
1328 * Otherwise, this will trigger the scrollbar in the clipwindow.
1330 if (cw_width > 2u * da_borderWidth) {
1331 cw_width -= 2u * da_borderWidth;
1335 XtSetArg(arg[num_args], XmNwidth, (cw_width - 2));
1343 * Clip window width is less than minimum width
1344 * -> check if draw area width is more than it's minimum.
1345 * If yes, shrink it back down to the minimum width.
1347 if ((Dimension)da_width > props->min_width)
1349 XtSetArg(arg[num_args], XmNwidth, props->min_width);
1355 if ((Dimension)cw_height > props->min_height)
1358 * Clip window height is more than minimum height
1359 * -> expand draw area
1360 * The dimension that we actually use must be offset by the
1361 * border width to ensure a perfect fit in the clip window.
1362 * Otherwise, this will trigger the scrollbar in the clipwindow.
1364 if (cw_height > 2u * da_borderWidth) {
1365 cw_height -= 2u * da_borderWidth;
1369 XtSetArg(arg[num_args], XmNheight, (cw_height - 2));
1377 * Clip window height is less than minimum height
1378 * -> check if draw area height is more than it's minimum.
1379 * If yes, shrink it back down to the minimum height.
1381 if ((Dimension)da_height > props->min_height)
1383 XtSetArg(arg[num_args], XmNheight, props->min_height);
1389 XtSetValues(draw_area, arg, num_args);
1393 brwsP_collapse_selected(
1398 VNode *selected_nodes = NULL;
1400 int num_selected = 0,
1402 short redraw = FALSE;
1408 if (!(v = ab->module))
1411 if (!(m = v->methods))
1415 * Get nodes that are selected
1417 vwr_get_cond(v->current_tree, &selected_nodes,
1418 &num_selected, select_fn);
1421 * Return if no selected nodes
1423 if (num_selected == 0)
1426 for (i=0; i < num_selected; ++i)
1429 * For each selected node, check if they are expanded.
1430 * If they are, mark them as collapsed.
1432 if (BRWS_NODE_STATE_IS_SET(selected_nodes[i], BRWS_NODE_EXPANDED))
1434 BRWS_NODE_UNSET_STATE(selected_nodes[i], BRWS_NODE_EXPANDED);
1446 * Free up node list if it contained anything
1449 util_free(selected_nodes);
1454 brwsP_expand_selected(
1459 VNode *selected_nodes = NULL;
1461 int num_selected = 0,
1463 short redraw = FALSE;
1468 if (!(v = ab->module))
1471 if (!(m = v->methods))
1475 * Get nodes that are selected
1477 vwr_get_cond(v->current_tree, &selected_nodes,
1478 &num_selected, select_fn);
1481 * Return if no selected nodes
1483 if (num_selected == 0)
1486 for (i=0; i < num_selected; ++i)
1489 * For each selected node, check if they are collapsed.
1490 * If they are, mark them as expanded.
1492 if (!BRWS_NODE_STATE_IS_SET(selected_nodes[i], BRWS_NODE_EXPANDED))
1494 BRWS_NODE_SET_STATE(selected_nodes[i], BRWS_NODE_EXPANDED);
1506 * Free up node list if it contained anything
1509 util_free(selected_nodes);
1514 brwsP_expand_collapsed(
1519 VNode *collapsed_nodes = NULL;
1521 int num_collapsed = 0,
1523 short redraw = FALSE;
1528 if (!(v = ab->module))
1531 if (!(m = v->methods))
1535 * Get nodes that are collapsed
1537 vwr_get_cond(v->current_tree, &collapsed_nodes,
1538 &num_collapsed, collapsed_fn);
1541 * Return if no collapsed nodes
1543 if (num_collapsed == 0)
1546 for (i=0; i < num_collapsed; ++i)
1549 * For each collapsed node, mark them as expanded only if
1552 if (brwsP_node_is_visible(collapsed_nodes[i]))
1554 BRWS_NODE_SET_STATE(collapsed_nodes[i], BRWS_NODE_EXPANDED);
1566 * Free up node list if it contained anything
1568 if (collapsed_nodes)
1569 util_free(collapsed_nodes);
1574 brwsP_tear_off_selected(
1578 ABBrowser new_browser, b_list;
1579 BrowserProps props, new_props;
1580 AB_OBJ *project, *sel_obj;
1584 if (!b || !b->module)
1587 project = (AB_OBJ *)b->module->obj_data;
1592 new_browser = brws_create();
1596 * Link this new browser with the rest
1598 b_list = (ABBrowser)project->info.project.browsers;
1599 new_browser->next = b_list;
1601 b_list->previous = new_browser;
1604 * Make this new browser the first one on the list
1606 project->info.project.browsers = new_browser;
1609 * Add VNodes to the viewers of this browser
1611 m = new_browser->project->methods;
1612 (*m->insert_tree)(new_browser->project, b->project->tree->obj_data);
1614 m = new_browser->module->methods;
1615 (*m->insert_tree)(new_browser->module, b->module->tree->obj_data);
1617 brwsP_sync_views(new_browser, TRUE);
1620 * Code to make the root of the new browser the
1621 * current selected node in the current browser
1622 selected = node_selected(b->current_tree);
1623 sel_obj = (AB_OBJ *)selected->obj_data;
1625 new_browser->current_tree = aob_find_bnode(sel_obj, new_browser);
1628 aob_copy_props(b->project, new_browser->project);
1629 aob_copy_props(b->module, new_browser->module);
1631 recompute_viewer(new_browser->project);
1632 recompute_viewer(new_browser->module);
1634 brws_popup(new_browser);
1643 Vwr top_level_view = NULL;
1644 Vwr detailed_view = NULL;
1650 * Get top level and detailed tree view
1652 top_level_view = ab->project;
1653 detailed_view = ab->module;
1655 if (top_level_view && detailed_view)
1658 DtbBrwsMainwindowInfo instance;
1659 VNode detailed_node;
1660 Widget vert_sb = (Widget)NULL;
1661 Widget horiz_sb = (Widget)NULL;
1662 int x, y, value, size, increment, page,
1663 vert_max, horiz_max,
1664 vert_min, horiz_min;
1665 Dimension scroll_width, scroll_height;
1666 BOOL redraw_needed = FALSE;
1670 * Get node in detailed view to center on
1672 detailed_node = aob_find_bnode(obj, detailed_view);
1678 * If the node in the detailed view is not visible,
1679 * make it visible first before proceeding.
1680 * This is done by selecting the relevant node in the
1681 * top level view and calling brwsP_sync_views().
1683 if (!brwsP_node_is_visible(detailed_node))
1686 VNode top_level_node;
1691 module = obj_get_module(obj);
1694 * Look for direct child of module which is the
1695 * ancestor of the centered object/node
1697 for (trav_open(&trav, module, AB_TRAV_CHILDREN);
1698 (top_level_obj = trav_next(&trav)) != NULL; ) {
1700 if (obj_is_descendant_of(obj, top_level_obj) ||
1701 (obj == top_level_obj))
1710 * Found top level ABObj - direct child of module which is
1711 * the ancestor of 'obj'.
1713 * Get the corresponding node in the top level view
1715 top_level_node = aob_find_bnode(top_level_obj, top_level_view);
1717 if (!top_level_node)
1721 * Select the top level node
1723 BRWS_NODE_SET_STATE(top_level_node, BRWS_NODE_SELECTED);
1725 m = top_level_view->methods;
1731 * Render it selected
1733 (*m->render_node)(top_level_node, TRUE);
1736 * Sync up the top level and detailed tree views
1737 * After this the centered node will be 'visible'
1739 brwsP_sync_views(ab, FALSE);
1742 * Erase and recompute views
1744 erase_viewer(detailed_view);
1745 recompute_viewer(detailed_view);
1746 redraw_needed = TRUE;
1749 ui = aob_ui_from_browser(detailed_view);
1750 instance = (DtbBrwsMainwindowInfo)ui->ip;
1752 if (!instance->detailed_drawarea)
1756 * Get vertical/horizontal scrollbars of scrolled window
1758 XtVaGetValues(instance->detailed_drawarea_scrolledwin,
1759 XmNverticalScrollBar, &vert_sb,
1760 XmNhorizontalScrollBar, &horiz_sb,
1761 XmNwidth, &scroll_width,
1762 XmNheight, &scroll_height,
1766 * If the scrolled area is smaller than the node, use the
1767 * node's size as the scroll area - to prevent getting
1768 * negative numbers in our calculations later on.
1769 * BUG - am I casting properly here?
1771 if (scroll_width < (Dimension)detailed_node->width)
1772 scroll_width = (Dimension)detailed_node->width;
1773 if (scroll_height < (Dimension)detailed_node->height)
1774 scroll_height = (Dimension)detailed_node->height;
1777 **********************************************************
1778 * Center browser node to the middle of the scrolled window
1779 **********************************************************
1783 * Adjust vertical scrollbar
1790 * Get current scrollbar values
1792 XtVaGetValues(vert_sb,
1793 XmNminimum, &vert_min,
1794 XmNmaximum, &vert_max,
1796 XmScrollBarGetValues(vert_sb, &value, &size, &increment, &page);
1799 * Don't adjust if for some reason if the node is off the browser
1801 if (detailed_node->y < vert_max)
1804 * This adjusts the y position of the scrollbar so that
1805 * the node is centered
1807 y = detailed_node->y - ((int)scroll_height - detailed_node->height)/2;
1810 * Check for illegal y value:
1811 * Must make sure the y position does not exceed
1812 * (XmNmaximum - XmNsliderSize)
1814 if (vert_max - y < size)
1815 y = vert_max - size;
1821 * Set the scrollbar with new 'centered' y position
1823 XmScrollBarSetValues(vert_sb, (int)y, size, increment, page, True);
1828 * Adjust horizontal scrollbar
1834 * Get current scrollbar values
1836 XtVaGetValues(horiz_sb,
1837 XmNminimum, &horiz_min,
1838 XmNmaximum, &horiz_max,
1840 XmScrollBarGetValues(horiz_sb, &value, &size, &increment, &page);
1843 * Don't adjust if for some reason if the node is off the browser
1845 if (detailed_node->x < horiz_max)
1848 * This adjusts the y position of the scrollbar so that
1849 * the node is centered
1851 x = detailed_node->x - ((int)scroll_width - detailed_node->width)/2;
1854 * Check for illegal y value:
1855 * Must make sure the y position does not exceed
1856 * (XmNmaximum - XmNsliderSize)
1858 if (horiz_max - x < size)
1859 x = horiz_max - size;
1865 * Set the scrollbar with new 'centered' y position
1867 XmScrollBarSetValues(horiz_sb, (int)x, size, increment, page, True);
1875 draw_viewer(detailed_view);