/* * Action: mouse button down on browser */ static void project_bpress( Widget widget, XEvent *event, String *params, int num_params ) { XButtonEvent *bevent; if (event->type == ButtonPress) { bevent = (XButtonEvent*)event; if (bevent->state == 0 && bevent->button == 1)/* RUBBERBAND SELECT */ { if (ui_initiate_rubberband(widget, True, project_rband, (XtPointer)NULL) == ERROR) { if (util_get_verbosity() > 0) fprintf(stderr,"project organizer: couldn't begin rubberbanding\n"); } else mselect_adjust = False; } else if (bevent->button == 2 || /* RUBBERBAND ADJUST SELECT */ (bevent->button == 1 && (bevent->state & ShiftMask))) { if (ui_initiate_rubberband(widget, True, project_rband, (XtPointer)NULL) == ERROR) { if (util_get_verbosity() > 0) fprintf(stderr,"project organizer: couldn't begin rubberbanding\n"); } else mselect_adjust = True; } } }
/************************************************************************* ** ** ** Function Definitions ** ** ** **************************************************************************/ void ui_win_front( Widget widget ) { Widget p_shell; if (widget == NULL) return; p_shell = ui_get_ancestor_shell(widget); if (XtIsRealized(p_shell)) XRaiseWindow(XtDisplay(p_shell),XtWindow(p_shell)); else if (util_get_verbosity() > 0) fprintf(stderr,"ui_win_front: widget not realized\n"); }
/* * Action: Show the module when double-clicked on. */ static void show_module( Widget widget, XEvent *event, String *params, int num_params ) { Vwr v = NULL; VNode selected_node; VMethods m; ABObj obj; ABObj winobj; AB_TRAVERSAL trav; XtVaGetValues(widget, XmNuserData, &v, NULL); if (!v) return; selected_node = vwr_locate_node(v, event->xbutton.x, event->xbutton.y); if (selected_node) { VNode *selected_nodes = NULL; int num_selected = 0; if (!(m = v->methods)) return; /* USE METHODS !! */ obj = (ABObj) selected_node->obj_data; if (!obj) return; /* * Set busy cursor before this potentially * lengthy operation */ ab_set_busy_cursor(TRUE); /* If the module is already showing, then * make all of its windows come to the fore- * ground. */ if (obj_has_flag(obj, MappedFlag)) { for (trav_open(&trav, obj, AB_TRAV_WINDOWS); (winobj = trav_next(&trav)) != NULL; ) { if (obj_has_flag(winobj, MappedFlag)) ui_win_front(objxm_get_widget(winobj)); } trav_close(&trav); proj_set_cur_module(obj); } else if( abobj_show_tree(obj, TRUE) == -1 ) { if (util_get_verbosity() > 0) fprintf(stderr,"show_module: error in abobj_show_tree\n"); } else { proj_set_cur_module(obj); } vwr_get_cond(v->current_tree, &selected_nodes, &num_selected, select_fn); if (selected_nodes) free((char *)selected_nodes); update_menu_items(0, num_selected); /* * Unset busy cursor */ ab_set_busy_cursor(FALSE); } }
/* * Function for undoing RESIZE */ static void undo_resize( ABUndoRec undo_rec ) { Position x, y; int width, height, i; ABObj obj; if (!undo_rec) return; /* * Set undo to undo this resize (undo of undo) */ (void)abobj_set_undo(undo_rec->list, undo_rec->count, undo_resize, AB_UNDO_RESIZE); /* * For each object that was resized */ for (i = 0; i < undo_rec->count; ++i) { BOOL w_resizable, h_resizable; /* * If undo record is not the right type, something is WRONG !! */ if (undo_rec->info_list[i].type != AB_UNDO_RESIZE) continue; obj = undo_rec->list[i]; w_resizable = abobj_width_resizable(obj); h_resizable = abobj_height_resizable(obj); /* * Get current x,y position */ if (obj->ui_handle) { XtVaGetValues(objxm_get_widget(obj), XmNx, &x, XmNy, &y, NULL); } else { x = (Position)obj_get_x(obj); y = (Position)obj_get_y(obj); } /* * Get previous width/height */ width = undo_rec->info_list[i].info.resize.width; height = undo_rec->info_list[i].info.resize.height; /* * Resize the object ! */ resize_in_pixels(obj, (int)width, (int)height, border_w); abobj_set_xy(obj, (int)x, (int)y); if (xy_obj->attachments) abobj_calculate_new_layout(xy_obj, (int)x, (int)y, width, height); abobj_instantiate_changes(obj); /* 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); } }
/* * 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; }
/* * 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; }