/* use for mousemove events */ static bool view3d_ruler_item_mousemove(bContext *C, RulerInfo *ruler_info, const int mval[2], const bool do_thickness, const bool do_snap) { const float eps_bias = 0.0002f; RulerItem *ruler_item = ruler_item_active_get(ruler_info); ruler_info->snap_flag &= ~RULER_SNAP_OK; if (ruler_item) { float *co = ruler_item->co[ruler_item->co_index]; /* restore the initial depth */ copy_v3_v3(co, ruler_info->drag_start_co); view3d_ruler_item_project(ruler_info, co, mval); if (do_thickness && ruler_item->co_index != 1) { const float mval_fl[2] = {UNPACK2(mval)}; float ray_normal[3]; float ray_start[3]; float *co_other; co_other = ruler_item->co[ruler_item->co_index == 0 ? 2 : 0]; if (ED_view3d_snap_co(C, co, ray_normal, mval_fl, true, false, false, false, true)) { negate_v3(ray_normal); /* add some bias */ madd_v3_v3v3fl(ray_start, co, ray_normal, eps_bias); ED_view3d_snap_ray(C, co_other, ray_start, ray_normal); } } else if (do_snap) { const float mval_fl[2] = {UNPACK2(mval)}; View3D *v3d = CTX_wm_view3d(C); bool use_depth = (v3d->drawtype >= OB_SOLID); bool is_hit = ED_view3d_snap_co(C, co, NULL, mval_fl, use_depth, false, true, true, use_depth); if (is_hit) { ruler_info->snap_flag |= RULER_SNAP_OK; } } return true; } else { return false; } }
static int paintcurve_slide_invoke(bContext *C, wmOperator *op, const wmEvent *event) { Paint *p = BKE_paint_get_active_from_context(C); const float loc_fl[2] = {UNPACK2(event->mval)}; char select; int i; bool do_select = RNA_boolean_get(op->ptr, "select"); bool align = RNA_boolean_get(op->ptr, "align"); Brush *br = p->brush; PaintCurve *pc = br->paint_curve; PaintCurvePoint *pcp; if (!pc) { return OPERATOR_PASS_THROUGH; } if (do_select) { pcp = paintcurve_point_get_closest(pc, loc_fl, align, PAINT_CURVE_SELECT_THRESHOLD, &select); } else { pcp = NULL; /* just find first selected point */ for (i = 0; i < pc->tot_points; i++) { if ((select = paintcurve_point_side_index(&pc->points[i].bez, i == 0, SEL_F3))) { pcp = &pc->points[i]; break; } } } if (pcp) { ARegion *ar = CTX_wm_region(C); wmWindow *window = CTX_wm_window(C); PointSlideData *psd = MEM_mallocN(sizeof(PointSlideData), "PointSlideData"); copy_v2_v2_int(psd->initial_loc, event->mval); psd->event = event->type; psd->pcp = pcp; psd->select = paintcurve_point_co_index(select); for (i = 0; i < 3; i++) { copy_v2_v2(psd->point_initial_loc[i], pcp->bez.vec[i]); } psd->align = align; op->customdata = psd; /* first, clear all selection from points */ for (i = 0; i < pc->tot_points; i++) { pc->points[i].bez.f1 = pc->points[i].bez.f3 = pc->points[i].bez.f2 = 0; } /* only select the active point */ PAINT_CURVE_POINT_SELECT(pcp, psd->select); BKE_paint_curve_clamp_endpoint_add_index(pc, pcp - pc->points); WM_event_add_modal_handler(C, op); WM_paint_cursor_tag_redraw(window, ar); return OPERATOR_RUNNING_MODAL; } return OPERATOR_PASS_THROUGH; }
/** * Only to check for error-cases. */ static void polyfill_validate_tri(unsigned int (*tris)[3], unsigned int tri_index, EdgeHash *ehash) { const unsigned int *tri = tris[tri_index]; int j_curr; BLI_assert(!ELEM(tri[0], tri[1], tri[2]) && !ELEM(tri[1], tri[0], tri[2]) && !ELEM(tri[2], tri[0], tri[1])); for (j_curr = 0; j_curr < 3; j_curr++) { struct PolyEdge *e; unsigned int e_v1 = tri[(j_curr ) ]; unsigned int e_v2 = tri[(j_curr + 1) % 3]; e = BLI_edgehash_lookup(ehash, e_v1, e_v2); if (e) { if (e->faces[0] == tri_index) { BLI_assert(e->verts[0] == e_v1); BLI_assert(e->verts[1] == e_v2); } else if (e->faces[1] == tri_index) { BLI_assert(e->verts[0] == e_v2); BLI_assert(e->verts[1] == e_v1); } else { BLI_assert(0); } BLI_assert(e->faces[0] != e->faces[1]); BLI_assert(ELEM(e_v1, UNPACK3(tri))); BLI_assert(ELEM(e_v2, UNPACK3(tri))); BLI_assert(ELEM(e_v1, UNPACK2(e->verts))); BLI_assert(ELEM(e_v2, UNPACK2(e->verts))); BLI_assert(e_v1 != tris[e->faces[0]][e->faces_other_v[0]]); BLI_assert(e_v1 != tris[e->faces[1]][e->faces_other_v[1]]); BLI_assert(e_v2 != tris[e->faces[0]][e->faces_other_v[0]]); BLI_assert(e_v2 != tris[e->faces[1]][e->faces_other_v[1]]); BLI_assert(ELEM(tri_index, UNPACK2(e->faces))); } } }
static void polyedge_beauty_cost_update( const float (*coords)[2], const unsigned int (*tris)[3], const struct PolyEdge *edges, struct PolyEdge *e, Heap *eheap, HeapNode **eheap_table, EdgeHash *ehash) { const unsigned int *tri_0 = tris[e->faces[0]]; const unsigned int *tri_1 = tris[e->faces[1]]; unsigned int i; struct PolyEdge *e_arr[4] = { BLI_edgehash_lookup(ehash, tri_0[(e->faces_other_v[0] ) % 3], tri_0[(e->faces_other_v[0] + 1) % 3]), BLI_edgehash_lookup(ehash, tri_0[(e->faces_other_v[0] + 2) % 3], tri_0[(e->faces_other_v[0] ) % 3]), BLI_edgehash_lookup(ehash, tri_1[(e->faces_other_v[1] ) % 3], tri_1[(e->faces_other_v[1] + 1) % 3]), BLI_edgehash_lookup(ehash, tri_1[(e->faces_other_v[1] + 2) % 3], tri_1[(e->faces_other_v[1] ) % 3]), }; for (i = 0; i < 4; i++) { if (e_arr[i]) { BLI_assert(!(ELEM(e_arr[i]->faces[0], UNPACK2(e->faces)) && ELEM(e_arr[i]->faces[1], UNPACK2(e->faces)))); polyedge_beauty_cost_update_single( coords, tris, edges, e_arr[i], eheap, eheap_table); } } }
static int paintcurve_select_point_invoke(bContext *C, wmOperator *op, const wmEvent *event) { int loc[2] = {UNPACK2(event->mval)}; bool toggle = RNA_boolean_get(op->ptr, "toggle"); bool extend = RNA_boolean_get(op->ptr, "extend"); if (paintcurve_point_select(C, op, loc, toggle, extend)) { RNA_int_set_array(op->ptr, "location", loc); return OPERATOR_FINISHED; } else { return OPERATOR_CANCELLED; } }
/** * Translate any popup regions (so we can drag them). */ void ui_popup_translate(ARegion *ar, const int mdiff[2]) { uiBlock *block; BLI_rcti_translate(&ar->winrct, UNPACK2(mdiff)); ED_region_update_rect(ar); ED_region_tag_redraw(ar); /* update blocks */ for (block = ar->uiblocks.first; block; block = block->next) { uiPopupBlockHandle *handle = block->handle; /* Make empty, will be initialized on next use, see T60608. */ BLI_rctf_init(&handle->prev_block_rect, 0, 0, 0, 0); uiSafetyRct *saferct; for (saferct = block->saferct.first; saferct; saferct = saferct->next) { BLI_rctf_translate(&saferct->parent, UNPACK2(mdiff)); BLI_rctf_translate(&saferct->safety, UNPACK2(mdiff)); } } }
/** * \note #StrokeElem.mval & #StrokeElem.pressure must be set first. */ static bool stroke_elem_project_fallback_elem( const struct CurveDrawData *cdd, const float location_fallback_depth[3], struct StrokeElem *selem) { const int mval_i[2] = {UNPACK2(selem->mval)}; const float radius = stroke_elem_radius(cdd, selem); return stroke_elem_project_fallback( cdd, mval_i, selem->mval, cdd->project.surface_offset, radius, location_fallback_depth, selem->location_world, selem->location_local, selem->normal_world, selem->normal_local); }
static void polyedge_rotate( unsigned int (*tris)[3], struct PolyEdge *e, EdgeHash *ehash) { unsigned int e_v1_new = tris[e->faces[0]][e->faces_other_v[0]]; unsigned int e_v2_new = tris[e->faces[1]][e->faces_other_v[1]]; #ifndef NDEBUG polyfill_validate_tri(tris, e->faces[0], ehash); polyfill_validate_tri(tris, e->faces[1], ehash); #endif BLI_assert(e_v1_new != e_v2_new); BLI_assert(!ELEM(e_v2_new, UNPACK3(tris[e->faces[0]]))); BLI_assert(!ELEM(e_v1_new, UNPACK3(tris[e->faces[1]]))); tris[e->faces[0]][(e->faces_other_v[0] + 1) % 3] = e_v2_new; tris[e->faces[1]][(e->faces_other_v[1] + 1) % 3] = e_v1_new; e->faces_other_v[0] = (e->faces_other_v[0] + 2) % 3; e->faces_other_v[1] = (e->faces_other_v[1] + 2) % 3; BLI_assert((tris[e->faces[0]][e->faces_other_v[0]] != e_v1_new) && (tris[e->faces[0]][e->faces_other_v[0]] != e_v2_new)); BLI_assert((tris[e->faces[1]][e->faces_other_v[1]] != e_v1_new) && (tris[e->faces[1]][e->faces_other_v[1]] != e_v2_new)); BLI_edgehash_remove(ehash, e->verts[0], e->verts[1], NULL); BLI_edgehash_insert(ehash, e_v1_new, e_v2_new, e); if (e_v1_new < e_v2_new) { e->verts[0] = e_v1_new; e->verts[1] = e_v2_new; } else { /* maintain winding info */ e->verts[0] = e_v2_new; e->verts[1] = e_v1_new; SWAP(unsigned int, e->faces[0], e->faces[1]); SWAP(unsigned int, e->faces_other_v[0], e->faces_other_v[1]); } /* update adjacent data */ { unsigned int e_side = 0; for (e_side = 0; e_side < 2; e_side++) { /* 't_other' which we need to swap out is always the same edge-order */ const unsigned int t_other = (((e->faces_other_v[e_side]) + 2)) % 3; unsigned int t_index = e->faces[e_side]; unsigned int t_index_other = e->faces[!e_side]; unsigned int *tri = tris[t_index]; struct PolyEdge *e_other; unsigned int e_v1 = tri[(t_other ) ]; unsigned int e_v2 = tri[(t_other + 1) % 3]; e_other = BLI_edgehash_lookup(ehash, e_v1, e_v2); if (e_other) { BLI_assert(t_index != e_other->faces[0] && t_index != e_other->faces[1]); if (t_index_other == e_other->faces[0]) { e_other->faces[0] = t_index; e_other->faces_other_v[0] = (t_other + 2) % 3; BLI_assert(!ELEM(tri[e_other->faces_other_v[0]], e_v1, e_v2)); } else if (t_index_other == e_other->faces[1]) { e_other->faces[1] = t_index; e_other->faces_other_v[1] = (t_other + 2) % 3; BLI_assert(!ELEM(tri[e_other->faces_other_v[1]], e_v1, e_v2)); } else { BLI_assert(0); } } } } #ifndef NDEBUG polyfill_validate_tri(tris, e->faces[0], ehash); polyfill_validate_tri(tris, e->faces[1], ehash); #endif BLI_assert(!ELEM(tris[e->faces[0]][e->faces_other_v[0]], UNPACK2(e->verts))); BLI_assert(!ELEM(tris[e->faces[1]][e->faces_other_v[1]], UNPACK2(e->verts))); }
static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event) { bool do_draw = false; int exit_code = OPERATOR_RUNNING_MODAL; RulerInfo *ruler_info = op->customdata; ScrArea *sa = ruler_info->sa; ARegion *ar = ruler_info->ar; RegionView3D *rv3d = ar->regiondata; /* its possible to change spaces while running the operator [#34894] */ if (UNLIKELY(ar != CTX_wm_region(C))) { exit_code = OPERATOR_FINISHED; goto exit; } switch (event->type) { case LEFTMOUSE: if (event->val == KM_RELEASE) { if (ruler_info->state == RULER_STATE_DRAG) { /* rubber-band angle removal */ RulerItem *ruler_item = ruler_item_active_get(ruler_info); if (ruler_item && (ruler_item->co_index == 1) && (ruler_item->flag & RULERITEM_USE_ANGLE)) { if (!BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) { ruler_item->flag &= ~RULERITEM_USE_ANGLE; do_draw = true; } } if (ruler_info->snap_flag & RULER_SNAP_OK) { ruler_info->snap_flag &= ~RULER_SNAP_OK; do_draw = true; } ruler_info->state = RULER_STATE_NORMAL; } } else { if (ruler_info->state == RULER_STATE_NORMAL) { if (event->ctrl || /* weak - but user friendly */ BLI_listbase_is_empty(&ruler_info->items)) { View3D *v3d = CTX_wm_view3d(C); const bool use_depth = (v3d->drawtype >= OB_SOLID); /* Create new line */ RulerItem *ruler_item_prev = ruler_item_active_get(ruler_info); RulerItem *ruler_item; /* check if we want to drag an existing point or add a new one */ ruler_info->state = RULER_STATE_DRAG; ruler_item = ruler_item_add(ruler_info); ruler_item_active_set(ruler_info, ruler_item); if (use_depth) { /* snap the first point added, not essential but handy */ ruler_item->co_index = 0; view3d_ruler_item_mousemove(C, ruler_info, event->mval, false, true); copy_v3_v3(ruler_info->drag_start_co, ruler_item->co[ruler_item->co_index]); } else { /* initial depth either previous ruler, view offset */ if (ruler_item_prev) { copy_v3_v3(ruler_info->drag_start_co, ruler_item_prev->co[ruler_item_prev->co_index]); } else { negate_v3_v3(ruler_info->drag_start_co, rv3d->ofs); } copy_v3_v3(ruler_item->co[0], ruler_info->drag_start_co); view3d_ruler_item_project(ruler_info, ruler_item->co[0], event->mval); } copy_v3_v3(ruler_item->co[2], ruler_item->co[0]); ruler_item->co_index = 2; do_draw = true; } else { float mval_fl[2] = {UNPACK2(event->mval)}; RulerItem *ruler_item_pick; int co_index; /* select and drag */ if (view3d_ruler_pick(ruler_info, mval_fl, &ruler_item_pick, &co_index)) { if (co_index == -1) { if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) { /* Add Center Point */ ruler_item_active_set(ruler_info, ruler_item_pick); ruler_item_pick->flag |= RULERITEM_USE_ANGLE; ruler_item_pick->co_index = 1; ruler_info->state = RULER_STATE_DRAG; /* find the factor */ { float co_ss[2][2]; float fac; ED_view3d_project_float_global(ar, ruler_item_pick->co[0], co_ss[0], V3D_PROJ_TEST_NOP); ED_view3d_project_float_global(ar, ruler_item_pick->co[2], co_ss[1], V3D_PROJ_TEST_NOP); fac = line_point_factor_v2(mval_fl, co_ss[0], co_ss[1]); CLAMP(fac, 0.0f, 1.0f); interp_v3_v3v3(ruler_item_pick->co[1], ruler_item_pick->co[0], ruler_item_pick->co[2], fac); } /* update the new location */ view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->shift != 0, event->ctrl != 0); do_draw = true; } } else { ruler_item_active_set(ruler_info, ruler_item_pick); ruler_item_pick->co_index = co_index; ruler_info->state = RULER_STATE_DRAG; /* store the initial depth */ copy_v3_v3(ruler_info->drag_start_co, ruler_item_pick->co[ruler_item_pick->co_index]); do_draw = true; } } else { exit_code = OPERATOR_PASS_THROUGH; } } } } break; case CKEY: { if (event->ctrl) { RulerItem *ruler_item = ruler_item_active_get(ruler_info); if (ruler_item) { const int prec = 8; char numstr[256]; Scene *scene = CTX_data_scene(C); UnitSettings *unit = &scene->unit; ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec); WM_clipboard_text_set((void *) numstr, false); } } break; } case RIGHTCTRLKEY: case LEFTCTRLKEY: { WM_event_add_mousemove(C); break; } case MOUSEMOVE: { if (ruler_info->state == RULER_STATE_DRAG) { if (view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->shift != 0, event->ctrl != 0)) { do_draw = true; } } break; } case ESCKEY: { do_draw = true; exit_code = OPERATOR_CANCELLED; break; } case RETKEY: { view3d_ruler_to_gpencil(C, ruler_info); do_draw = true; exit_code = OPERATOR_FINISHED; break; } case DELKEY: { if (event->val == KM_PRESS) { if (ruler_info->state == RULER_STATE_NORMAL) { RulerItem *ruler_item = ruler_item_active_get(ruler_info); if (ruler_item) { RulerItem *ruler_item_other = ruler_item->prev ? ruler_item->prev : ruler_item->next; ruler_item_remove(ruler_info, ruler_item); ruler_item_active_set(ruler_info, ruler_item_other); do_draw = true; } } } break; } default: exit_code = OPERATOR_PASS_THROUGH; break; } if (do_draw) { view3d_ruler_header_update(sa); /* all 3d views draw rulers */ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); } exit: if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) { WM_cursor_modal_restore(ruler_info->win); view3d_ruler_end(C, ruler_info); view3d_ruler_free(ruler_info); op->customdata = NULL; ED_area_headerprint(sa, NULL); } return exit_code; }
static bool view3d_ruler_pick(RulerInfo *ruler_info, const float mval[2], RulerItem **r_ruler_item, int *r_co_index) { ARegion *ar = ruler_info->ar; RulerItem *ruler_item; float dist_best = RULER_PICK_DIST_SQ; RulerItem *ruler_item_best = NULL; int co_index_best = -1; for (ruler_item = ruler_info->items.first; ruler_item; ruler_item = ruler_item->next) { float co_ss[3][2]; float dist; int j; /* should these be checked? - ok for now not to */ for (j = 0; j < 3; j++) { ED_view3d_project_float_global(ar, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_NOP); } if (ruler_item->flag & RULERITEM_USE_ANGLE) { dist = min_ff(dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[1]), dist_squared_to_line_segment_v2(mval, co_ss[1], co_ss[2])); if (dist < dist_best) { dist_best = dist; ruler_item_best = ruler_item; { const float dist_points[3] = { len_squared_v2v2(co_ss[0], mval), len_squared_v2v2(co_ss[1], mval), len_squared_v2v2(co_ss[2], mval), }; if (min_fff(UNPACK3(dist_points)) < RULER_PICK_DIST_SQ) { co_index_best = min_axis_v3(dist_points); } else { co_index_best = -1; } } } } else { dist = dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[2]); if (dist < dist_best) { dist_best = dist; ruler_item_best = ruler_item; { const float dist_points[2] = { len_squared_v2v2(co_ss[0], mval), len_squared_v2v2(co_ss[2], mval), }; if (min_ff(UNPACK2(dist_points)) < RULER_PICK_DIST_SQ) { co_index_best = (dist_points[0] < dist_points[1]) ? 0 : 2; } else { co_index_best = -1; } } } } } if (ruler_item_best) { *r_ruler_item = ruler_item_best; *r_co_index = co_index_best; return true; } else { *r_ruler_item = NULL; *r_co_index = -1; return false; } }
static bool paintcurve_point_select( bContext *C, wmOperator *op, const int loc[2], bool toggle, bool extend) { wmWindow *window = CTX_wm_window(C); ARegion *ar = CTX_wm_region(C); Paint *p = BKE_paint_get_active_from_context(C); Brush *br = p->brush; PaintCurve *pc; int i; const float loc_fl[2] = {UNPACK2(loc)}; pc = br->paint_curve; if (!pc) { return false; } ED_paintcurve_undo_push_begin(op->type->name); if (toggle) { PaintCurvePoint *pcp; char select = 0; bool selected = false; pcp = pc->points; for (i = 0; i < pc->tot_points; i++) { if (pcp[i].bez.f1 || pcp[i].bez.f2 || pcp[i].bez.f3) { selected = true; break; } } if (!selected) { select = SELECT; } for (i = 0; i < pc->tot_points; i++) { pc->points[i].bez.f1 = pc->points[i].bez.f2 = pc->points[i].bez.f3 = select; } } else { PaintCurvePoint *pcp; char selflag; pcp = paintcurve_point_get_closest(pc, loc_fl, false, PAINT_CURVE_SELECT_THRESHOLD, &selflag); if (pcp) { BKE_paint_curve_clamp_endpoint_add_index(pc, pcp - pc->points); if (selflag == SEL_F2) { if (extend) { pcp->bez.f2 ^= SELECT; } else { pcp->bez.f2 |= SELECT; } } else if (selflag == SEL_F1) { if (extend) { pcp->bez.f1 ^= SELECT; } else { pcp->bez.f1 |= SELECT; } } else if (selflag == SEL_F3) { if (extend) { pcp->bez.f3 ^= SELECT; } else { pcp->bez.f3 |= SELECT; } } } /* clear selection for unselected points if not extending and if a point has been selected */ if (!extend && pcp) { for (i = 0; i < pc->tot_points; i++) { pc->points[i].bez.f1 = pc->points[i].bez.f2 = pc->points[i].bez.f3 = 0; if ((pc->points + i) == pcp) { char index = paintcurve_point_co_index(selflag); PAINT_CURVE_POINT_SELECT(pcp, index); } } } if (!pcp) { ED_paintcurve_undo_push_end(); return false; } } ED_paintcurve_undo_push_end(); WM_paint_cursor_tag_redraw(window, ar); return true; }
/** * Called for creating new popups and refreshing existing ones. */ uiBlock *ui_popup_block_refresh(bContext *C, uiPopupBlockHandle *handle, ARegion *butregion, uiBut *but) { const int margin = UI_POPUP_MARGIN; wmWindow *window = CTX_wm_window(C); ARegion *ar = handle->region; uiBlockCreateFunc create_func = handle->popup_create_vars.create_func; uiBlockHandleCreateFunc handle_create_func = handle->popup_create_vars.handle_create_func; void *arg = handle->popup_create_vars.arg; uiBlock *block_old = ar->uiblocks.first; uiBlock *block; handle->refresh = (block_old != NULL); BLI_assert(!handle->refresh || handle->can_refresh); #ifdef DEBUG wmEvent *event_back = window->eventstate; #endif /* create ui block */ if (create_func) { block = create_func(C, ar, arg); } else { block = handle_create_func(C, handle, arg); } /* callbacks _must_ leave this for us, otherwise we can't call UI_block_update_from_old */ BLI_assert(!block->endblock); /* ensure we don't use mouse coords here! */ #ifdef DEBUG window->eventstate = NULL; #endif if (block->handle) { memcpy(block->handle, handle, sizeof(uiPopupBlockHandle)); MEM_freeN(handle); handle = block->handle; } else { block->handle = handle; } ar->regiondata = handle; /* set UI_BLOCK_NUMSELECT before UI_block_end() so we get alphanumeric keys assigned */ if (but == NULL) { block->flag |= UI_BLOCK_POPUP; } block->flag |= UI_BLOCK_LOOP; UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP); /* defer this until blocks are translated (below) */ block->oldblock = NULL; if (!block->endblock) { UI_block_end_ex( C, block, handle->popup_create_vars.event_xy, handle->popup_create_vars.event_xy); } /* if this is being created from a button */ if (but) { block->aspect = but->block->aspect; ui_popup_block_position(window, butregion, but, block); handle->direction = block->direction; } else { uiSafetyRct *saferct; /* keep a list of these, needed for pulldown menus */ saferct = MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct"); saferct->safety = block->safety; BLI_addhead(&block->saferct, saferct); } if (block->flag & UI_BLOCK_RADIAL) { int win_width = UI_SCREEN_MARGIN; int winx, winy; int x_offset = 0, y_offset = 0; winx = WM_window_pixels_x(window); winy = WM_window_pixels_y(window); copy_v2_v2(block->pie_data.pie_center_init, block->pie_data.pie_center_spawned); /* only try translation if area is large enough */ if (BLI_rctf_size_x(&block->rect) < winx - (2.0f * win_width)) { if (block->rect.xmin < win_width) { x_offset += win_width - block->rect.xmin; } if (block->rect.xmax > winx - win_width) { x_offset += winx - win_width - block->rect.xmax; } } if (BLI_rctf_size_y(&block->rect) < winy - (2.0f * win_width)) { if (block->rect.ymin < win_width) { y_offset += win_width - block->rect.ymin; } if (block->rect.ymax > winy - win_width) { y_offset += winy - win_width - block->rect.ymax; } } /* if we are offsetting set up initial data for timeout functionality */ if ((x_offset != 0) || (y_offset != 0)) { block->pie_data.pie_center_spawned[0] += x_offset; block->pie_data.pie_center_spawned[1] += y_offset; UI_block_translate(block, x_offset, y_offset); if (U.pie_initial_timeout > 0) { block->pie_data.flags |= UI_PIE_INITIAL_DIRECTION; } } ar->winrct.xmin = 0; ar->winrct.xmax = winx; ar->winrct.ymin = 0; ar->winrct.ymax = winy; ui_block_calc_pie_segment(block, block->pie_data.pie_center_init); /* lastly set the buttons at the center of the pie menu, ready for animation */ if (U.pie_animation_timeout > 0) { for (uiBut *but_iter = block->buttons.first; but_iter; but_iter = but_iter->next) { if (but_iter->pie_dir != UI_RADIAL_NONE) { BLI_rctf_recenter(&but_iter->rect, UNPACK2(block->pie_data.pie_center_spawned)); } } } } else { /* clip block with window boundary */ ui_popup_block_clip(window, block); /* Avoid menu moving down and losing cursor focus by keeping it at * the same height. */ if (handle->refresh && handle->prev_block_rect.ymax > block->rect.ymax) { float offset = handle->prev_block_rect.ymax - block->rect.ymax; UI_block_translate(block, 0, offset); block->rect.ymin = handle->prev_block_rect.ymin; } handle->prev_block_rect = block->rect; /* the block and buttons were positioned in window space as in 2.4x, now * these menu blocks are regions so we bring it back to region space. * additionally we add some padding for the menu shadow or rounded menus */ ar->winrct.xmin = block->rect.xmin - margin; ar->winrct.xmax = block->rect.xmax + margin; ar->winrct.ymin = block->rect.ymin - margin; ar->winrct.ymax = block->rect.ymax + UI_POPUP_MENU_TOP; UI_block_translate(block, -ar->winrct.xmin, -ar->winrct.ymin); /* apply scroll offset */ if (handle->scrolloffset != 0.0f) { for (uiBut *bt = block->buttons.first; bt; bt = bt->next) { bt->rect.ymin += handle->scrolloffset; bt->rect.ymax += handle->scrolloffset; } } } if (block_old) { block->oldblock = block_old; UI_block_update_from_old(C, block); UI_blocklist_free_inactive(C, &ar->uiblocks); } /* checks which buttons are visible, sets flags to prevent draw (do after region init) */ ui_popup_block_scrolltest(block); /* adds subwindow */ ED_region_init(ar); /* get winmat now that we actually have the subwindow */ wmGetProjectionMatrix(block->winmat, &ar->winrct); /* notify change and redraw */ ED_region_tag_redraw(ar); ED_region_update_rect(ar); #ifdef DEBUG window->eventstate = event_back; #endif return block; }
/* ------------------------------------------------------------------------------------ */ #if GASNETE_BUILD_AMREF_GET_HANDLERS GASNETI_INLINE(gasnete_amref_get_reqh_inner) void gasnete_amref_get_reqh_inner(gasnet_token_t token, gasnet_handlerarg_t nbytes, void *dest, void *src, void *done) { gasneti_assert(nbytes <= gasnet_AMMaxMedium()); GASNETI_SAFE( MEDIUM_REP(2,4,(token, gasneti_handleridx(gasnete_amref_get_reph), src, nbytes, PACK(dest), PACK(done)))); } SHORT_HANDLER(gasnete_amref_get_reqh,4,7, (token, a0, UNPACK(a1), UNPACK(a2), UNPACK(a3) ), (token, a0, UNPACK2(a1, a2), UNPACK2(a3, a4), UNPACK2(a5, a6))); GASNETI_INLINE(gasnete_amref_get_reph_inner) void gasnete_amref_get_reph_inner(gasnet_token_t token, void *addr, size_t nbytes, void *dest, void *done) { GASNETE_FAST_UNALIGNED_MEMCPY(dest, addr, nbytes); MARK_DONE(done,1); } MEDIUM_HANDLER(gasnete_amref_get_reph,2,4, (token,addr,nbytes, UNPACK(a0), UNPACK(a1) ), (token,addr,nbytes, UNPACK2(a0, a1), UNPACK2(a2, a3))); GASNETI_INLINE(gasnete_amref_getlong_reqh_inner) void gasnete_amref_getlong_reqh_inner(gasnet_token_t token, gasnet_handlerarg_t nbytes, void *dest, void *src, void *done) {