// For debugging static void DrawRedBoxAroundRect(gl_context_t* context, rect2d_t rect) { float const l = rect_left(rect); float const r = rect_right(rect); float const t = rect_top(rect); float const b = rect_bottom(rect); // Draw a yellow 1 pixel box around the entire thing. GLfloat boxLines[] = { l, b, 0, l, t, 0, r, t, 0, r, b, 0 }; // Use the program object glUseProgram(context->mainProgram); glVertexAttribPointer(context->a_position, 3, GL_FLOAT, GL_FALSE, 0, boxLines); glEnableVertexAttribArray(context->a_position); glUniform4f(context->u_fragColor, 1,0,0,1); glDrawArrays(GL_LINE_LOOP, 0, 4); check_gl(); }
/* * 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; }
static void project_rband( Widget widget, XEvent *event, XRectangle *rb_rect, XtPointer client_data ) { Vwr v = NULL; VNode *selected_nodes = NULL; VMethods m; ABSelectedRec old_sel, new_sel; XRectangle tmp_rect; int num_selected = 0, num_cur_selected = 0, i; XtVaGetValues(widget, XmNuserData, &v, NULL); if (!v) return; if (!(m = v->methods)) return; /* If rubberband was drawn from lower-right to upper-left, * translate rect so that x,y is upper-left point in rectangle. */ if (rect_right(rb_rect) < rb_rect->x || rect_bottom(rb_rect) < rb_rect->y) { tmp_rect.x = rect_right(rb_rect); tmp_rect.y = rect_bottom(rb_rect); tmp_rect.width = rb_rect->x - tmp_rect.x; tmp_rect.height = rb_rect->y - tmp_rect.y; rb_rect = &tmp_rect; } /* * Important: set rband_rect so that * the function 'project_select_rband' can see it. */ rband_rect = rb_rect; /* * Get list of currently selected modules in project * organizer */ vwr_get_cond(v->current_tree, &selected_nodes, &num_selected, select_fn); if (mselect_adjust) /* * If select adjust, remember how many modules are currently * selected */ num_cur_selected = num_selected; else { /* * If not select adjust, the current select count is reset */ num_cur_selected = 0; /* * Deselect all currently selected nodes */ for (i=0; i < num_selected; ++i) { ABObj obj; /* * Get ABObj */ obj = (ABObj)selected_nodes[i]->obj_data; if (!obj) continue; proj_deselect(obj); } } /* * Free up node list if it contained anything */ if (selected_nodes) util_free(selected_nodes); /* * Get nodes in browser that are within the * rubber band rectangle. */ vwr_get_cond(v->current_tree, &selected_nodes, &num_selected, project_select_rband); /* * Update (activate/deactivate) project organizer menu items */ update_menu_items(0, num_cur_selected + num_selected); /* * Return if no selected nodes */ if (num_selected == 0) return; /* * For each object enclosed in rubber band rectangle */ for (i=0; i < num_selected; ++i) { ABObj obj; int j; /* * Get ABObj */ obj = (ABObj)selected_nodes[i]->obj_data; if (!obj) continue; proj_select(obj); } /* * Unset rband_rect */ rband_rect = NULL; /* * Free up node list if it contained anything */ if (selected_nodes) util_free(selected_nodes); }
/* * 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; }