/* * Test whether a Button should be a candidate to be the dialog's * "Default" button or not */ static BOOL button_test_func( ABObj obj ) { ABObj parent = obj_get_root(obj_get_parent(obj)); if (obj_is_button(obj)) { while (obj_is_group(parent)) parent = obj_get_root(obj_get_parent(parent)); if (obj_get_container_type(parent) == AB_CONT_BUTTON_PANEL) return True; } return False; }
void abobj_nudge_selected( ABObj *sel_list, int sel_count, short x_delta, short y_delta, BOOL reselect ) { ABObj moveobj; ABObj xyobj; XRectangle new_rect; int i; for (i=0; i < sel_count; i++) { if (obj_is_layers(obj_get_parent(sel_list[i]))) moveobj = obj_get_parent(sel_list[i]); else moveobj = sel_list[i]; xyobj = objxm_comp_get_subobj(moveobj, AB_CFG_POSITION_OBJ); x_get_widget_rect(objxm_get_widget(xyobj), &new_rect); new_rect.x += x_delta; new_rect.y += y_delta; /* Move object */ abobj_set_xy(moveobj, new_rect.x, new_rect.y); /* if (xyobj->attachments) abobj_calculate_new_layout(xyobj, new_rect.x, new_rect.y, new_rect.width, new_rect.height); */ abobj_tree_instantiate_changes(moveobj); /* * UGLY WORKAROUND for Motif bug which prevents a 1 pixel move * to the Left from working if only 1 object is being moved... */ if (sel_count == 1 && x_delta == -1) abobj_force_dang_form_resize(moveobj); if (reselect) abobj_select(sel_list[i]); } }
/* * Effects: Actually performs the destroy of one object. * * DOESN'T SEND ANY EVENTS OR GET PERMISSION, OR NUTHIN! * */ int objP_actually_destroy_one_impl(ABObj *objPtr) { #define obj (*objPtr) int iReturn= 0; int iRC= 0; /* return code */ ABObj parent= NULL; /* * don't send events! */ objP_notify_push_mode(); objP_notify_clear_mode(OBJEV_MODE_SEND_ALLOW_EVS); objP_notify_clear_mode(OBJEV_MODE_SEND_NOTIFY_EVS); if ((parent= obj_get_parent(obj)) != NULL) { if ((iRC = obj_move_children(parent, obj)) < 0) { iReturn= iRC; goto epilogue; } } /* * Remove any references to this object */ objP_remove_all_refs_to(obj); /* * actually deallocate the space! * * We set the flags to AlreadyFreedValue in case an attempt is made to * accessed the freed data - we can check. */ obj->impl_flags= ObjFlagAlreadyFreedValue; objP_free_mem(obj); /* actually destroy it! */ obj = NULL; /* objP_free_mem() does this, but I'm going to set */ /* it to NULL, again. */ objP_notify_pop_mode(); epilogue: obj = NULL; /* forget we ever saw it... */ return iReturn; #undef obj }
BOOL abobj_is_movable( ABObj obj ) { BOOL movable = True; ABObj pobj; AB_CONTAINER_TYPE cont_type; /* If object is a child of a Group and the group has a * defined layout type, then it is not movable */ pobj = obj_get_root(obj_get_parent(obj)); if (obj_is_group(pobj) && obj_get_group_type(pobj) != AB_GROUP_IGNORE) movable = False; switch(obj_get_type(obj)) { case AB_TYPE_TEXT_PANE: case AB_TYPE_TERM_PANE: case AB_TYPE_DRAWING_AREA: case AB_TYPE_CONTAINER: { /* If object is child of PanedWindow, it cannot be moved */ if (obj_is_paned_win(pobj)) movable = False; else if (obj_is_container(obj)) { cont_type = obj_get_container_type(obj); if (cont_type == AB_CONT_MENU_BAR || cont_type == AB_CONT_TOOL_BAR || cont_type == AB_CONT_FOOTER || cont_type == AB_CONT_BUTTON_PANEL) movable = False; } break; } default: break; } return movable; }
/* ** Set the label string on an object ** (converts it to XmString internally, if needed) */ void ui_obj_set_label_string( ABObj obj, STRING label ) { ABObj labelObj = NULL; if (obj == NULL) return; switch (obj_get_type(obj)) { case AB_TYPE_BUTTON: case AB_TYPE_CHOICE: case AB_TYPE_COMBO_BOX: case AB_TYPE_LABEL: case AB_TYPE_LIST: case AB_TYPE_SPIN_BOX: case AB_TYPE_SCALE: case AB_TYPE_TEXT_FIELD: labelObj = objxm_comp_get_subobj(obj, AB_CFG_LABEL_OBJ); if (labelObj == NULL || objxm_get_widget(labelObj) == NULL) return; ui_set_label_string(objxm_get_widget(labelObj), label); break; case AB_TYPE_ITEM: switch(obj_get_item_type(obj)) { case AB_ITEM_FOR_MENU: case AB_ITEM_FOR_MENUBAR: case AB_ITEM_FOR_CHOICE: labelObj = objxm_comp_get_subobj(obj, AB_CFG_LABEL_OBJ); if (labelObj == NULL || objxm_get_widget(labelObj) == NULL) return; ui_set_label_string(objxm_get_widget(labelObj), label); break; case AB_ITEM_FOR_COMBO_BOX: case AB_ITEM_FOR_LIST: case AB_ITEM_FOR_SPIN_BOX: { ABObj p_obj = obj_get_parent(obj); Widget parent = objxm_get_widget(p_obj); AB_ITEM_TYPE itype = (AB_ITEM_TYPE)obj_get_subtype(obj); int pos; int num_items; XmString xmitem; if (parent != NULL) { xmitem = XmStringCreateLocalized(label); pos = obj_get_child_num(obj); pos++; /* XmList starts at 1 */ if (obj_is_combo_box_item(obj)) parent = ui_combobox_get_list_widget(parent); if (obj_is_list_item(obj) || obj_is_combo_box_item(obj)) XtVaGetValues(parent, XmNitemCount, &num_items, NULL); else if (obj_is_spin_box_item(obj)) XtVaGetValues(parent, DtNnumValues, &num_items, NULL); if (pos <= num_items) { if (obj_is_list_item(obj) || obj_is_combo_box_item(obj)) { XmListReplacePositions(parent, &pos, &xmitem, 1); } else { DtSpinBoxDeletePos(parent, pos); DtSpinBoxAddItem(parent, xmitem, pos); } } XmStringFree(xmitem); } } break; default: break; } break; case AB_TYPE_BASE_WINDOW: case AB_TYPE_DIALOG: case AB_TYPE_FILE_CHOOSER: labelObj = objxm_comp_get_subobj(obj, AB_CFG_LABEL_OBJ); if (labelObj == NULL || objxm_get_widget(labelObj) == NULL) return; XtVaSetValues(objxm_get_widget(labelObj), XmNtitle, label, NULL); break; default: break; } }
/* * Finds the target matching the given description, creating it if necessary. * * Assumes: strings are pointers to allocated space. Sets strings to NULL, if * the values are used. * * Assumes that obj may not be in the object tree yet, and may return it as the * target. */ static ABObj find_or_create_target( ABObj obj, ABObj module, ISTRING interface_name, ISTRING parent_name, ISTRING obj_name, ISTRING item_label ) { ABObj target = NULL; /* the real thing, baby! */ ABObj target_project = NULL; char target_interface_file[MAXPATHLEN+1]; char target_interface_name[GIL_MAX_NAME_SIZE]; ABObj target_module = NULL; char target_parent_name[GIL_MAX_NAME_SIZE]; ABObj target_parent = NULL; char target_obj_name[GIL_MAX_NAME_SIZE]; ABObj target_obj = NULL; char target_item_label[GIL_MAX_NAME_SIZE]; ABObj target_item = NULL; AB_TRAVERSAL trav; *target_interface_file = 0; *target_interface_name = 0; *target_parent_name = 0; *target_obj_name = 0; *target_item_label = 0; /* must have object name */ if (debugging()) { assert( (obj_name != NULL) && (obj_is_project(module) || obj_is_module(module))); } if (obj_is_project(module)) { /* The first string must be an interface file name */ if (interface_name != NULL) { util_strncpy(target_interface_file, istr_string(interface_name), GIL_MAX_NAME_SIZE); if (parent_name != NULL) { util_strncpy(target_parent_name, istr_string(parent_name), GIL_MAX_NAME_SIZE); } } else if (parent_name != NULL) { util_strncpy(target_interface_file, istr_string(parent_name), GIL_MAX_NAME_SIZE); } else { abil_print_load_err(ERR_WANT_FULL_NAME); goto epilogue; } /* derive the name from the file name */ strcpy(target_interface_name, target_interface_file); { int len = strlen(target_interface_name); if ( (len >= 2) && ( util_streq(&(target_interface_name[len-2]), ".G") || util_streq(&(target_interface_name[len-2]), ".P"))) { target_interface_name[len-2] = 0; } } util_strncpy(target_obj_name, istr_string(obj_name), GIL_MAX_NAME_SIZE); if (item_label != NULL) { util_strncpy(target_item_label, istr_string(item_label), GIL_MAX_NAME_SIZE); } } else /* ! obj_is_project() */ { if (parent_name != NULL) { /* we have parent name and object name */ util_strncpy(target_parent_name, istr_string(parent_name), GIL_MAX_NAME_SIZE); } util_strncpy(target_obj_name, istr_string(obj_name), GIL_MAX_NAME_SIZE); if (item_label != NULL) { /* we have object name and item_label */ util_strncpy(target_item_label, istr_string(item_label), GIL_MAX_NAME_SIZE); } } /* * We've got the name broken down into the appropriate pieces. * Now find the actual target. */ /*util_dprintf(3, "finding: module:'%s' parent:'%s' obj:'%s' item:'%s'\n", target_interface_name, target_parent_name, target_obj_name, target_item_label);*/ /* * Find target project */ target_project = obj_get_project(module); /* * Find target module */ if (util_strempty(target_interface_name)) { target_module = module; } else { /* find specified intefarce (module) */ for (trav_open(&trav, target_project, AB_TRAV_MODULES); (target_module = trav_next(&trav)) != NULL; ) { if ( (target_module != target_project) && (util_streq( obj_get_file(target_module), target_interface_file))) { break; } } trav_close(&trav); if (target_module == NULL) { target_module = obj_create(AB_TYPE_MODULE, target_project); obj_set_is_defined(target_module, FALSE); obj_set_file(target_module, target_interface_file); obj_set_name(target_module, target_interface_name); } } /* * Find target parent */ if (util_strempty(target_parent_name)) { target_parent = target_module; } else { for (trav_open(&trav, target_module, AB_TRAV_ALL | AB_TRAV_MOD_PARENTS_FIRST); (target_parent = trav_next(&trav)) != NULL; ) { if ( (target_parent != target_module) && (util_streq( obj_get_name(target_parent), target_parent_name))) { break; } } trav_close(&trav); if (target_parent == NULL) { target_parent = obj_create(AB_TYPE_UNDEF, target_module); obj_set_is_defined(target_parent, FALSE); obj_set_file(target_parent, target_interface_file); obj_set_name(target_parent, target_parent_name); } } /* * Find target obj */ for (trav_open(&trav, target_parent, AB_TRAV_ALL | AB_TRAV_MOD_PARENTS_FIRST); (target_obj = trav_next(&trav)) != NULL; ) { if ( (target_obj != target_parent) && util_streq(target_obj_name, obj_get_name(target_obj))) { break; } } trav_close(&trav); if (target_obj == NULL) { target_obj = obj_create(AB_TYPE_UNDEF, target_parent); obj_set_is_defined(target_obj, FALSE); obj_set_file(target_obj, target_interface_file); obj_set_name(target_obj, target_obj_name); } /* * Find item */ if (util_strempty(target_item_label)) { target_item = NULL; } else { for (trav_open(&trav, target_obj, AB_TRAV_ITEMS); (target_item = trav_next(&trav)) != NULL; ) { if ( (target_item != target_obj) && util_streq(obj_get_label(target_item), target_item_label)) { break; } } trav_close(&trav); if (target_item == NULL) { target_item = obj_create(AB_TYPE_ITEM, target_obj); obj_set_is_defined(target_item, FALSE); obj_set_file(target_item, target_interface_file); obj_set_label(target_item, target_item_label); obj_set_name_from_label(target_item, obj_get_name(obj_get_parent(target_item))); } } if (target_item != NULL) { target = target_item; } else { target = target_obj; } epilogue: return target; }
/* * Resize object according to info in last resize rubberbanding */ int abobj_resize( ABObj obj, XEvent *event ) { Widget parent; Display *dpy; XRectangle p_rect; XRectangle adj_rect; Window rootwin; int orig_x, orig_y; int trans_x, trans_y; ABObj moveobj; ABObj pobj; if (!first_move) /* resize occurred */ { Window win; if (obj_is_item(obj)) obj = obj_get_parent(obj); obj = obj_get_root(obj); parent = XtParent(xy_widget); dpy = XtDisplay(xy_widget); orig_x = (int)resize_rect.x; orig_y = (int)resize_rect.y; first_move = TRUE; x_get_widget_rect(parent, &p_rect); rootwin = RootWindowOfScreen(XtScreen(xy_widget)); /* erase last rect outline */ x_fullscreen_box(xy_widget, rootwin, resize_rect.x, resize_rect.y, rect_right(&resize_rect), rect_bottom(&resize_rect)); /* translate from root coordinates to parent's */ XTranslateCoordinates(dpy, rootwin, XtWindow(parent), orig_x , orig_y, &trans_x, &trans_y, &win); resize_rect.width++; resize_rect.height++; /* Ensure new geometry fits within parent */ if (trans_x < 0) { resize_rect.x = 0; resize_rect.width += trans_x; if (obj_is_pane(obj) || obj_is_separator(obj)) /* If a pane, attach to parent's edge */ obj_set_attachment(xy_obj, AB_CP_WEST, AB_ATTACH_OBJ, obj_get_parent(xy_obj), 0); } else { resize_rect.x = trans_x; /* Break edge-attachment */ if ((obj_is_pane(obj) || obj_is_separator(obj)) && (obj_get_attach_type(xy_obj, AB_CP_WEST) == AB_ATTACH_OBJ && obj_get_attach_value(xy_obj, AB_CP_WEST) == (void*)obj_get_parent(xy_obj))) obj_set_attachment(xy_obj, AB_CP_WEST, AB_ATTACH_POINT, (void*)0, trans_x); } if (trans_y < 0) { resize_rect.y = 0; resize_rect.height += trans_y; if (obj_is_pane(obj) || obj_is_separator(obj)) /* If a pane, attach to parent's edge */ obj_set_attachment(xy_obj, AB_CP_NORTH, AB_ATTACH_OBJ, obj_get_parent(xy_obj), 0); } else { resize_rect.y = trans_y; /* Break edge-attachment */ if ((obj_is_pane(obj) || obj_is_separator(obj)) && (obj_get_attach_type(xy_obj, AB_CP_NORTH) == AB_ATTACH_OBJ && obj_get_attach_value(xy_obj, AB_CP_NORTH) == (void*)obj_get_parent(xy_obj))) obj_set_attachment(xy_obj, AB_CP_NORTH, AB_ATTACH_POINT, (void*)0, trans_y); } if (resize_rect.x + (short)resize_rect.width >= (short)p_rect.width) { resize_rect.width = (short)p_rect.width - resize_rect.x - 1; if (obj_is_pane(obj) || obj_is_separator(obj)) /* If a pane, attach to parent's edge */ obj_set_attachment(xy_obj, AB_CP_EAST, AB_ATTACH_OBJ, obj_get_parent(xy_obj), 0); } else { /* Break edge-attachment */ if ((obj_is_pane(obj) || obj_is_separator(obj)) && (obj_get_attach_type(xy_obj, AB_CP_EAST) == AB_ATTACH_OBJ && obj_get_attach_value(xy_obj, AB_CP_EAST) == (void*)obj_get_parent(xy_obj))) obj_set_attachment(xy_obj, AB_CP_EAST, AB_ATTACH_NONE, (void*)0, 0); } if (resize_rect.y + (short)resize_rect.height > (short)p_rect.height) { resize_rect.height = (short)p_rect.height - resize_rect.y - 1; if (obj_is_pane(obj) || obj_is_separator(obj)) /* If a pane, attach to parent's edge */ obj_set_attachment(xy_obj, AB_CP_SOUTH, AB_ATTACH_OBJ, obj_get_parent(xy_obj), 0); } else { /* Break edge-attachment */ if ((obj_is_pane(obj) || obj_is_separator(obj)) && (obj_get_attach_type(xy_obj, AB_CP_SOUTH) == AB_ATTACH_OBJ && obj_get_attach_value(xy_obj, AB_CP_SOUTH) == (void*)obj_get_parent(xy_obj))) obj_set_attachment(xy_obj, AB_CP_SOUTH, AB_ATTACH_NONE, (void*)0, 0); } (void)abobj_set_undo(&obj, 1, undo_resize, AB_UNDO_RESIZE); pobj = obj_get_parent(obj); if (obj_is_layers(pobj)) moveobj = pobj; else moveobj = obj; adj_rect = resize_rect; if (abobj_has_attached_label(obj)) subtract_attached_label(obj, &adj_rect); if (obj_is_drawing_area(obj) && obj_has_scrollbar(obj)) { int new_d_w = -1; int new_d_h = -1; int d_w = obj_get_drawarea_width(obj); int d_h = obj_get_drawarea_height(obj); /* If the overall DrawArea dimension is now larger than the internal * canvas dimension, resize the canvas dimension to be at least as large * as the overall DrawArea. */ if ((int)resize_rect.width != obj_get_width(obj) && (int)resize_rect.width > d_w) new_d_w = (int)resize_rect.width; if ((int)resize_rect.height != obj_get_height(obj) && (int)resize_rect.height > d_h) new_d_h = (int)resize_rect.height; if (new_d_w != -1 || new_d_h != -1) abobj_set_drawarea_size(obj, new_d_w != -1? new_d_w : d_w, new_d_h != -1? new_d_h : d_h); } /* * Resize the object ! */ if (obj_is_layers(pobj)) abobj_layer_set_size(pobj, resize_rect.width, resize_rect.height); else if ((obj_is_text(obj) || obj_is_term_pane(obj)) && obj_get_num_columns(obj) != -1) /* TextPane, TermPane, TextField with Character-based Sizing */ abobj_set_text_size(obj, (int)adj_rect.width, (int)adj_rect.height); else if (obj_is_list(obj) && obj_get_num_rows(obj) != -1) { /* List with Character-based height */ abobj_set_text_size(obj, (int)adj_rect.width, (int)adj_rect.height); abobj_set_pixel_width(obj, (int)adj_rect.width, border_w); } else /* else size is Pixel-based...*/ resize_in_pixels(obj, (int)adj_rect.width, (int)adj_rect.height, border_w); abobj_set_xy(moveobj, resize_rect.x, resize_rect.y); if (xy_obj->attachments) abobj_calculate_new_layout(xy_obj, resize_rect.x, resize_rect.y, resize_rect.width, resize_rect.height); /* Change obj size BEFORE changing attachments...*/ abobj_instantiate_changes(obj); abobj_tree_instantiate_changes(moveobj); /* WORKAROUND for Motif XmForm bug (it ignores child resize request * if x,y have not also changed). So, we have to force it. */ abobj_force_dang_form_resize(xy_obj); if (util_get_verbosity() > 3) objxm_dump_widget_geometry(xy_widget); return OK; } return ERROR; }
/* * Draw rubberbanding outline for resizing action */ int abobjP_resize_object_outline( ABObj obj, XEvent *event, RESIZE_DIR dir ) { ABObj s_obj; static Widget parent; static Window rootwin; static Display *dpy; static XRectangle orig_r, r; static int last_x, last_y; int x,y; char buf[80]; if (event->type == MotionNotify) { x = ((XMotionEvent*)event)->x_root; y = ((XMotionEvent*)event)->y_root; } else if (event->type == ButtonPress) { x = ((XButtonEvent*)event)->x_root; y = ((XButtonEvent*)event)->y_root; } else return -1; if (first_move) { Window win; int orig_x, orig_y; int trans_x, trans_y; if (obj_is_item(obj)) obj = obj_get_parent(obj); obj = obj_get_root(obj); xy_obj = objxm_comp_get_subobj(obj, AB_CFG_POSITION_OBJ); xy_widget = (Widget)xy_obj->ui_handle; if (xy_widget == NULL) { if (util_get_verbosity() > 0) fprintf(stderr,"abobjP_resize_object_outline: %s :no SIZE widget\n", util_strsafe(obj_get_name(obj))); return ERROR; } parent = XtParent(xy_widget); dpy = XtDisplay(xy_widget); rootwin = RootWindowOfScreen(XtScreen(xy_widget)); x_get_widget_rect(xy_widget, &orig_r); if (obj_has_border_frame(obj)) /* We have a border-frame to deal with */ { XRectangle pane_r; s_obj = objxm_comp_get_subobj(obj, AB_CFG_SIZE_OBJ); /* Determine width of border */ x_get_widget_rect(objxm_get_widget(s_obj), &pane_r); border_w = ((int)(orig_r.width - pane_r.width))/2; } else border_w = 0; orig_r.width--; orig_r.height--; r = orig_r; orig_x = (int)orig_r.x; orig_y = (int)orig_r.y; XTranslateCoordinates(dpy, XtWindow(parent), rootwin, orig_x , orig_y, &trans_x, &trans_y, &win); r.x = (short)trans_x; r.y = (short)trans_y; first_move = FALSE; } else /* erase previous outline */ { make_rect(&resize_rect, &r, last_x, last_y, dir); x_fullscreen_box(xy_widget, rootwin, resize_rect.x, resize_rect.y, rect_right(&resize_rect), rect_bottom(&resize_rect)); } make_rect(&resize_rect, &r, x, y, dir); x_fullscreen_box(xy_widget, rootwin, resize_rect.x, resize_rect.y, rect_right(&resize_rect), rect_bottom(&resize_rect)); sprintf(buf, "%3.3dx%3.3d", resize_rect.width, resize_rect.height); /* REMIND: aim, update status region on ab palette win */ last_x = x; last_y = y; return OK; }
/* * Return resize-direction corresponding to cursor x,y position */ RESIZE_DIR abobjP_find_resize_direction ( ABObj obj, Widget widget, XEvent *event ) { ABObj rootObj; XRectangle w_rect; XRectangle temp; int half_handle; int half_width; int half_height; int x, y; int orig_x, orig_y; int grabbox_size; if (event->type == MotionNotify) { orig_x = x = ((XMotionEvent*)event)->x; orig_y = y = ((XMotionEvent*)event)->y; } else if (event->type == ButtonPress) { orig_x = x = ((XButtonEvent*)event)->x; orig_y = y = ((XButtonEvent*)event)->y; } else return NONE; if (obj_is_item(obj)) obj = obj_get_parent(obj); rootObj = obj_get_root(obj); rect_zero_out(&w_rect); if ((obj_is_drawing_area(obj) || obj_is_text_pane(obj)) && (obj_has_hscrollbar(obj) || obj_has_vscrollbar(obj)) ) { ABObj swobj = objxm_comp_get_subobj(obj, AB_CFG_SIZE_OBJ); Widget cwidget; XtVaGetValues((Widget)swobj->ui_handle, XmNclipWindow, &cwidget, NULL); if (cwidget) x_get_widget_rect(cwidget, &w_rect); } else if (rootObj != obj) { Window win; XTranslateCoordinates(XtDisplay(widget), XtWindow(widget), XtWindow(objxm_get_widget(rootObj)), orig_x , orig_y, &x, &y, &win); widget = objxm_get_widget(rootObj); } if (w_rect.width == 0 || w_rect.height == 0) x_get_widget_rect(widget, &w_rect); /* if (obj_is_control(obj)) grabbox_size = (AB_selected_rect_size / 2) + 1; else */ grabbox_size = AB_selected_rect_size; /* Readjust coordinates to remove offset within the parent window. */ w_rect.x = 0; w_rect.y = 0; /* Exit if we are not near the border. */ temp = w_rect; x_adjust_rect_margin(&temp, 0 - grabbox_size); if (obj_is_control_panel(rootObj) && rect_includespoint (&temp, x, y)) return (NONE); if (!abobj_is_directly_resizable(rootObj)) return (MOVE); half_handle = grabbox_size/ 2 + 1; half_width = w_rect.width / 2; half_height = w_rect.height / 2; temp.width = temp.height = grabbox_size + 2; /******************************** * SOUTH_EAST * Most common ? *********************************/ temp.x = w_rect.width - grabbox_size; temp.y = w_rect.height - grabbox_size; if (rect_includespoint (&temp, x, y)) return (SOUTH_EAST); /******************************** * SOUTH_WEST *********************************/ temp.x = 0; temp.y = w_rect.height - grabbox_size; if (rect_includespoint (&temp, x, y)) return (SOUTH_WEST); /******************************** * NORTH *********************************/ temp.x = half_width - half_handle; temp.y = 0; if (rect_includespoint (&temp, x, y)) return (NORTH); /******************************** * SOUTH *********************************/ temp.x = half_width - half_handle; temp.y = w_rect.height - grabbox_size; if (rect_includespoint (&temp, x, y)) return (SOUTH); /******************************** * EAST *********************************/ temp.x = w_rect.width - grabbox_size; temp.y = half_height - half_handle; if (rect_includespoint (&temp, x, y)) return (EAST); /******************************** * WEST *********************************/ temp.x = 0; temp.y = half_height - half_handle; if (rect_includespoint (&temp, x, y)) return (WEST); /******************************** * NORTH_EAST *********************************/ temp.x = w_rect.width - grabbox_size; temp.y = 0; if (rect_includespoint (&temp, x, y)) return (NORTH_EAST); /******************************** * NORTH_WEST *********************************/ temp.x = 0; temp.y = 0; if (rect_includespoint (&temp, x, y)) return (NORTH_WEST); /******************************** * Must be a move. *********************************/ return (MOVE); }
/* * Given a new x,y,width,height, calculate appropriate layout info */ int abobj_calculate_new_layout( ABObj obj, int new_x, int new_y, Dimension new_width, Dimension new_height ) { ABObj parent; ABAttachListPtr attachments; Position x, y; Dimension width, height; Dimension p_width, p_height; long gridpos; if ((attachments = obj->attachments) == NULL) return -1; if (obj->ui_handle == NULL) { if (util_get_verbosity() > 0) fprintf(stderr,"abobj_calculate_new_layout: %s: NULL widget\n", obj_get_name(obj)); return -1; } XtVaGetValues((Widget)obj->ui_handle, XmNx, &x, XmNy, &y, XmNwidth, &width, XmNheight, &height, NULL); parent = obj_get_parent(obj); XtVaGetValues((Widget)parent->ui_handle, XmNwidth, &p_width, XmNheight, &p_height, NULL); switch(attachments->west.type) { case AB_ATTACH_POINT: attachments->west.offset = new_x; break; case AB_ATTACH_GRIDLINE: gridpos = (100 * new_x)/(int)p_width; attachments->west.value = (void*)gridpos; break; case AB_ATTACH_CENTER_GRIDLINE: gridpos = (100 * (new_x + (int)new_width/2))/(int)p_width; attachments->west.value = (void*)gridpos; break; case AB_ATTACH_OBJ: case AB_ATTACH_ALIGN_OBJ_EDGE: attachments->west.offset += (new_x - x); if (new_x == 0 && attachments->west.offset < 0) attachments->west.offset = 0; break; } switch(attachments->east.type) { case AB_ATTACH_POINT: attachments->east.offset = p_width - (new_x + new_width); break; case AB_ATTACH_GRIDLINE: gridpos = (100 * (new_x + (int)new_width))/(int)p_width; attachments->east.value = (void*)gridpos; break; case AB_ATTACH_CENTER_GRIDLINE: gridpos = (100 * (new_x + (int)new_width/2))/(int)p_width; attachments->east.value = (void*)gridpos; break; case AB_ATTACH_OBJ: attachments->east.offset = p_width - (new_x + new_width + 1); break; case AB_ATTACH_ALIGN_OBJ_EDGE: attachments->east.offset += (x + width - new_x - new_width); break; } switch(attachments->north.type) { case AB_ATTACH_POINT: attachments->north.offset = new_y; break; case AB_ATTACH_GRIDLINE: gridpos = (100 * new_y)/(int)p_height; attachments->north.value = (void*)gridpos; break; case AB_ATTACH_CENTER_GRIDLINE: gridpos = (100 * (new_y + (int)new_height/2))/(int)p_height; attachments->north.value = (void*)gridpos; break; case AB_ATTACH_OBJ: case AB_ATTACH_ALIGN_OBJ_EDGE: attachments->north.offset += (new_y - y); if (new_y == 0 && attachments->north.offset < 0) attachments->north.offset = 0; break; } switch(attachments->south.type) { case AB_ATTACH_POINT: attachments->south.offset = p_height - (new_y + new_height); break; case AB_ATTACH_GRIDLINE: gridpos = (100 * (new_y + (int)new_height))/(int)p_height; attachments->south.value = (void*)gridpos; break; case AB_ATTACH_CENTER_GRIDLINE: gridpos = (100 * (new_y + (int)new_height/2))/(int)p_height; attachments->south.value = (void*)gridpos; break; case AB_ATTACH_OBJ: attachments->south.offset = p_height - (new_y + new_height + 1); break; case AB_ATTACH_ALIGN_OBJ_EDGE: attachments->south.offset += (y + height - new_y - new_height); break; } objxm_obj_set_attachment_args(obj, OBJXM_CONFIG_BUILD); return 0; }
/************************************************************************* ** ** ** Function Definitions ** ** ** **************************************************************************/ int abobjP_move_object_outline( ABObj obj, XMotionEvent *mevent ) { static XRectangle parent_rect; static XRectangle last_rect; static int x_offset, y_offset; static Dimension border_w; static Display *dpy; XRectangle widget_rect; int trans_x, trans_y; /* First time: set up initial move variables */ if (first_move) { if (obj_is_item(obj)) obj = obj_get_parent(obj); obj = obj_get_root(obj); /* Multiple objects might be selected...*/ if (obj_is_control(obj) || obj_is_group(obj) || obj_is_pane(obj)) { abobj_get_selected(obj_get_root(obj_get_parent(obj)), False, False, &sel); } else { sel.count = 1; sel.list = (ABObj*)util_malloc(sizeof(ABObj)); sel.list[0] = obj; } xy_obj = objxm_comp_get_subobj(obj, AB_CFG_POSITION_OBJ); xy_widget = (Widget)xy_obj->ui_handle; if (xy_widget == NULL) { if (util_get_verbosity() > 2) fprintf(stderr,"abobjP_move_object_outline: %s :no POSITION widget\n", util_strsafe(obj_get_name(obj))); return ERROR; } dpy = XtDisplay(xy_widget); parent = XtParent(xy_widget); x_get_widget_rect(xy_widget, &widget_rect); x_get_widget_rect(parent, &parent_rect); if (sel.count > 1) { abobj_get_rect_for_objects(sel.list, sel.count, &orig_rect); } else { orig_rect = widget_rect; XtVaGetValues(xy_widget, XtNborderWidth, &border_w, NULL); orig_rect.width += (2*border_w); orig_rect.height += (2*border_w); orig_rect.width--; orig_rect.height--; } move_rect = orig_rect; drag_init_rect.x = mevent->x - AB_drag_threshold; drag_init_rect.y = mevent->y - AB_drag_threshold; drag_init_rect.width = drag_init_rect.height = 2 * AB_drag_threshold; x_offset = widget_rect.x - orig_rect.x + mevent->x; y_offset = widget_rect.y - orig_rect.y + mevent->y; first_move = False; rect_zero_out(&last_rect); } /* Don't begin rendering move outline until pointer is out of * the drag_init bounding box */ else if (!rect_includespoint(&drag_init_rect, mevent->x, mevent->y)) { Window win; /* event coords are relative to widget-must translate to parent */ XTranslateCoordinates(dpy, XtWindow(xy_widget), XtWindow(parent), mevent->x, mevent->y, &trans_x, &trans_y, &win); move_rect.x = trans_x - x_offset; move_rect.y = trans_y - y_offset; /* Ensure move outline is within the parent's rect */ if (move_rect.x < 0) move_rect.x = 0; else if ((move_rect.x + (short)move_rect.width + 1) >= (short)parent_rect.width) move_rect.x = parent_rect.width - (move_rect.width + 1); if (move_rect.y < 0) move_rect.y = 0; else if ((move_rect.y + (short)move_rect.height + 1) >= (short)parent_rect.height) move_rect.y = parent_rect.height - (move_rect.height + 1); /* If cursor has moved since last event, erase previous outline * and render new one (using XOR function) */ if (!rect_equal(&move_rect, &last_rect)) { if (!rect_isnull(&last_rect)) x_box_r(parent, &last_rect); x_box_r(parent, &move_rect); last_rect = move_rect; } } return OK; }