simplify drag toggle operator, use BLI_rctf_isect_segment between mouse events rather then many calls to ui_but_find_mouse_over().
This commit is contained in:
@@ -153,6 +153,7 @@ typedef struct uiHandleButtonData {
|
|||||||
int maxlen, selextend, selstartx;
|
int maxlen, selextend, selstartx;
|
||||||
|
|
||||||
/* number editing / dragging */
|
/* number editing / dragging */
|
||||||
|
/* coords are Window/uiBlock relative (depends on the button) */
|
||||||
int draglastx, draglasty;
|
int draglastx, draglasty;
|
||||||
int dragstartx, dragstarty;
|
int dragstartx, dragstarty;
|
||||||
int dragchange, draglock, dragsel;
|
int dragchange, draglock, dragsel;
|
||||||
@@ -5474,6 +5475,24 @@ static int ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can we mouse over the button or is it hidden/disabled/layout.
|
||||||
|
*/
|
||||||
|
bool ui_is_but_interactive(uiBut *but)
|
||||||
|
{
|
||||||
|
/* note, LABEL is included for highlights, this allows drags */
|
||||||
|
if (but->type == LABEL && but->dragpoin == NULL)
|
||||||
|
return false;
|
||||||
|
if (ELEM3(but->type, ROUNDBOX, SEPR, LISTBOX))
|
||||||
|
return false;
|
||||||
|
if (but->flag & UI_HIDDEN)
|
||||||
|
return false;
|
||||||
|
if (but->flag & UI_SCROLLED)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
|
uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
|
||||||
{
|
{
|
||||||
uiBlock *block;
|
uiBlock *block;
|
||||||
@@ -5491,17 +5510,11 @@ uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
|
|||||||
ui_window_to_block(ar, block, &mx, &my);
|
ui_window_to_block(ar, block, &mx, &my);
|
||||||
|
|
||||||
for (but = block->buttons.first; but; but = but->next) {
|
for (but = block->buttons.first; but; but = but->next) {
|
||||||
/* note, LABEL is included for highlights, this allows drags */
|
if (ui_is_but_interactive(but)) {
|
||||||
if (but->type == LABEL && but->dragpoin == NULL)
|
if (ui_but_contains_pt(but, mx, my)) {
|
||||||
continue;
|
butover = but;
|
||||||
if (ELEM3(but->type, ROUNDBOX, SEPR, LISTBOX))
|
}
|
||||||
continue;
|
}
|
||||||
if (but->flag & UI_HIDDEN)
|
|
||||||
continue;
|
|
||||||
if (but->flag & UI_SCROLLED)
|
|
||||||
continue;
|
|
||||||
if (ui_but_contains_pt(but, mx, my))
|
|
||||||
butover = but;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CLIP_EVENTS prevents the event from reaching other blocks */
|
/* CLIP_EVENTS prevents the event from reaching other blocks */
|
||||||
@@ -5843,12 +5856,13 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da
|
|||||||
|
|
||||||
/* redraw (data is but->active!) */
|
/* redraw (data is but->active!) */
|
||||||
ED_region_tag_redraw(data->region);
|
ED_region_tag_redraw(data->region);
|
||||||
|
|
||||||
/* clean up button */
|
/* clean up button */
|
||||||
if (but->active) {
|
if (but->active) {
|
||||||
MEM_freeN(but->active);
|
MEM_freeN(but->active);
|
||||||
but->active = NULL;
|
but->active = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
but->flag &= ~(UI_ACTIVE | UI_SELECT);
|
but->flag &= ~(UI_ACTIVE | UI_SELECT);
|
||||||
but->flag |= UI_BUT_LAST_ACTIVE;
|
but->flag |= UI_BUT_LAST_ACTIVE;
|
||||||
if (!onfree)
|
if (!onfree)
|
||||||
|
@@ -171,8 +171,8 @@ struct uiBut {
|
|||||||
char *str;
|
char *str;
|
||||||
char strdata[UI_MAX_NAME_STR];
|
char strdata[UI_MAX_NAME_STR];
|
||||||
char drawstr[UI_MAX_DRAW_STR];
|
char drawstr[UI_MAX_DRAW_STR];
|
||||||
|
|
||||||
rctf rect;
|
rctf rect; /* block relative coords */
|
||||||
|
|
||||||
char *poin;
|
char *poin;
|
||||||
float hardmin, hardmax, softmin, softmax;
|
float hardmin, hardmax, softmin, softmax;
|
||||||
@@ -225,7 +225,7 @@ struct uiBut {
|
|||||||
void *rename_orig;
|
void *rename_orig;
|
||||||
|
|
||||||
uiLink *link;
|
uiLink *link;
|
||||||
short linkto[2];
|
short linkto[2]; /* region relative coords */
|
||||||
|
|
||||||
const char *tip, *lockstr;
|
const char *tip, *lockstr;
|
||||||
|
|
||||||
@@ -410,6 +410,7 @@ extern int ui_is_but_bool(uiBut *but);
|
|||||||
extern int ui_is_but_unit(uiBut *but);
|
extern int ui_is_but_unit(uiBut *but);
|
||||||
extern int ui_is_but_rna_valid(uiBut *but);
|
extern int ui_is_but_rna_valid(uiBut *but);
|
||||||
extern int ui_is_but_utf8(uiBut *but);
|
extern int ui_is_but_utf8(uiBut *but);
|
||||||
|
extern bool ui_is_but_interactive(uiBut *but);
|
||||||
|
|
||||||
extern void ui_bounds_block(uiBlock *block);
|
extern void ui_bounds_block(uiBlock *block);
|
||||||
extern void ui_block_translate(uiBlock *block, int x, int y);
|
extern void ui_block_translate(uiBlock *block, int x, int y);
|
||||||
|
@@ -1081,64 +1081,46 @@ typedef struct DragOpInfo {
|
|||||||
eButType but_type_start;
|
eButType but_type_start;
|
||||||
} DragOpInfo;
|
} DragOpInfo;
|
||||||
|
|
||||||
typedef struct DragOpPlotData {
|
|
||||||
bContext *C;
|
|
||||||
ARegion *ar;
|
|
||||||
bool is_set;
|
|
||||||
eButType but_type_start;
|
|
||||||
bool do_draw;
|
|
||||||
const uiBut *but_prev;
|
|
||||||
} DragOpPlotData;
|
|
||||||
|
|
||||||
static const uiBut *ui_but_set_xy(bContext *C, ARegion *ar, const bool is_set, const eButType but_type_start,
|
|
||||||
const int xy[2], const uiBut *but_prev)
|
|
||||||
{
|
|
||||||
uiBut *but = ui_but_find_mouse_over(ar, xy[0], xy[1]);
|
|
||||||
|
|
||||||
if (but_prev == but) {
|
|
||||||
return but_prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (but && ui_is_but_bool(but) && but->type == but_type_start) {
|
|
||||||
/* is it pressed? */
|
|
||||||
bool is_set_but = (ui_get_but_val(but) != 0.0);
|
|
||||||
BLI_assert(ui_is_but_bool(but) == true);
|
|
||||||
if (is_set_but != is_set) {
|
|
||||||
uiButExecute(C, but);
|
|
||||||
return but;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return but_prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ui_but_set_cb(int x, int y, void *data_v)
|
|
||||||
{
|
|
||||||
DragOpPlotData *data = data_v;
|
|
||||||
int xy[2] = {x, y};
|
|
||||||
data->but_prev = ui_but_set_xy(data->C, data->ar, data->is_set, data->but_type_start, xy, data->but_prev);
|
|
||||||
return 1; /* keep going */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* operates on buttons between 2 mouse-points */
|
|
||||||
static bool ui_but_set_xy_xy(bContext *C, ARegion *ar, const bool is_set, const eButType but_type_start,
|
static bool ui_but_set_xy_xy(bContext *C, ARegion *ar, const bool is_set, const eButType but_type_start,
|
||||||
const int xy_src[2], const int xy_dst[2])
|
const int xy_src[2], const int xy_dst[2])
|
||||||
{
|
{
|
||||||
DragOpPlotData data;
|
bool change = false;
|
||||||
data.C = C;
|
uiBlock *block;
|
||||||
data.ar = ar;
|
|
||||||
data.is_set = is_set;
|
|
||||||
data.but_type_start = but_type_start;
|
|
||||||
data.do_draw = false;
|
|
||||||
data.but_prev = NULL;
|
|
||||||
|
|
||||||
|
for (block = ar->uiblocks.first; block; block = block->next) {
|
||||||
|
uiBut *but;
|
||||||
|
|
||||||
/* prevent dragging too fast loosing buttons */
|
float xy_a_block[2] = {UNPACK2(xy_src)};
|
||||||
plot_line_v2v2i(xy_src, xy_dst, ui_but_set_cb, &data);
|
float xy_b_block[2] = {UNPACK2(xy_dst)};
|
||||||
|
|
||||||
return data.do_draw;
|
ui_window_to_block_fl(ar, block, &xy_a_block[0], &xy_a_block[1]);
|
||||||
|
ui_window_to_block_fl(ar, block, &xy_b_block[0], &xy_b_block[1]);
|
||||||
|
|
||||||
|
for (but = block->buttons.first; but; but = but->next) {
|
||||||
|
if (ui_is_but_interactive(but)) {
|
||||||
|
if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) {
|
||||||
|
|
||||||
|
/* execute the button */
|
||||||
|
if (ui_is_but_bool(but) && but->type == but_type_start) {
|
||||||
|
/* is it pressed? */
|
||||||
|
bool is_set_but = (ui_get_but_val(but) != 0.0);
|
||||||
|
BLI_assert(ui_is_but_bool(but) == true);
|
||||||
|
if (is_set_but != is_set) {
|
||||||
|
uiButExecute(C, but);
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* done */
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ui_drag_but_set(bContext *C, wmOperator *op, const int xy_input[2])
|
static void ui_drag_but_set(bContext *C, wmOperator *op, const int xy_input[2])
|
||||||
{
|
{
|
||||||
ARegion *ar = CTX_wm_region(C);
|
ARegion *ar = CTX_wm_region(C);
|
||||||
@@ -1307,4 +1289,3 @@ void UI_buttons_operatortypes(void)
|
|||||||
WM_operatortype_append(UI_OT_reloadtranslation);
|
WM_operatortype_append(UI_OT_reloadtranslation);
|
||||||
WM_operatortype_append(UI_OT_drag_toggle);
|
WM_operatortype_append(UI_OT_drag_toggle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user