diff options
Diffstat (limited to 'source/blender/editors')
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); } |