Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-11-02 07:44:33 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-11-02 07:45:19 +0300
commit4a85089abe6d5abb9f6bb0d8255eba33dc030fcb (patch)
tree25459e54af9cf6712ca349b924319939ba853909 /source/blender/editors
parentcf6e45b5224d16263d7c87411a2ff71ed928410f (diff)
parent765e28948e706d8fce97c23d4d050a607971488b (diff)
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/animation/drivers.c1
-rw-r--r--source/blender/editors/animation/keyframing.c1
-rw-r--r--source/blender/editors/armature/armature_add.c10
-rw-r--r--source/blender/editors/armature/armature_intern.h1
-rw-r--r--source/blender/editors/armature/armature_utils.c10
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c5
-rw-r--r--source/blender/editors/armature/pose_transform.c6
-rw-r--r--source/blender/editors/armature/pose_utils.c4
-rw-r--r--source/blender/editors/curve/editcurve.c2
-rw-r--r--source/blender/editors/include/ED_armature.h5
-rw-r--r--source/blender/editors/include/UI_interface.h11
-rw-r--r--source/blender/editors/interface/interface.c10
-rw-r--r--source/blender/editors/interface/interface_handlers.c67
-rw-r--r--source/blender/editors/interface/interface_intern.h4
-rw-r--r--source/blender/editors/interface/interface_layout.c52
-rw-r--r--source/blender/editors/interface/interface_regions.c21
-rw-r--r--source/blender/editors/interface/interface_widgets.c151
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c7
18 files changed, 291 insertions, 77 deletions
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index dde531a6193..2d04f73c4ac 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -104,6 +104,7 @@ FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_inde
fcu = MEM_callocN(sizeof(FCurve), "FCurve");
fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
+ fcu->auto_smoothing = FCURVE_SMOOTH_CONT_ACCEL;
/* store path - make copy, and store that */
fcu->rna_path = BLI_strdup(rna_path);
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 93ce45e1e8f..afbd8e5bd41 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -188,6 +188,7 @@ FCurve *verify_fcurve(bAction *act, const char group[], PointerRNA *ptr,
fcu = MEM_callocN(sizeof(FCurve), "FCurve");
fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
+ fcu->auto_smoothing = FCURVE_SMOOTH_CONT_ACCEL;
if (BLI_listbase_is_empty(&act->curves))
fcu->flag |= FCURVE_ACTIVE; /* first one added active */
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index cff161d9d93..e419100bd04 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -77,19 +77,20 @@ EditBone *ED_armature_edit_bone_add(bArmature *arm, const char *name)
bone->dist = 0.25f;
bone->xwidth = 0.1f;
bone->zwidth = 0.1f;
- bone->ease1 = 1.0f;
- bone->ease2 = 1.0f;
bone->rad_head = 0.10f;
bone->rad_tail = 0.05f;
bone->segments = 1;
bone->layer = arm->layer;
+ /* Bendy-Bone parameters */
bone->roll1 = 0.0f;
bone->roll2 = 0.0f;
bone->curveInX = 0.0f;
bone->curveInY = 0.0f;
bone->curveOutX = 0.0f;
bone->curveOutY = 0.0f;
+ bone->ease1 = 1.0f;
+ bone->ease2 = 1.0f;
bone->scaleIn = 1.0f;
bone->scaleOut = 1.0f;
@@ -899,19 +900,20 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
newbone->dist = ebone->dist;
newbone->xwidth = ebone->xwidth;
newbone->zwidth = ebone->zwidth;
- newbone->ease1 = ebone->ease1;
- newbone->ease2 = ebone->ease2;
newbone->rad_head = ebone->rad_tail; // don't copy entire bone...
newbone->rad_tail = ebone->rad_tail;
newbone->segments = 1;
newbone->layer = ebone->layer;
+ /* Bendy-Bone parameters */
newbone->roll1 = ebone->roll1;
newbone->roll2 = ebone->roll2;
newbone->curveInX = ebone->curveInX;
newbone->curveInY = ebone->curveInY;
newbone->curveOutX = ebone->curveOutX;
newbone->curveOutY = ebone->curveOutY;
+ newbone->ease1 = ebone->ease1;
+ newbone->ease2 = ebone->ease2;
newbone->scaleIn = ebone->scaleIn;
newbone->scaleOut = ebone->scaleOut;
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index 8c1083dc290..89839af2ae0 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -173,6 +173,7 @@ typedef struct tPChanFCurveLink {
float roll1, roll2; /* old bbone values (to be restored along with the transform properties) */
float curveInX, curveInY; /* (NOTE: we haven't renamed these this time, as their names are already long enough) */
float curveOutX, curveOutY;
+ float ease1, ease2;
float scaleIn, scaleOut;
struct IDProperty *oldprops; /* copy of custom properties at start of operator (to be restored before each modal step) */
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index a2663cdd935..f27c4fdd96f 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -463,19 +463,20 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone
eBone->weight = curBone->weight;
eBone->xwidth = curBone->xwidth;
eBone->zwidth = curBone->zwidth;
- eBone->ease1 = curBone->ease1;
- eBone->ease2 = curBone->ease2;
eBone->rad_head = curBone->rad_head;
eBone->rad_tail = curBone->rad_tail;
eBone->segments = curBone->segments;
eBone->layer = curBone->layer;
+ /* Bendy-Bone parameters */
eBone->roll1 = curBone->roll1;
eBone->roll2 = curBone->roll2;
eBone->curveInX = curBone->curveInX;
eBone->curveInY = curBone->curveInY;
eBone->curveOutX = curBone->curveOutX;
eBone->curveOutY = curBone->curveOutY;
+ eBone->ease1 = curBone->ease1;
+ eBone->ease2 = curBone->ease2;
eBone->scaleIn = curBone->scaleIn;
eBone->scaleOut = curBone->scaleOut;
@@ -627,19 +628,20 @@ void ED_armature_from_edit(bArmature *arm)
newBone->xwidth = eBone->xwidth;
newBone->zwidth = eBone->zwidth;
- newBone->ease1 = eBone->ease1;
- newBone->ease2 = eBone->ease2;
newBone->rad_head = eBone->rad_head;
newBone->rad_tail = eBone->rad_tail;
newBone->segments = eBone->segments;
newBone->layer = eBone->layer;
+ /* Bendy-Bone parameters */
newBone->roll1 = eBone->roll1;
newBone->roll2 = eBone->roll2;
newBone->curveInX = eBone->curveInX;
newBone->curveInY = eBone->curveInY;
newBone->curveOutX = eBone->curveOutX;
newBone->curveOutY = eBone->curveOutY;
+ newBone->ease1 = eBone->ease1;
+ newBone->ease2 = eBone->ease2;
newBone->scaleIn = eBone->scaleIn;
newBone->scaleOut = eBone->scaleOut;
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index fa7bf6e7ad4..2fb216c2ef8 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -1444,19 +1444,20 @@ static EditBone *add_editbonetolist(char *name, ListBase *list)
bone->dist = 0.25F;
bone->xwidth = 0.1;
bone->zwidth = 0.1;
- bone->ease1 = 1.0;
- bone->ease2 = 1.0;
bone->rad_head = 0.10;
bone->rad_tail = 0.05;
bone->segments = 1;
bone->layer = 1; //arm->layer;
+ /* Bendy-Bone parameters */
bone->roll1 = 0.0f;
bone->roll2 = 0.0f;
bone->curveInX = 0.0f;
bone->curveInY = 0.0f;
bone->curveOutX = 0.0f;
bone->curveOutY = 0.0f;
+ bone->ease1 = 1.0f;
+ bone->ease2 = 1.0f;
bone->scaleIn = 1.0f;
bone->scaleOut = 1.0f;
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index 49e16794588..948c7803420 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -362,6 +362,8 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo
pchan->roll1 = chan->roll1;
pchan->roll2 = chan->roll2;
+ pchan->ease1 = chan->ease1;
+ pchan->ease2 = chan->ease2;
pchan->scaleIn = chan->scaleIn;
pchan->scaleOut = chan->scaleOut;
@@ -584,6 +586,8 @@ static void pchan_clear_scale(bPoseChannel *pchan)
if ((pchan->protectflag & OB_LOCK_SCALEZ) == 0)
pchan->size[2] = 1.0f;
+ pchan->ease1 = 0.0f;
+ pchan->ease2 = 0.0f;
pchan->scaleIn = 1.0f;
pchan->scaleOut = 1.0f;
}
@@ -742,7 +746,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
/* clear any unkeyed tags */
if (pchan->bone)
pchan->bone->flag &= ~BONE_UNKEYED;
-
+
/* tag for autokeying later */
autokey = 1;
}
diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c
index b17cc286333..acb9363cf10 100644
--- a/source/blender/editors/armature/pose_utils.c
+++ b/source/blender/editors/armature/pose_utils.c
@@ -115,6 +115,8 @@ static void fcurves_to_pchan_links_get(ListBase *pfLinks, Object *ob, bAction *a
pfl->curveInY = pchan->curveInY;
pfl->curveOutX = pchan->curveOutX;
pfl->curveOutY = pchan->curveOutY;
+ pfl->ease1 = pchan->ease1;
+ pfl->ease2 = pchan->ease2;
pfl->scaleIn = pchan->scaleIn;
pfl->scaleOut = pchan->scaleOut;
@@ -223,6 +225,8 @@ void poseAnim_mapping_reset(ListBase *pfLinks)
pchan->curveInY = pfl->curveInY;
pchan->curveOutX = pfl->curveOutX;
pchan->curveOutY = pfl->curveOutY;
+ pchan->ease1 = pfl->ease1;
+ pchan->ease2 = pfl->ease2;
pchan->scaleIn = pfl->scaleIn;
pchan->scaleOut = pfl->scaleOut;
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 565521ad111..85715bf575b 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -595,7 +595,7 @@ static void calc_keyHandles(ListBase *nurb, float *key)
if (nextp) key_to_bezt(nextfp, nextp, &next);
if (prevp) key_to_bezt(prevfp, prevp, &prev);
- BKE_nurb_handle_calc(&cur, prevp ? &prev : NULL, nextp ? &next : NULL, 0);
+ BKE_nurb_handle_calc(&cur, prevp ? &prev : NULL, nextp ? &next : NULL, 0, 0);
bezt_to_key(&cur, fp);
prevp = bezt;
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index d65ea8e79f0..6ce86f082b0 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -75,12 +75,15 @@ typedef struct EditBone {
float dist, weight;
float xwidth, length, zwidth; /* put them in order! transform uses this as scale */
- float ease1, ease2;
float rad_head, rad_tail;
+
+ /* Bendy-Bone parameters */
float roll1, roll2;
float curveOutX, curveOutY;
float curveInX, curveInY;
+ float ease1, ease2;
float scaleIn, scaleOut;
+
float oldlength; /* for envelope scaling */
short segments;
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index b30d71941d6..de6d9d78974 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -136,6 +136,7 @@ enum {
/* block->flag bits 14-17 are identical to but->drawflag bits */
+#define UI_BLOCK_POPUP_HOLD (1 << 18)
#define UI_BLOCK_LIST_ITEM (1 << 19)
#define UI_BLOCK_RADIAL (1 << 20)
@@ -359,6 +360,7 @@ typedef struct uiSearchItems uiSearchItems;
typedef void (*uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2);
typedef void (*uiButHandleRenameFunc)(struct bContext *C, void *arg, char *origstr);
typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2);
+typedef void (*uiButHandleHoldFunc)(struct bContext *C, struct ARegion *butregion, uiBut *but);
typedef int (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
typedef struct ARegion *(*uiButSearchCreateFunc)(struct bContext *C, struct ARegion *butregion, uiBut *but);
typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items);
@@ -400,6 +402,7 @@ void UI_popup_menu_reports(struct bContext *C, struct ReportList *reports) ATTR_
int UI_popup_menu_invoke(struct bContext *C, const char *idname, struct ReportList *reports) ATTR_NONNULL(1, 2);
void UI_popup_menu_retval_set(const uiBlock *block, const int retval, const bool enable);
+void UI_popup_menu_but_set(uiPopupMenu *pup, struct ARegion *butregion, uiBut *but);
/* Pie menus */
typedef struct uiPieMenu uiPieMenu;
@@ -731,6 +734,8 @@ bool UI_textbutton_activate_but(const struct bContext *C, uiBut *but);
void UI_but_focus_on_enter_event(struct wmWindow *win, uiBut *but);
+void UI_but_func_hold_set(uiBut *but, uiButHandleHoldFunc func, void *argN);
+
/* Autocomplete
*
* Tab complete helper functions, for use in uiButCompleteFunc callbacks.
@@ -831,6 +836,7 @@ void UI_exit(void);
#define UI_ITEM_R_FULL_EVENT (1 << 6)
#define UI_ITEM_R_NO_BG (1 << 7)
#define UI_ITEM_R_IMMEDIATE (1 << 8)
+#define UI_ITEM_O_DEPRESS (1 << 9)
/* uiTemplateOperatorPropertyButs flags */
#define UI_TEMPLATE_OP_PROPS_SHOW_TITLE 1
@@ -1005,6 +1011,11 @@ void uiItemFullO(
uiLayout *layout, const char *idname, const char *name, int icon,
struct IDProperty *properties, int context, int flag,
PointerRNA *r_opptr);
+void uiItemFullOMenuHold_ptr(
+ uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon,
+ struct IDProperty *properties, int context, int flag,
+ const char *menu_id, /* extra menu arg. */
+ PointerRNA *r_opptr);
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon);
void uiItemFullR(uiLayout *layout, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, int value, int flag, const char *name, int icon);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 96273f5e83c..0d166b874cb 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -2678,6 +2678,10 @@ static void ui_but_free(const bContext *C, uiBut *but)
MEM_freeN(but->tip_argN);
}
+ if (but->hold_argN) {
+ MEM_freeN(but->hold_argN);
+ }
+
if (!but->editstr && but->free_search_arg) {
MEM_SAFE_FREE(but->search_arg);
}
@@ -4532,6 +4536,12 @@ void UI_but_focus_on_enter_event(wmWindow *win, uiBut *but)
wm_event_add(win, &event);
}
+void UI_but_func_hold_set(uiBut *but, uiButHandleHoldFunc func, void *argN)
+{
+ but->hold_func = func;
+ but->hold_argN = argN;
+}
+
void UI_but_string_info_get(bContext *C, uiBut *but, ...)
{
va_list args;
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index bb813f399d6..09b79c19ae5 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -305,6 +305,9 @@ typedef struct uiHandleButtonData {
bool used_mouse;
wmTimer *autoopentimer;
+ /* auto open (hold) */
+ wmTimer *hold_action_timer;
+
/* text selection/editing */
/* size of 'str' (including terminator) */
int maxlen;
@@ -7809,6 +7812,15 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
data->flashtimer = NULL;
}
+ /* add hold timer if it's used */
+ if (state == BUTTON_STATE_WAIT_RELEASE && (but->hold_func != NULL)) {
+ data->hold_action_timer = WM_event_add_timer(data->wm, data->window, TIMER, BUTTON_AUTO_OPEN_THRESH);
+ }
+ else if (data->hold_action_timer) {
+ WM_event_remove_timer(data->wm, data->window, data->hold_action_timer);
+ data->hold_action_timer = NULL;
+ }
+
/* add a blocking ui handler at the window handler for blocking, modal states
* but not for popups, because we already have a window level handler*/
if (!(but->block->handle && but->block->handle->popup)) {
@@ -8423,6 +8435,25 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
button_activate_state(C, but, BUTTON_STATE_EXIT);
break;
+ case TIMER:
+ {
+ if (event->customdata == data->hold_action_timer) {
+ if (true) {
+ data->cancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else {
+ /* Do this so we can still mouse-up, closing the menu and running the button.
+ * This is nice to support but there are times when the button gets left pressed.
+ * Keep disavled for now. */
+ WM_event_remove_timer(data->wm, data->window, data->hold_action_timer);
+ data->hold_action_timer = NULL;
+ }
+ retval = WM_UI_HANDLER_CONTINUE;
+ but->hold_func(C, data->region, but);
+ }
+ break;
+ }
case MOUSEMOVE:
if (ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK)) {
but->flag |= UI_SELECT;
@@ -9349,21 +9380,29 @@ static int ui_handle_menu_event(
if (inside == 0) {
uiSafetyRct *saferct = block->saferct.first;
- if (ELEM(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) &&
- ELEM(event->val, KM_PRESS, KM_DBL_CLICK))
- {
- if ((is_parent_menu == false) && (U.uiflag & USER_MENUOPENAUTO) == 0) {
- /* for root menus, allow clicking to close */
- if (block->flag & (UI_BLOCK_OUT_1))
- menu->menuretval = UI_RETURN_OK;
- else
- menu->menuretval = UI_RETURN_OUT;
+ if (ELEM(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE)) {
+ if (ELEM(event->val, KM_PRESS, KM_DBL_CLICK)) {
+ if ((is_parent_menu == false) && (U.uiflag & USER_MENUOPENAUTO) == 0) {
+ /* for root menus, allow clicking to close */
+ if (block->flag & (UI_BLOCK_OUT_1))
+ menu->menuretval = UI_RETURN_OK;
+ else
+ menu->menuretval = UI_RETURN_OUT;
+ }
+ else if (saferct && !BLI_rctf_isect_pt(&saferct->parent, event->x, event->y)) {
+ if (block->flag & (UI_BLOCK_OUT_1))
+ menu->menuretval = UI_RETURN_OK;
+ else
+ menu->menuretval = UI_RETURN_OUT;
+ }
}
- else if (saferct && !BLI_rctf_isect_pt(&saferct->parent, event->x, event->y)) {
- if (block->flag & (UI_BLOCK_OUT_1))
- menu->menuretval = UI_RETURN_OK;
- else
- menu->menuretval = UI_RETURN_OUT;
+ else if (ELEM(event->val, KM_RELEASE, KM_CLICK)) {
+ /* For buttons that use a hold function, exit when mouse-up outside the menu. */
+ if (block->flag & UI_BLOCK_POPUP_HOLD) {
+ /* Note, we could check the cursor is over the parent button. */
+ menu->menuretval = UI_RETURN_CANCEL;
+ retval = WM_UI_HANDLER_CONTINUE;
+ }
}
}
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 2abb8dcf20f..983653675d6 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -266,6 +266,10 @@ struct uiBut {
void *rename_arg1;
void *rename_orig;
+ /* Run an action when holding the button down. */
+ uiButHandleHoldFunc hold_func;
+ void *hold_argN;
+
uiLink *link;
short linkto[2]; /* region relative coords */
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 1ac54d5353d..212cd462aef 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -795,7 +795,7 @@ static void ui_item_disabled(uiLayout *layout, const char *name)
* \param r_opptr: Optional, initialize with operator properties when not NULL.
* Will always be written to even in the case of errors.
*/
-void uiItemFullO_ptr(
+static uiBut *uiItemFullO_ptr_ex(
uiLayout *layout, wmOperatorType *ot,
const char *name, int icon, IDProperty *properties, int context, int flag,
PointerRNA *r_opptr)
@@ -845,6 +845,10 @@ void uiItemFullO_ptr(
if (flag & UI_ITEM_R_NO_BG)
UI_block_emboss_set(block, UI_EMBOSS);
+ if (flag & UI_ITEM_O_DEPRESS) {
+ but->flag |= UI_SELECT;
+ }
+
if (layout->redalert)
UI_but_flag_enable(but, UI_BUT_REDALERT);
@@ -862,6 +866,50 @@ void uiItemFullO_ptr(
*r_opptr = *opptr;
}
}
+
+ return but;
+}
+
+static void ui_item_hold_menu(struct bContext *C, ARegion *butregion, uiBut *but)
+{
+ uiPopupMenu *pup = UI_popup_menu_begin(C, "", ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
+ uiBlock *block = layout->root->block;
+ UI_popup_menu_but_set(pup, butregion, but);
+
+ block->flag |= UI_BLOCK_POPUP_HOLD;
+
+ const char *menu_id = but->hold_argN;
+ MenuType *mt = WM_menutype_find(menu_id, true);
+ if (mt) {
+ Menu menu = {NULL};
+ menu.layout = layout;
+ menu.type = mt;
+ mt->draw(C, &menu);
+ }
+ else {
+ uiItemL(layout, "Menu Missing:", ICON_NONE);
+ uiItemL(layout, menu_id, ICON_NONE);
+ }
+ UI_popup_menu_end(C, pup);
+}
+
+void uiItemFullO_ptr(
+ uiLayout *layout, wmOperatorType *ot,
+ const char *name, int icon, IDProperty *properties, int context, int flag,
+ PointerRNA *r_opptr)
+{
+ uiItemFullO_ptr_ex(layout, ot, name, icon, properties, context, flag, r_opptr);
+}
+
+void uiItemFullOMenuHold_ptr(
+ uiLayout *layout, wmOperatorType *ot,
+ const char *name, int icon, IDProperty *properties, int context, int flag,
+ const char *menu_id,
+ PointerRNA *r_opptr)
+{
+ uiBut *but = uiItemFullO_ptr_ex(layout, ot, name, icon, properties, context, flag, r_opptr);
+ UI_but_func_hold_set(but, ui_item_hold_menu, BLI_strdup(menu_id));
}
void uiItemFullO(
@@ -875,7 +923,7 @@ void uiItemFullO(
ot, opname, {
if (r_opptr) {
*r_opptr = PointerRNA_NULL;
- };
+ }
return;
});
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index aabb165b483..cd3aa2095b0 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -2635,6 +2635,7 @@ struct uiPopupMenu {
uiBlock *block;
uiLayout *layout;
uiBut *but;
+ ARegion *butregion;
int mx, my;
bool popup, slideout;
@@ -2881,17 +2882,33 @@ uiPopupMenu *UI_popup_menu_begin(bContext *C, const char *title, int icon)
return UI_popup_menu_begin_ex(C, title, __func__, icon);
}
+/**
+ * Setting the button makes the popup open from the button instead of the cursor.
+ */
+void UI_popup_menu_but_set(uiPopupMenu *pup, struct ARegion *butregion, uiBut *but)
+{
+ pup->but = but;
+ pup->butregion = butregion;
+}
+
/* set the whole structure to work */
void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
{
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *menu;
+ uiBut *but = NULL;
+ ARegion *butregion = NULL;
pup->popup = true;
pup->mx = window->eventstate->x;
pup->my = window->eventstate->y;
-
- menu = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_POPUP, pup);
+
+ if (pup->but) {
+ but = pup->but;
+ butregion = pup->butregion;
+ }
+
+ menu = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup);
menu->popup = true;
UI_popup_handlers_add(C, &window->modalhandlers, menu, 0);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index e3977219eda..f419ab2d1ed 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -66,6 +66,15 @@
/* icons are 80% of height of button (16 pixels inside 20 height) */
#define ICON_SIZE_FROM_BUTRECT(rect) (0.8f * BLI_rcti_size_y(rect))
+#define UI_BUT_FLAGS_PUBLIC \
+ (UI_SELECT | UI_SCROLLED | UI_ACTIVE | UI_HAS_ICON | UI_TEXTINPUT | UI_HIDDEN)
+
+/* Bits 0..5 are from UI_SELECT .. etc */
+enum {
+ /* Show that holding the button opens a menu. */
+ UI_STATE_HOLD_ACTION = (1 << 6),
+};
+
/* ************** widget base functions ************** */
/**
* - in: roundbox codes for corner types and radius
@@ -145,45 +154,54 @@ static const float jit[WIDGET_AA_JITTER][2] = {
{-0.272855, 0.269918}, { 0.095909, 0.388710}
};
-static const float num_tria_vert[3][2] = {
+/* -------------------------------------------------------------------- */
+/** \name Shape Preset Data
+ * \{ */
+
+static const float g_shape_preset_number_arrow_vert[3][2] = {
{-0.352077, 0.532607}, {-0.352077, -0.549313}, {0.330000, -0.008353}
};
-
-static const unsigned int num_tria_face[1][3] = {
+static const uint g_shape_preset_number_arrow_face[1][3] = {
{0, 1, 2}
};
-static const float scroll_circle_vert[16][2] = {
+static const float g_shape_preset_scroll_circle_vert[16][2] = {
{0.382684, 0.923879}, {0.000001, 1.000000}, {-0.382683, 0.923880}, {-0.707107, 0.707107},
{-0.923879, 0.382684}, {-1.000000, 0.000000}, {-0.923880, -0.382684}, {-0.707107, -0.707107},
{-0.382683, -0.923880}, {0.000000, -1.000000}, {0.382684, -0.923880}, {0.707107, -0.707107},
{0.923880, -0.382684}, {1.000000, -0.000000}, {0.923880, 0.382683}, {0.707107, 0.707107}
};
-
-static const unsigned int scroll_circle_face[14][3] = {
+static const uint g_shape_preset_scroll_circle_face[14][3] = {
{0, 1, 2}, {2, 0, 3}, {3, 0, 15}, {3, 15, 4}, {4, 15, 14}, {4, 14, 5}, {5, 14, 13}, {5, 13, 6},
{6, 13, 12}, {6, 12, 7}, {7, 12, 11}, {7, 11, 8}, {8, 11, 10}, {8, 10, 9}
};
-
-static const float menu_tria_vert[6][2] = {
+static const float g_shape_preset_menu_arrow_vert[6][2] = {
{-0.33, 0.16}, {0.33, 0.16}, {0, 0.82},
{0, -0.82}, {-0.33, -0.16}, {0.33, -0.16}
};
+static const uint g_shape_preset_menu_arrow_face[2][3] = {{2, 0, 1}, {3, 5, 4}};
-
-
-static const unsigned int menu_tria_face[2][3] = {{2, 0, 1}, {3, 5, 4}};
-
-static const float check_tria_vert[6][2] = {
+static const float g_shape_preset_checkmark_vert[6][2] = {
{-0.578579, 0.253369}, {-0.392773, 0.412794}, {-0.004241, -0.328551},
{-0.003001, 0.034320}, {1.055313, 0.864744}, {0.866408, 1.026895}
};
-static const unsigned int check_tria_face[4][3] = {
+static const uint g_shape_preset_checkmark_face[4][3] = {
{3, 2, 4}, {3, 4, 5}, {1, 0, 3}, {0, 2, 3}
};
+#define OY -0.2
+#define SC 0.35
+static const float g_shape_preset_hold_action_vert[6][2] = {
+ {-0.5 + SC, 1.0 + OY}, {0.5, 1.0 + OY}, {0.5, 0.0 + OY + SC},
+};
+static const uint g_shape_preset_hold_action_face[2][3] = {{2, 0, 1}, {3, 5, 4}};
+#undef OY
+#undef SC
+
+/** \} */
+
/* ************************************************* */
void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3,
@@ -490,9 +508,12 @@ static void round_box_edges(uiWidgetBase *wt, int roundboxalign, const rcti *rec
round_box__edges(wt, roundboxalign, rect, rad, rad - U.pixelsize);
}
+/* -------------------------------------------------------------------- */
+/** \name Shape Preset Mini API
+ * \{ */
/* based on button rect, return scaled array of triangles */
-static void widget_draw_tria_ex(
+static void shape_preset_init_trias_ex(
uiWidgetTrias *tria, const rcti *rect, float triasize, char where,
/* input data */
const float verts[][2], const int verts_tot,
@@ -531,23 +552,31 @@ static void widget_draw_tria_ex(
tria->index = tris;
}
-static void widget_num_tria(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
+static void shape_preset_init_number_arrows(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
+{
+ shape_preset_init_trias_ex(
+ tria, rect, triasize, where,
+ g_shape_preset_number_arrow_vert, ARRAY_SIZE(g_shape_preset_number_arrow_vert),
+ g_shape_preset_number_arrow_face, ARRAY_SIZE(g_shape_preset_number_arrow_face));
+}
+
+static void shape_preset_init_hold_action(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
{
- widget_draw_tria_ex(
+ shape_preset_init_trias_ex(
tria, rect, triasize, where,
- num_tria_vert, ARRAY_SIZE(num_tria_vert),
- num_tria_face, ARRAY_SIZE(num_tria_face));
+ g_shape_preset_hold_action_vert, ARRAY_SIZE(g_shape_preset_hold_action_vert),
+ g_shape_preset_hold_action_face, ARRAY_SIZE(g_shape_preset_hold_action_face));
}
-static void widget_scroll_circle(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
+static void shape_preset_init_scroll_circle(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
{
- widget_draw_tria_ex(
+ shape_preset_init_trias_ex(
tria, rect, triasize, where,
- scroll_circle_vert, ARRAY_SIZE(scroll_circle_vert),
- scroll_circle_face, ARRAY_SIZE(scroll_circle_face));
+ g_shape_preset_scroll_circle_vert, ARRAY_SIZE(g_shape_preset_scroll_circle_vert),
+ g_shape_preset_scroll_circle_face, ARRAY_SIZE(g_shape_preset_scroll_circle_face));
}
-static void widget_trias_draw(uiWidgetTrias *tria, unsigned int pos)
+static void shape_preset_draw_trias(uiWidgetTrias *tria, uint pos)
{
immBegin(GWN_PRIM_TRIS, tria->tot * 3);
for (int i = 0; i < tria->tot; ++i)
@@ -570,7 +599,7 @@ static void widget_draw_vertex_buffer(unsigned int pos, unsigned int col, int mo
immEnd();
}
-static void widget_menu_trias(uiWidgetTrias *tria, const rcti *rect)
+static void shape_preset_trias_from_rect_menu(uiWidgetTrias *tria, const rcti *rect)
{
float centx, centy, size;
int a;
@@ -581,15 +610,15 @@ static void widget_menu_trias(uiWidgetTrias *tria, const rcti *rect)
size = 0.4f * BLI_rcti_size_y(rect);
for (a = 0; a < 6; a++) {
- tria->vec[a][0] = size * menu_tria_vert[a][0] + centx;
- tria->vec[a][1] = size * menu_tria_vert[a][1] + centy;
+ tria->vec[a][0] = size * g_shape_preset_menu_arrow_vert[a][0] + centx;
+ tria->vec[a][1] = size * g_shape_preset_menu_arrow_vert[a][1] + centy;
}
tria->tot = 2;
- tria->index = menu_tria_face;
+ tria->index = g_shape_preset_menu_arrow_face;
}
-static void widget_check_trias(uiWidgetTrias *tria, const rcti *rect)
+static void shape_preset_trias_from_rect_checkmark(uiWidgetTrias *tria, const rcti *rect)
{
float centx, centy, size;
int a;
@@ -600,14 +629,16 @@ static void widget_check_trias(uiWidgetTrias *tria, const rcti *rect)
size = 0.5f * BLI_rcti_size_y(rect);
for (a = 0; a < 6; a++) {
- tria->vec[a][0] = size * check_tria_vert[a][0] + centx;
- tria->vec[a][1] = size * check_tria_vert[a][1] + centy;
+ tria->vec[a][0] = size * g_shape_preset_checkmark_vert[a][0] + centx;
+ tria->vec[a][1] = size * g_shape_preset_checkmark_vert[a][1] + centy;
}
tria->tot = 4;
- tria->index = check_tria_face;
+ tria->index = g_shape_preset_checkmark_face;
}
+/** \} */
+
/* prepares shade colors */
static void shadecolors4(char coltop[4], char coldown[4], const char *color, short shadetop, short shadedown)
@@ -805,11 +836,11 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
gpuTranslate2fv(jit[j]);
if (wtb->tria1.tot)
- widget_trias_draw(&wtb->tria1, pos);
+ shape_preset_draw_trias(&wtb->tria1, pos);
if (wtb->tria2.tot)
- widget_trias_draw(&wtb->tria2, pos);
-
+ shape_preset_draw_trias(&wtb->tria2, pos);
+
gpuTranslate2f(-jit[j][0], -jit[j][1]);
}
@@ -2742,8 +2773,8 @@ static void widget_numbut_draw(uiWidgetColors *wcol, rcti *rect, int state, int
/* decoration */
if (!(state & UI_TEXTINPUT)) {
- widget_num_tria(&wtb.tria1, rect, 0.6f, 'l');
- widget_num_tria(&wtb.tria2, rect, 0.6f, 'r');
+ shape_preset_init_number_arrows(&wtb.tria1, rect, 0.6f, 'l');
+ shape_preset_init_number_arrows(&wtb.tria2, rect, 0.6f, 'r');
}
widgetbase_draw(&wtb, wcol);
@@ -2885,12 +2916,12 @@ void UI_draw_widget_scroll(uiWidgetColors *wcol, const rcti *rect, const rcti *s
wcol->item[3] = 255;
if (horizontal) {
- widget_scroll_circle(&wtb.tria1, slider, 0.6f, 'l');
- widget_scroll_circle(&wtb.tria2, slider, 0.6f, 'r');
+ shape_preset_init_scroll_circle(&wtb.tria1, slider, 0.6f, 'l');
+ shape_preset_init_scroll_circle(&wtb.tria2, slider, 0.6f, 'r');
}
else {
- widget_scroll_circle(&wtb.tria1, slider, 0.6f, 'b');
- widget_scroll_circle(&wtb.tria2, slider, 0.6f, 't');
+ shape_preset_init_scroll_circle(&wtb.tria1, slider, 0.6f, 'b');
+ shape_preset_init_scroll_circle(&wtb.tria2, slider, 0.6f, 't');
}
}
widgetbase_draw(&wtb, wcol);
@@ -3233,7 +3264,7 @@ static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
round_box_edges(&wtb, roundboxalign, rect, rad);
/* decoration */
- widget_menu_trias(&wtb.tria1, rect);
+ shape_preset_trias_from_rect_menu(&wtb.tria1, rect);
widgetbase_draw(&wtb, wcol);
@@ -3372,7 +3403,7 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN
/* decoration */
if (state & UI_SELECT) {
- widget_check_trias(&wtb.tria1, &recttemp);
+ shape_preset_trias_from_rect_checkmark(&wtb.tria1, &recttemp);
}
widgetbase_draw(&wtb, wcol);
@@ -3455,6 +3486,7 @@ static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int
widgetbase_draw(&wtb, wcol);
}
+#if 0
static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
uiWidgetBase wtb;
@@ -3467,6 +3499,25 @@ static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
widgetbase_draw(&wtb, wcol);
}
+#endif
+
+static void widget_roundbut_exec(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+{
+ uiWidgetBase wtb;
+ const float rad = 0.25f * U.widget_unit;
+
+ widget_init(&wtb);
+
+ if (state & UI_STATE_HOLD_ACTION) {
+ /* Show that keeping pressed performs another action (typically a menu). */
+ shape_preset_init_hold_action(&wtb.tria1, rect, 0.75f, 'r');
+ }
+
+ /* half rounded */
+ round_box_edges(&wtb, roundboxalign, rect, rad);
+
+ widgetbase_draw(&wtb, wcol);
+}
static void widget_tab(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
@@ -3590,7 +3641,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
case UI_WTYPE_EXEC:
wt.wcol_theme = &btheme->tui.wcol_tool;
- wt.draw = widget_roundbut;
+ wt.draw = widget_roundbut_exec;
break;
case UI_WTYPE_TAB:
@@ -3770,6 +3821,10 @@ static int widget_roundbox_set(uiBut *but, rcti *rect)
return roundbox;
}
+/* -------------------------------------------------------------------- */
+/** \name Public API
+ * \{ */
+
/* conversion from old to new buttons, so still messy */
void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rcti *rect)
{
@@ -4009,7 +4064,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
roundboxalign = widget_roundbox_set(but, rect);
- state = but->flag;
+ state = but->flag & UI_BUT_FLAGS_PUBLIC;
if ((but->editstr) ||
(UNLIKELY(but->flag & UI_BUT_DRAG_MULTI) && ui_but_drag_multi_edit_get(but)))
@@ -4017,6 +4072,10 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
state |= UI_TEXTINPUT;
}
+ if (but->hold_func) {
+ state |= UI_STATE_HOLD_ACTION;
+ }
+
if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE))
if (but->dt != UI_EMBOSS_PULLDOWN)
disabled = true;
@@ -4343,3 +4402,5 @@ void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, const char *name, int
UI_fontstyle_draw(fstyle, &trect, drawstr, (unsigned char *)wt->wcol.text);
}
}
+
+/** \} */
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index d6843cc959d..ab55221c1dc 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -208,7 +208,12 @@ static void graph_panel_properties(const bContext *C, Panel *pa)
sub = uiLayoutRow(row, true);
uiLayoutSetEnabled(sub, (fcu->color_mode == FCURVE_COLOR_CUSTOM));
uiItemR(sub, &fcu_ptr, "color", 0, "", ICON_NONE);
-
+
+ /* smoothing setting */
+ col = uiLayoutColumn(layout, true);
+ uiItemL(col, IFACE_("Auto Handle Smoothing:"), ICON_NONE);
+ uiItemR(col, &fcu_ptr, "auto_smoothing", 0, "", ICON_NONE);
+
MEM_freeN(ale);
}