Esempio n. 1
0
/* 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;
	}
}
Esempio n. 2
0
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);
        }
    }
}
Esempio n. 5
0
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;
  }
}
Esempio n. 6
0
/**
 * 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));
    }
  }
}
Esempio n. 7
0
/**
 * \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)));
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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;
	}
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
/**
 * 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) {