static void custdlg_create_area( ABObj obj, AB_CONTAINER_TYPE area_type ) { ABObj pwobj; ABObj label, area; ABObj workobj; Dimension height; pwobj = objxm_comp_get_subobj(obj, AB_CFG_WINDOW_PW_OBJ); workobj = objxm_comp_get_subobj(obj, AB_CFG_PARENT_OBJ); area = obj_create(AB_TYPE_CONTAINER, pwobj); obj_set_subtype(area, area_type); pal_initialize_obj(area); if (area_type == AB_CONT_FOOTER) { label = obj_create(AB_TYPE_LABEL, area); obj_set_x(label, 1); obj_set_y(label, 1); pal_initialize_obj(label); obj_set_label(label, catgets(Dtb_project_catd, 100, 264, "footer message")); obj_set_label_alignment(label, AB_ALIGN_LEFT); obj_set_unique_name(label, ab_ident_from_name_and_label(obj_get_name(obj), "label")); /* * Workaround part1: MainWindow bug that causes MainWindow to shrink * when a MessageWindow area is added */ XtVaGetValues(objxm_get_widget(workobj), XmNheight, &height, NULL); } else if (area_type == AB_CONT_BUTTON_PANEL) custdlg_create_buttons(obj, area); abobj_show_tree(area, True); /* Workaround part2 */ if (area_type == AB_CONT_FOOTER) XtVaSetValues(objxm_get_widget(workobj), XmNheight, height, NULL); abobj_set_save_needed(obj_get_module(obj), True); }
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]); } }
/* ** Set the label glyph (ie graphic) on an object */ void ui_obj_set_label_glyph( ABObj obj, STRING fileName ) { ABObj labelObj = NULL; if (obj == NULL) return; if (util_strempty(fileName)) return; labelObj = objxm_comp_get_subobj(obj, AB_CFG_LABEL_OBJ); if (labelObj == NULL || objxm_get_widget(labelObj) == 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: ui_set_label_glyph(objxm_get_widget(labelObj), fileName); 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: ui_set_label_glyph(objxm_get_widget(labelObj), fileName); break; default: break; } break; default: break; } }
static void subtract_attached_label( ABObj obj, XRectangle *r_rect ) { ABObj lblObj; Widget lbl_widget; Dimension lbl_w = 0; Dimension lbl_h = 0; Dimension margin = 0; Dimension spacing = 0; Dimension width, height; if (!abobj_has_attached_label(obj)) return; lblObj = objxm_comp_get_subobj(obj, AB_CFG_LABEL_OBJ); lbl_widget = objxm_get_widget(lblObj); if (lblObj != NULL && lbl_widget != NULL) { switch(obj_get_label_position(obj)) { case AB_CP_WEST: XtVaGetValues(lbl_widget, XmNwidth, &lbl_w, NULL); XtVaGetValues(XtParent(lbl_widget), /* RowColumn */ XmNmarginWidth, &margin, XmNspacing, &spacing, NULL); width = r_rect->width - lbl_w - (2*margin) - spacing; r_rect->width = width; break; case AB_CP_NORTH: XtVaGetValues(lbl_widget, XmNheight, &lbl_h, NULL); XtVaGetValues(XtParent(lbl_widget), /* RowColumn */ XmNmarginHeight, &margin, XmNspacing, &spacing, NULL); height = r_rect->height - lbl_h - (2*margin) - spacing; r_rect->height = height; break; default: break; } } }
/* * Sort the objects children by either X or Y. */ void abobj_sort_children( ABObj obj, int sort ) { ABObj child1, child2; ABObj pobj = objxm_comp_get_subobj(obj, AB_CFG_PARENT_OBJ); int num_children = obj_get_num_children(pobj); int i, j; int x1, y1, x2, y2; for (i = 0; i < num_children; i++) { for (j = i; j < num_children; j++) { child1 = obj_get_child(pobj, i); child2 = obj_get_child(pobj, j); x1 = obj_get_x(child1); y1 = obj_get_y(child1); x2 = obj_get_x(child2); y2 = obj_get_y(child2); if (sort == XSORT) { if (x2 < x1 || (x2 == x1 && y2 < y1)) obj_swap_siblings(child1, child2); } else { if (y2 < y1 || (y2 == y1 && x2 < x1)) obj_swap_siblings(child1, child2); } } } }
/* ** 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; } }
/* * 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); }
/* * Either works on a object or its children. * Clear the obj's attachments entirely if init_attachments * is TRUE but also configure the widget hierarchy to have two * basic connections: North and West point attachments with the * objs x and y offsets. */ void abobj_clear_layout( ABObj obj, BOOL clear_children, BOOL init_attachments ) { ABObj pos_obj = objxm_comp_get_subobj(obj, AB_CFG_POSITION_OBJ); ABAttachment attach; if (clear_children) { AB_TRAVERSAL trav; ABObj child; for (trav_open(&trav, pos_obj, AB_TRAV_SALIENT_CHILDREN | AB_TRAV_MOD_SAFE); (child = trav_next(&trav)) != NULL; ) { /* Configure the tree to have just basic attachments */ attach.type = AB_ATTACH_POINT; attach.value = (void *)NULL; attach.offset = abobj_get_y(child); abobj_set_attachment(child, AB_CP_NORTH, &attach); attach.type = AB_ATTACH_POINT; attach.value = (void *)NULL; attach.offset = abobj_get_x(child); abobj_set_attachment(child, AB_CP_WEST, &attach); attach.type = AB_ATTACH_NONE; attach.value = (void *)NULL; attach.offset = 0; abobj_set_attachment(child, AB_CP_SOUTH, &attach); abobj_set_attachment(child, AB_CP_EAST, &attach); abobj_instantiate_changes(child); /* * Clear out all attachments in obj structure * if init_attachments is set */ if (init_attachments) obj_init_attachments(child); } trav_close(&trav); } else { attach.type = AB_ATTACH_POINT; attach.value = (void *)NULL; attach.offset = abobj_get_y(pos_obj); abobj_set_attachment(pos_obj, AB_CP_NORTH, &attach); attach.type = AB_ATTACH_POINT; attach.value = (void *)NULL; attach.offset = abobj_get_x(pos_obj); abobj_set_attachment(pos_obj, AB_CP_WEST, &attach); attach.type = AB_ATTACH_NONE; attach.value = (void *)NULL; attach.offset = 0; abobj_set_attachment(pos_obj, AB_CP_SOUTH, &attach); abobj_set_attachment(pos_obj, AB_CP_EAST, &attach); abobj_instantiate_changes(pos_obj); /* * Clear out all attachments in obj structure * if init_attachments is set */ if (init_attachments) obj_init_attachments(pos_obj); } }
/************************************************************************* ** ** ** 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; }
static BOOL verify_props( AB_PROP_TYPE type ) { PropCustdlgSettingsRec *pcs = &(prop_custdlg_settings_rec[type]); ABObj area; BOOL area_set; if (prop_changed(pcs->name.changebar) && !prop_name_ok(pcs->current_obj, pcs->name.field)) return False; if (prop_changed(pcs->areas.changebar)) { DTB_MODAL_ANSWER answer = DTB_ANSWER_NONE; ABObj pobj; /* Check Button Panel */ area = objxm_comp_custdlg_get_area(pcs->current_obj, AB_CONT_BUTTON_PANEL); area_set = prop_checkbox_get_value(&(pcs->areas), AB_CONT_BUTTON_PANEL); if (area != NULL && !area_set) /* Remove Menubar */ { pobj = objxm_comp_get_subobj(area, AB_CFG_PARENT_OBJ); if (obj_get_num_children(pobj) > 0) { /* Popup Modal Message and wait for answer */ dtb_custdlg_remove_bpanel_msg_initialize( &dtb_custdlg_remove_bpanel_msg); answer = dtb_show_modal_message(pcs->areas.checkbox, &dtb_custdlg_remove_bpanel_msg, NULL, NULL, NULL); if (answer == DTB_ANSWER_CANCEL) return False; } } area = objxm_comp_custdlg_get_area(pcs->current_obj, AB_CONT_FOOTER); area_set = prop_checkbox_get_value(&(pcs->areas), AB_CONT_FOOTER); if (area != NULL && !area_set) /* Remove Footer */ { pobj = objxm_comp_get_subobj(area, AB_CFG_PARENT_OBJ); if (obj_get_num_children(pobj) > 0) { /* Popup Modal Message and wait for answer */ dtb_custdlg_remove_footer_msg_initialize( &dtb_custdlg_remove_footer_msg); answer = dtb_show_modal_message(pcs->areas.checkbox, &dtb_custdlg_remove_footer_msg, NULL, NULL, NULL); if (answer == DTB_ANSWER_CANCEL) return False; } } } if (prop_changed(pcs->geometry.changebar) && (!prop_number_ok(pcs->geometry.w_field, (STRING)WFieldStr, 1, SHRT_MAX) || !prop_number_ok(pcs->geometry.h_field, (STRING)HFieldStr, 1, SHRT_MAX))) return False; if (prop_changed(pcs->fg_color.changebar) && !prop_color_ok(pcs->fg_color.field)) return False; if (prop_changed(pcs->bg_color.changebar) && !prop_color_ok(pcs->bg_color.field)) return False; return True; }