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:
Diffstat (limited to 'source/blender/editors/interface')
-rw-r--r--source/blender/editors/interface/interface.c191
-rw-r--r--source/blender/editors/interface/interface_anim.c32
-rw-r--r--source/blender/editors/interface/interface_draw.c11
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c43
-rw-r--r--source/blender/editors/interface/interface_handlers.c859
-rw-r--r--source/blender/editors/interface/interface_icons.c185
-rw-r--r--source/blender/editors/interface/interface_intern.h40
-rw-r--r--source/blender/editors/interface/interface_layout.c67
-rw-r--r--source/blender/editors/interface/interface_ops.c108
-rw-r--r--source/blender/editors/interface/interface_panel.c268
-rw-r--r--source/blender/editors/interface/interface_regions.c114
-rw-r--r--source/blender/editors/interface/interface_style.c8
-rw-r--r--source/blender/editors/interface/interface_templates.c279
-rw-r--r--source/blender/editors/interface/interface_utils.c38
-rw-r--r--source/blender/editors/interface/interface_widgets.c293
-rw-r--r--source/blender/editors/interface/resources.c42
-rw-r--r--source/blender/editors/interface/view2d.c215
-rw-r--r--source/blender/editors/interface/view2d_ops.c101
18 files changed, 1973 insertions, 921 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index bad09a7c441..e045db8fdd2 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -37,6 +37,7 @@
#include "MEM_guardedalloc.h"
+#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
@@ -82,11 +83,11 @@
#define B_NOP -1
-/*
- * a full doc with API notes can be found in bf-blender/trunk/blender/doc/guides/interface_API.txt
+/**
+ * a full doc with API notes can be found in 'blender/doc/guides/interface_API.txt'
*
- * uiBlahBlah() external function
- * ui_blah_blah() internal function
+ * `uiBlahBlah()` external function.
+ * `ui_blah_blah()` internal function.
*/
static void ui_but_free(const bContext *C, uiBut *but);
@@ -513,7 +514,7 @@ static void ui_draw_links(uiBlock *block)
uiBut *but;
uiLinkLine *line;
- /* Draw the grey out lines. Do this first so they appear at the
+ /* Draw the gray out lines. Do this first so they appear at the
* bottom of inactive or active lines.
* As we go, remember if we see any active or selected lines. */
bool found_selectline = false;
@@ -548,7 +549,7 @@ static void ui_draw_links(uiBlock *block)
}
/* Draw any active lines (lines with either button being hovered over).
- * Do this last so they appear on top of inactive and grey out lines. */
+ * Do this last so they appear on top of inactive and gray out lines. */
if (found_activeline) {
for (but = block->buttons.first; but; but = but->next) {
if (but->type == UI_BTYPE_LINK && but->link) {
@@ -1099,13 +1100,16 @@ static bool ui_but_event_property_operator_string(const bContext *C, uiBut *but,
return found;
}
-/* this goes in a seemingly weird pattern:
+/**
+ * This goes in a seemingly weird pattern:
*
+ * <pre>
* 4
* 5 6
* 1 2
* 7 8
* 3
+ * </pre>
*
* but it's actually quite logical. It's designed to be 'upwards compatible'
* for muscle memory so that the menu item locations are fixed and don't move
@@ -1930,7 +1934,7 @@ void ui_but_value_set(uiBut *but, double value)
int ui_but_string_get_max_length(uiBut *but)
{
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK))
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU))
return but->hardmax;
else
return UI_MAX_DRAW_STR;
@@ -1951,6 +1955,56 @@ uiBut *ui_but_drag_multi_edit_get(uiBut *but)
return but_iter;
}
+/** \name Check to show extra icons
+ *
+ * Extra icons are shown on the right hand side of buttons.
+ * \{ */
+
+static bool ui_but_icon_extra_is_visible_search_unlink(const uiBut *but)
+{
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+ return ((but->editstr == NULL) &&
+ (but->drawstr[0] != '\0') &&
+ (but->flag & UI_BUT_SEARCH_UNLINK));
+}
+
+static bool ui_but_icon_extra_is_visible_eyedropper(uiBut *but)
+{
+ StructRNA *type;
+ short idcode;
+
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU && (but->flag & UI_BUT_SEARCH_UNLINK));
+
+ if (but->rnaprop == NULL) {
+ return false;
+ }
+
+ type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
+ idcode = RNA_type_to_ID_code(type);
+
+
+ return ((but->editstr == NULL) &&
+ (idcode == ID_OB || OB_DATA_SUPPORT_ID(idcode)));
+}
+
+uiButExtraIconType ui_but_icon_extra_get(uiBut *but)
+{
+ if ((but->flag & UI_BUT_SEARCH_UNLINK) == 0) {
+ /* pass */
+ }
+ else if (ui_but_icon_extra_is_visible_search_unlink(but)) {
+ return UI_BUT_ICONEXTRA_UNLINK;
+ }
+ else if (ui_but_icon_extra_is_visible_eyedropper(but)) {
+ return UI_BUT_ICONEXTRA_EYEDROPPER;
+ }
+
+ return UI_BUT_ICONEXTRA_NONE;
+}
+
+/** \} */
+
+
static double ui_get_but_scale_unit(uiBut *but, double value)
{
UnitSettings *unit = but->block->unit;
@@ -2031,7 +2085,7 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
*/
void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision)
{
- if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
PropertyType type;
const char *buf = NULL;
int buf_len;
@@ -2073,7 +2127,7 @@ void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int
BLI_strncpy(str, but->poin, maxlen);
return;
}
- else if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ else if (but->type == UI_BTYPE_SEARCH_MENU) {
/* string */
BLI_strncpy(str, but->poin, maxlen);
return;
@@ -2194,7 +2248,7 @@ static void ui_but_string_free_internal(uiBut *but)
bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
{
- if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
if (RNA_property_editable(&but->rnapoin, but->rnaprop)) {
PropertyType type;
@@ -2246,7 +2300,7 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
return true;
}
- else if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ else if (but->type == UI_BTYPE_SEARCH_MENU) {
/* string */
BLI_strncpy(but->poin, str, but->hardmax);
return true;
@@ -2264,6 +2318,7 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
double value;
if (ui_but_string_set_eval_num(C, but, str, &value) == false) {
+ WM_report_banner_show(C);
return false;
}
@@ -2714,11 +2769,11 @@ void ui_but_update(uiBut *but)
}
else {
const int prec = ui_but_calc_float_precision(but, value);
- slen += BLI_snprintf(but->drawstr + slen, sizeof(but->drawstr) - slen, "%.*f", prec, value);
+ slen += BLI_snprintf_rlen(but->drawstr + slen, sizeof(but->drawstr) - slen, "%.*f", prec, value);
}
}
else {
- slen += BLI_snprintf(but->drawstr + slen, sizeof(but->drawstr) - slen, "%d", (int)value);
+ slen += BLI_snprintf_rlen(but->drawstr + slen, sizeof(but->drawstr) - slen, "%d", (int)value);
}
if (but->rnaprop) {
@@ -2754,7 +2809,6 @@ void ui_but_update(uiBut *but)
case UI_BTYPE_TEXT:
case UI_BTYPE_SEARCH_MENU:
- case UI_BTYPE_SEARCH_MENU_UNLINK:
if (!but->editstr) {
char str[UI_MAX_DRAW_STR];
@@ -3047,17 +3101,18 @@ void ui_block_cm_to_scene_linear_v3(uiBlock *block, float pixel[3])
/**
* \brief ui_def_but is the function that draws many button types
*
- * \param x,y The lower left hand corner of the button (X axis)
- * \param width,height The size of the button.
+ * \param x, y: The lower left hand corner of the button (X axis)
+ * \param width, height: The size of the button.
*
* for float buttons:
- * - \a a1 Click Step (how much to change the value each click)
- * - \a a2 Number of decimal point values to display. 0 defaults to 3 (0.000)
- * 1,2,3, and a maximum of 4, all greater values will be clamped to 4.
+ * \param a1: Click Step (how much to change the value each click)
+ * \param a2: Number of decimal point values to display. 0 defaults to 3 (0.000)
+ * 1,2,3, and a maximum of 4, all greater values will be clamped to 4.
*/
-static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
- int x, int y, short width, short height,
- void *poin, float min, float max, float a1, float a2, const char *tip)
+static uiBut *ui_def_but(
+ uiBlock *block, int type, int retval, const char *str,
+ int x, int y, short width, short height,
+ void *poin, float min, float max, float a1, float a2, const char *tip)
{
uiBut *but;
int slen;
@@ -3139,7 +3194,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
ELEM(but->type,
UI_BTYPE_MENU, UI_BTYPE_TEXT, UI_BTYPE_LABEL,
UI_BTYPE_BLOCK, UI_BTYPE_BUT_MENU, UI_BTYPE_SEARCH_MENU,
- UI_BTYPE_PROGRESS_BAR, UI_BTYPE_SEARCH_MENU_UNLINK))
+ UI_BTYPE_PROGRESS_BAR))
{
but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT);
}
@@ -3186,6 +3241,19 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
return but;
}
+void ui_def_but_icon(uiBut *but, const int icon, const int flag)
+{
+ if (icon) {
+ ui_icon_ensure_deferred(but->block->evil_C, icon, (flag & UI_BUT_ICON_PREVIEW) != 0);
+ }
+ but->icon = (BIFIconID)icon;
+ but->flag |= flag;
+
+ if (but->str && but->str[0]) {
+ but->drawflag |= UI_BUT_ICON_LEFT;
+ }
+}
+
static void ui_def_but_rna__disable(uiBut *but)
{
but->flag |= UI_BUT_DISABLED;
@@ -3325,10 +3393,11 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu
* When this kind of change won't disrupt branches, best look into making more
* of our UI functions take prop rather then propname.
*/
-static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str,
- int x, int y, short width, short height,
- PointerRNA *ptr, PropertyRNA *prop, int index,
- float min, float max, float a1, float a2, const char *tip)
+static uiBut *ui_def_but_rna(
+ uiBlock *block, int type, int retval, const char *str,
+ int x, int y, short width, short height,
+ PointerRNA *ptr, PropertyRNA *prop, int index,
+ float min, float max, float a1, float a2, const char *tip)
{
const PropertyType proptype = RNA_property_type(prop);
uiBut *but;
@@ -3448,11 +3517,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
but->rnaindex = 0;
if (icon) {
- but->icon = (BIFIconID)icon;
- but->flag |= UI_HAS_ICON;
- if (str[0]) {
- but->drawflag |= UI_BUT_ICON_LEFT;
- }
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
}
if ((type == UI_BTYPE_MENU) && (but->dt == UI_EMBOSS_PULLDOWN)) {
@@ -3639,8 +3704,7 @@ int UI_autocomplete_end(AutoComplete *autocpl, char *autoname)
static void ui_but_update_and_icon_set(uiBut *but, int icon)
{
if (icon) {
- but->icon = (BIFIconID) icon;
- but->flag |= UI_HAS_ICON;
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
}
ui_but_update(but);
@@ -4014,7 +4078,7 @@ void UI_but_drag_set_value(uiBut *but)
void UI_but_drag_set_image(uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale)
{
but->dragtype = WM_DRAG_PATH;
- but->icon = icon; /* no flag UI_HAS_ICON, so icon doesnt draw in button */
+ ui_def_but_icon(but, icon, 0); /* no flag UI_HAS_ICON, so icon doesnt draw in button */
but->dragpoin = (void *)path;
but->imb = imb;
but->imb_scale = scale;
@@ -4168,8 +4232,7 @@ uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, in
{
uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
- but->icon = (BIFIconID) icon;
- but->flag |= UI_HAS_ICON;
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
but->drawflag |= UI_BUT_ICON_LEFT;
but->flag |= UI_BUT_ICON_SUBMENU;
@@ -4184,8 +4247,7 @@ uiBut *uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int ic
{
uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
- but->icon = (BIFIconID) icon;
- but->flag |= UI_HAS_ICON;
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
but->drawflag &= ~UI_BUT_ICON_LEFT;
but->menu_create_func = func;
@@ -4201,7 +4263,7 @@ uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg,
/* XXX temp, old menu calls pass on icon arrow, which is now UI_BUT_ICON_SUBMENU flag */
if (icon != ICON_RIGHTARROW_THIN) {
- but->icon = (BIFIconID) icon;
+ ui_def_but_icon(but, icon, 0);
but->drawflag |= UI_BUT_ICON_LEFT;
}
but->flag |= UI_HAS_ICON;
@@ -4218,9 +4280,8 @@ uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int
{
uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, retval, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
- but->icon = (BIFIconID) icon;
- but->flag |= UI_HAS_ICON;
-
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
+
but->drawflag |= UI_BUT_ICON_LEFT;
but->block_create_func = func;
@@ -4253,9 +4314,8 @@ uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxle
{
uiBut *but = ui_def_but(block, UI_BTYPE_SEARCH_MENU, retval, "", x, y, width, height, arg, 0.0, maxlen, a1, a2, tip);
- but->icon = (BIFIconID) icon;
- but->flag |= UI_HAS_ICON;
-
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
+
but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT;
ui_but_update(but);
@@ -4264,8 +4324,11 @@ uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxle
}
-/* arg is user value, searchfunc and handlefunc both get it as arg */
-/* if active set, button opens with this item visible and selected */
+/**
+ * \param sfunc, bfunc: both get it as \a arg.
+ * \param arg: user value,
+ * \param active: when set, button opens with this item visible and selected.
+ */
void UI_but_func_search_set(uiBut *but, uiButSearchFunc sfunc, void *arg, uiButHandleFunc bfunc, void *active)
{
but->search_func = sfunc;
@@ -4334,11 +4397,14 @@ static void operator_enum_call_cb(struct bContext *UNUSED(C), void *but, void *a
}
}
-/* Same parameters as for uiDefSearchBut, with additional operator type and properties, used by callback
- * to call again the right op with the right options (properties values). */
-uiBut *uiDefSearchButO_ptr(uiBlock *block, wmOperatorType *ot, IDProperty *properties,
- void *arg, int retval, int icon, int maxlen, int x, int y,
- short width, short height, float a1, float a2, const char *tip)
+/**
+ * Same parameters as for uiDefSearchBut, with additional operator type and properties, used by callback
+ * to call again the right op with the right options (properties values).
+ */
+uiBut *uiDefSearchButO_ptr(
+ uiBlock *block, wmOperatorType *ot, IDProperty *properties,
+ void *arg, int retval, int icon, int maxlen, int x, int y,
+ short width, short height, float a1, float a2, const char *tip)
{
uiBut *but;
@@ -4357,7 +4423,8 @@ uiBut *uiDefSearchButO_ptr(uiBlock *block, wmOperatorType *ot, IDProperty *prope
return but;
}
-/* push a new event onto event queue to activate the given button
+/**
+ * push a new event onto event queue to activate the given button
* (usually a text-field) upon entering a popup
*/
void UI_but_focus_on_enter_event(wmWindow *win, uiBut *but)
@@ -4390,7 +4457,19 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...)
if (type == BUT_GET_LABEL) {
if (but->str) {
- tmp = BLI_strdup(but->str);
+ const char *str_sep;
+ size_t str_len;
+
+ if ((but->flag & UI_BUT_HAS_SEP_CHAR) &&
+ (str_sep = strrchr(but->str, UI_SEP_CHAR)))
+ {
+ str_len = (str_sep - but->str);
+ }
+ else {
+ str_len = strlen(but->str);
+ }
+
+ tmp = BLI_strdupn(but->str, str_len);
}
else {
type = BUT_GET_RNA_LABEL; /* Fail-safe solution... */
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index 24a30ebe3d8..f6757b35462 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -54,13 +54,13 @@
#include "interface_intern.h"
-static FCurve *ui_but_get_fcurve(uiBut *but, AnimData **adt, bAction **action, bool *r_driven)
+static FCurve *ui_but_get_fcurve(uiBut *but, AnimData **adt, bAction **action, bool *r_driven, bool *r_special)
{
/* for entire array buttons we check the first component, it's not perfect
* but works well enough in typical cases */
int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex;
- return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven);
+ return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven, r_special);
}
void ui_but_anim_flag(uiBut *but, float cfra)
@@ -69,11 +69,16 @@ void ui_but_anim_flag(uiBut *but, float cfra)
bAction *act;
FCurve *fcu;
bool driven;
-
+ bool special;
+
but->flag &= ~(UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN);
-
- fcu = ui_but_get_fcurve(but, &adt, &act, &driven);
-
+
+ /* NOTE: "special" is reserved for special F-Curves stored on the animation data
+ * itself (which are used to animate properties of the animation data).
+ * We count those as "animated" too for now
+ */
+ fcu = ui_but_get_fcurve(but, &adt, &act, &driven, &special);
+
if (fcu) {
if (!driven) {
but->flag |= UI_BUT_ANIMATED;
@@ -98,10 +103,10 @@ bool ui_but_anim_expression_get(uiBut *but, char *str, size_t maxlen)
{
FCurve *fcu;
ChannelDriver *driver;
- bool driven;
-
- fcu = ui_but_get_fcurve(but, NULL, NULL, &driven);
-
+ bool driven, special;
+
+ fcu = ui_but_get_fcurve(but, NULL, NULL, &driven, &special);
+
if (fcu && driven) {
driver = fcu->driver;
@@ -118,9 +123,9 @@ bool ui_but_anim_expression_set(uiBut *but, const char *str)
{
FCurve *fcu;
ChannelDriver *driver;
- bool driven;
+ bool driven, special;
- fcu = ui_but_get_fcurve(but, NULL, NULL, &driven);
+ fcu = ui_but_get_fcurve(but, NULL, NULL, &driven, &special);
if (fcu && driven) {
driver = fcu->driver;
@@ -215,8 +220,9 @@ void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
bAction *action;
FCurve *fcu;
bool driven;
+ bool special;
- fcu = ui_but_get_fcurve(but, NULL, &action, &driven);
+ fcu = ui_but_get_fcurve(but, NULL, &action, &driven, &special);
if (fcu && !driven) {
id = but->rnapoin.id.data;
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 07d580b9138..2c13b199bba 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -508,8 +508,9 @@ static void draw_scope_end(const rctf *rect, GLint *scissor)
UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f);
}
-static void histogram_draw_one(float r, float g, float b, float alpha,
- float x, float y, float w, float h, const float *data, int res, const bool is_line)
+static void histogram_draw_one(
+ float r, float g, float b, float alpha,
+ float x, float y, float w, float h, const float *data, int res, const bool is_line)
{
int i;
@@ -1260,8 +1261,8 @@ void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
size = BLI_rcti_size_x(rect) / 200.f;
else
size = BLI_rcti_size_y(rect) / 200.f;
-
- glScalef(size, size, size);
+
+ glScalef(size, size, MIN2(size, 1.0f));
if (displist == 0) {
GLUquadricObj *qobj;
@@ -1453,7 +1454,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti
glEnd();
}
else if (cumap->cur == 3) {
- float lum = rgb_to_bw(cumap->sample);
+ float lum = IMB_colormanagement_get_luminance(cumap->sample);
glColor3ub(240, 240, 240);
glBegin(GL_LINES);
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index aabb8e29fa9..97aa865c287 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -36,6 +36,8 @@
#include "BLI_blenlib.h"
#include "BLI_math_vector.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_report.h"
@@ -176,8 +178,8 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
if (sa) {
if (sa->spacetype == SPACE_IMAGE) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
+ if (ar) {
SpaceImage *sima = sa->spacedata.first;
int mval[2] = {mx - ar->winrct.xmin,
my - ar->winrct.ymin};
@@ -188,8 +190,8 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
}
}
else if (sa->spacetype == SPACE_NODE) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
+ if (ar) {
SpaceNode *snode = sa->spacedata.first;
int mval[2] = {mx - ar->winrct.xmin,
my - ar->winrct.ymin};
@@ -200,8 +202,8 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
}
}
else if (sa->spacetype == SPACE_CLIP) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
+ if (ar) {
SpaceClip *sc = sa->spacedata.first;
int mval[2] = {mx - ar->winrct.xmin,
my - ar->winrct.ymin};
@@ -379,12 +381,11 @@ void UI_OT_eyedropper_color(wmOperatorType *ot)
/* -------------------------------------------------------------------- */
-/* Data Dropper
- *
- * note: datadropper is only internal name to avoid confusion in this file
- */
+/* Data Dropper */
/** \name Eyedropper (ID data-blocks)
+ *
+ * \note: datadropper is only internal name to avoid confusion in this file.
* \{ */
typedef struct DataDropper {
@@ -436,7 +437,8 @@ static int datadropper_init(bContext *C, wmOperator *op)
type = RNA_property_pointer_type(&ddr->ptr, ddr->prop);
ddr->idcode = RNA_type_to_ID_code(type);
BLI_assert(ddr->idcode != 0);
- ddr->idcode_name = BKE_idcode_to_name(ddr->idcode);
+ /* Note we can translate here (instead of on draw time), because this struct has very short lifetime. */
+ ddr->idcode_name = TIP_(BKE_idcode_to_name(ddr->idcode));
return true;
}
@@ -456,6 +458,8 @@ static void datadropper_exit(bContext *C, wmOperator *op)
op->customdata = NULL;
}
+
+ WM_event_add_mousemove(C);
}
static void datadropper_cancel(bContext *C, wmOperator *op)
@@ -482,8 +486,8 @@ static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int
if (sa) {
if (sa->spacetype == SPACE_VIEW3D) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
+ if (ar) {
const int mval[2] = {
mx - ar->winrct.xmin,
my - ar->winrct.ymin};
@@ -632,7 +636,7 @@ void UI_OT_eyedropper_id(wmOperatorType *ot)
/* identifiers */
ot->name = "Eyedropper Datablock";
ot->idname = "UI_OT_eyedropper_id";
- ot->description = "Sample a color from the Blender Window to store in a property";
+ ot->description = "Sample a datablock from the Blender Window to store in a property";
/* api callbacks */
ot->invoke = datadropper_invoke;
@@ -651,12 +655,11 @@ void UI_OT_eyedropper_id(wmOperatorType *ot)
/* -------------------------------------------------------------------- */
-/* Depth Dropper
- *
- * note: depthdropper is only internal name to avoid confusion in this file
- */
+/* Depth Dropper */
/** \name Eyedropper (Depth)
+ *
+ * \note: depthdropper is only internal name to avoid confusion in this file.
* \{ */
typedef struct DepthDropper {
@@ -765,8 +768,8 @@ static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx,
if (sa) {
if (sa->spacetype == SPACE_VIEW3D) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
+ if (ar) {
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
/* weak, we could pass in some reference point */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index a6ff5bb3ad3..58cf6b900b9 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -52,9 +52,9 @@
#include "BLI_linklist.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
+#include "BLI_string_cursor_utf8.h"
#include "BLI_rect.h"
#include "BLI_utildefines.h"
-#include "BLI_string_cursor_utf8.h"
#include "BLF_translation.h"
@@ -99,6 +99,9 @@
/* support dragging multiple number buttons at once */
#define USE_DRAG_MULTINUM
+/* allow dragging/editing all other selected items at once */
+#define USE_ALLSELECT
+
/* so we can avoid very small mouse-moves from jumping away from keyboard navigation [#34936] */
#define USE_KEYNAV_LIMIT
@@ -158,17 +161,63 @@ typedef enum uiHandleButtonState {
} uiHandleButtonState;
+#ifdef USE_ALLSELECT
+
+/* Unfortunately theres no good way handle more generally:
+ * (propagate single clicks on layer buttons to other objects) */
+#define USE_ALLSELECT_LAYER_HACK
+
+typedef struct uiSelectContextElem {
+ PointerRNA ptr;
+ union {
+ bool val_b;
+ int val_i;
+ float val_f;
+ };
+} uiSelectContextElem;
+
+typedef struct uiSelectContextStore {
+ uiSelectContextElem *elems;
+ int elems_len;
+ bool do_free;
+ bool is_enabled;
+ /* When set, simply copy values (don't apply difference).
+ * Rules are:
+ * - dragging numbers uses delta.
+ * - typing in values will assign to all. */
+ bool is_copy;
+} uiSelectContextStore;
+
+static bool ui_selectcontext_begin(
+ bContext *C, uiBut *but, struct uiSelectContextStore *selctx_data);
+static void ui_selectcontext_end(
+ uiBut *but, uiSelectContextStore *selctx_data);
+static void ui_selectcontext_apply(
+ bContext *C, uiBut *but, struct uiSelectContextStore *selctx_data,
+ const double value, const double value_orig);
+
+#define IS_ALLSELECT_EVENT(event) ((event)->alt != 0)
+
+/** just show a tinted color so users know its activated */
+#define UI_BUT_IS_SELECT_CONTEXT UI_BUT_NODE_ACTIVE
+
+#endif /* USE_ALLSELECT */
+
+
#ifdef USE_DRAG_MULTINUM
-/* how far to drag before we check for gesture direction (in pixels),
+/**
+ * how far to drag before we check for gesture direction (in pixels),
* note: half the height of a button is about right... */
#define DRAG_MULTINUM_THRESHOLD_DRAG_X (UI_UNIT_Y / 4)
-/* how far to drag horizontally before we stop checking which buttons the gesture spans (in pixels),
+/**
+ * how far to drag horizontally before we stop checking which buttons the gesture spans (in pixels),
* locking down the buttons so we can drag freely without worrying about vertical movement. */
#define DRAG_MULTINUM_THRESHOLD_DRAG_Y (UI_UNIT_Y / 4)
-/* how strict to be when detecting a vertical gesture, [0.5 == sloppy], [0.9 == strict], (unsigned dot-product)
+/**
+ * how strict to be when detecting a vertical gesture, [0.5 == sloppy], [0.9 == strict], (unsigned dot-product)
* note: we should be quite strict here, since doing a vertical gesture by accident should be avoided,
* however with some care a user should be able to do a vertical movement without *missing*. */
#define DRAG_MULTINUM_THRESHOLD_VERTICAL (0.75f)
@@ -178,6 +227,10 @@ typedef enum uiHandleButtonState {
typedef struct uiButMultiState {
double origvalue;
uiBut *but;
+
+#ifdef USE_ALLSELECT
+ uiSelectContextStore select_others;
+#endif
} uiButMultiState;
typedef struct uiHandleButtonMulti {
@@ -210,8 +263,6 @@ typedef struct uiHandleButtonMulti {
#endif /* USE_DRAG_MULTINUM */
-
-
typedef struct uiHandleButtonData {
wmWindowManager *wm;
wmWindow *window;
@@ -280,6 +331,10 @@ typedef struct uiHandleButtonData {
uiHandleButtonMulti multi_data;
#endif
+#ifdef USE_ALLSELECT
+ uiSelectContextStore select_others;
+#endif
+
/* post activate */
uiButtonActivateType posttype;
uiBut *postbut;
@@ -328,14 +383,14 @@ static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, c
static uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event);
static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type);
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state);
-static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *data,
- const bool mousemove, const bool onfree);
+static void button_activate_exit(
+ bContext *C, uiBut *but, uiHandleButtonData *data,
+ const bool mousemove, const bool onfree);
static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *userdata);
static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type);
-static void button_timers_tooltip_remove(bContext *C, uiBut *but);
#ifdef USE_DRAG_MULTINUM
-static void ui_multibut_restore(uiHandleButtonData *data, uiBlock *block);
+static void ui_multibut_restore(bContext *C, uiHandleButtonData *data, uiBlock *block);
static uiButMultiState *ui_multibut_lookup(uiHandleButtonData *data, const uiBut *but);
#endif
@@ -366,7 +421,7 @@ static void ui_color_snap_hue(const enum eSnapType snap, float *r_hue)
{
const float snap_increment = (snap == SNAP_ON_SMALL) ? 24 : 12;
BLI_assert(snap != SNAP_OFF);
- *r_hue = floorf(0.5f + ((*r_hue) * snap_increment)) / snap_increment;
+ *r_hue = roundf((*r_hue) * snap_increment) / snap_increment;
}
/* assumes event type is MOUSEPAN */
@@ -413,7 +468,7 @@ bool ui_but_is_editable_as_text(const uiBut *but)
{
return ELEM(but->type,
UI_BTYPE_TEXT, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER,
- UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK);
+ UI_BTYPE_SEARCH_MENU);
}
@@ -478,10 +533,9 @@ static float ui_mouse_scale_warp_factor(const bool shift)
return shift ? 0.05f : 1.0f;
}
-static void ui_mouse_scale_warp(uiHandleButtonData *data,
- const float mx, const float my,
- float *r_mx, float *r_my,
- const bool shift)
+static void ui_mouse_scale_warp(
+ uiHandleButtonData *data, const float mx, const float my,
+ float *r_mx, float *r_my, const bool shift)
{
const float fac = ui_mouse_scale_warp_factor(shift);
@@ -894,7 +948,7 @@ static uiButMultiState *ui_multibut_lookup(uiHandleButtonData *data, const uiBut
return NULL;
}
-static void ui_multibut_restore(uiHandleButtonData *data, uiBlock *block)
+static void ui_multibut_restore(bContext *C, uiHandleButtonData *data, uiBlock *block)
{
uiBut *but;
@@ -903,6 +957,16 @@ static void ui_multibut_restore(uiHandleButtonData *data, uiBlock *block)
uiButMultiState *mbut_state = ui_multibut_lookup(data, but);
if (mbut_state) {
ui_but_value_set(but, mbut_state->origvalue);
+
+#ifdef USE_ALLSELECT
+ if (mbut_state->select_others.elems_len > 0) {
+ ui_selectcontext_apply(
+ C, but, &mbut_state->select_others,
+ mbut_state->origvalue, mbut_state->origvalue);
+ }
+#else
+ UNUSED_VARS(C);
+#endif
}
}
}
@@ -910,7 +974,26 @@ static void ui_multibut_restore(uiHandleButtonData *data, uiBlock *block)
static void ui_multibut_free(uiHandleButtonData *data, uiBlock *block)
{
+#ifdef USE_ALLSELECT
+ if (data->multi_data.mbuts) {
+ LinkNode *list = data->multi_data.mbuts;
+ while (list) {
+ LinkNode *next = list->next;
+ uiButMultiState *mbut_state = list->link;
+
+ if (mbut_state->select_others.elems) {
+ MEM_freeN(mbut_state->select_others.elems);
+ }
+
+ MEM_freeN(list->link);
+ MEM_freeN(list);
+ list = next;
+ }
+ }
+#else
BLI_linklist_freeN(data->multi_data.mbuts);
+#endif
+
data->multi_data.mbuts = NULL;
if (data->multi_data.bs_mbuts) {
@@ -979,6 +1062,7 @@ static void ui_multibut_states_create(uiBut *but_active, uiHandleButtonData *dat
uiBut *but;
BLI_assert(data->multi_data.init == BUTTON_MULTI_INIT_SETUP);
+ BLI_assert(data->multi_data.has_mbuts);
data->multi_data.bs_mbuts = UI_butstore_create(but_active->block);
@@ -1016,6 +1100,24 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl
void *active_back;
ui_but_execute_begin(C, ar, but, &active_back);
+
+#ifdef USE_ALLSELECT
+ if (data->select_others.is_enabled) {
+ /* init once! */
+ if (mbut_state->select_others.elems_len == 0) {
+ ui_selectcontext_begin(C, but, &mbut_state->select_others);
+ }
+ if (mbut_state->select_others.elems_len == 0) {
+ mbut_state->select_others.elems_len = -1;
+ }
+ }
+
+ /* needed so we apply the right deltas */
+ but->active->origvalue = mbut_state->origvalue;
+ but->active->select_others = mbut_state->select_others;
+ but->active->select_others.do_free = false;
+#endif
+
BLI_assert(active_back == NULL);
/* no need to check 'data->state' here */
if (data->str) {
@@ -1064,8 +1166,9 @@ typedef struct uiDragToggleHandle {
int xy_last[2];
} uiDragToggleHandle;
-static bool ui_drag_toggle_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])
+static bool ui_drag_toggle_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])
{
/* popups such as layers won't re-evaluate on redraw */
const bool do_check = (ar->regiontype == RGN_TYPE_TEMPORARY);
@@ -1225,6 +1328,267 @@ static bool ui_but_is_drag_toggle(const uiBut *but)
#endif /* USE_DRAG_TOGGLE */
+#ifdef USE_ALLSELECT
+
+static bool ui_selectcontext_begin(
+ bContext *C, uiBut *but, uiSelectContextStore *selctx_data)
+{
+ PointerRNA ptr, lptr, idptr;
+ PropertyRNA *prop, *lprop;
+ bool success = false;
+ int index;
+
+ char *path = NULL;
+ ListBase lb = {NULL};
+
+ ptr = but->rnapoin;
+ prop = but->rnaprop;
+ index = but->rnaindex;
+
+ /* for now don't support whole colors */
+ if (index == -1)
+ return false;
+
+ /* if there is a valid property that is editable... */
+ if (ptr.data && prop) {
+ CollectionPointerLink *link;
+ bool use_path_from_id;
+ int i;
+
+ /* some facts we want to know */
+ const bool is_array = RNA_property_array_check(prop);
+ const int rna_type = RNA_property_type(prop);
+
+ if (!UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path)) {
+ goto finally;
+ }
+
+ selctx_data->elems_len = BLI_listbase_count(&lb);
+ if (selctx_data->elems_len == 0) {
+ goto finally;
+ }
+
+ selctx_data->elems = MEM_mallocN(sizeof(uiSelectContextElem) * selctx_data->elems_len, __func__);
+
+ for (i = 0, link = lb.first; i < selctx_data->elems_len; i++, link = link->next) {
+ uiSelectContextElem *other = &selctx_data->elems[i];
+ /* TODO,. de-duplicate copy_to_selected_button */
+ if (link->ptr.data != ptr.data) {
+ if (use_path_from_id) {
+ /* Path relative to ID. */
+ lprop = NULL;
+ RNA_id_pointer_create(link->ptr.id.data, &idptr);
+ RNA_path_resolve_property(&idptr, path, &lptr, &lprop);
+ }
+ else if (path) {
+ /* Path relative to elements from list. */
+ lprop = NULL;
+ RNA_path_resolve_property(&link->ptr, path, &lptr, &lprop);
+ }
+ else {
+ lptr = link->ptr;
+ lprop = prop;
+ }
+
+ /* lptr might not be the same as link->ptr! */
+ if ((lptr.data != ptr.data) &&
+ (lprop == prop) &&
+ RNA_property_editable(&lptr, lprop))
+ {
+ other->ptr = lptr;
+ if (is_array) {
+ if (rna_type == PROP_FLOAT) {
+ other->val_f = RNA_property_float_get_index(&lptr, lprop, index);
+ }
+ else if (rna_type == PROP_INT) {
+ other->val_i = RNA_property_int_get_index(&lptr, lprop, index);
+ }
+ /* ignored for now */
+#if 0
+ else if (rna_type == PROP_BOOLEAN) {
+ other->val_b = RNA_property_boolean_get_index(&lptr, lprop, index);
+ }
+#endif
+ }
+ else {
+ if (rna_type == PROP_FLOAT) {
+ other->val_f = RNA_property_float_get(&lptr, lprop);
+ }
+ else if (rna_type == PROP_INT) {
+ other->val_i = RNA_property_int_get(&lptr, lprop);
+ }
+ /* ignored for now */
+#if 0
+ else if (rna_type == PROP_BOOLEAN) {
+ other->val_b = RNA_property_boolean_get(&lptr, lprop);
+ }
+ else if (rna_type == PROP_ENUM) {
+ other->val_i = RNA_property_enum_get(&lptr, lprop);
+ }
+#endif
+ }
+
+ continue;
+ }
+ }
+
+ selctx_data->elems_len -= 1;
+ i -= 1;
+ }
+ }
+
+ success = (selctx_data->elems_len != 0);
+
+finally:
+ if (selctx_data->elems_len == 0) {
+ MEM_SAFE_FREE(selctx_data->elems);
+ }
+
+ MEM_SAFE_FREE(path);
+ BLI_freelistN(&lb);
+
+ /* caller can clear */
+ selctx_data->do_free = true;
+
+ if (success) {
+ but->flag |= UI_BUT_IS_SELECT_CONTEXT;
+ }
+
+ return success;
+}
+
+static void ui_selectcontext_end(
+ uiBut *but, uiSelectContextStore *selctx_data)
+{
+ if (selctx_data->do_free) {
+ if (selctx_data->elems) {
+ MEM_freeN(selctx_data->elems);
+ }
+ }
+
+ but->flag &= ~UI_BUT_IS_SELECT_CONTEXT;
+}
+
+static void ui_selectcontext_apply(
+ bContext *C, uiBut *but, uiSelectContextStore *selctx_data,
+ const double value, const double value_orig)
+{
+ if (selctx_data->elems) {
+ PropertyRNA *prop = but->rnaprop;
+ PropertyRNA *lprop = but->rnaprop;
+ int index = but->rnaindex;
+ int i;
+ const bool use_delta = (selctx_data->is_copy == false);
+
+ union {
+ bool b;
+ int i;
+ float f;
+ } delta, min, max;
+
+ const bool is_array = RNA_property_array_check(prop);
+ const int rna_type = RNA_property_type(prop);
+
+ if (rna_type == PROP_FLOAT) {
+ delta.f = use_delta ? (value - value_orig) : value;
+ RNA_property_float_range(&but->rnapoin, prop, &min.f, &max.f);
+ }
+ else if (rna_type == PROP_INT) {
+ delta.i = use_delta ? ((int)value - (int)value_orig) : (int)value;
+ RNA_property_int_range(&but->rnapoin, prop, &min.i, &max.i);
+ }
+ else if (rna_type == PROP_ENUM) {
+ delta.i = RNA_property_enum_get(&but->rnapoin, prop); /* not a delta infact */
+ }
+ else if (rna_type == PROP_BOOLEAN) {
+ if (is_array) {
+ delta.b = RNA_property_boolean_get_index(&but->rnapoin, prop, index); /* not a delta infact */
+ }
+ else {
+ delta.b = RNA_property_boolean_get(&but->rnapoin, prop); /* not a delta infact */
+ }
+ }
+
+#ifdef USE_ALLSELECT_LAYER_HACK
+ /* make up for not having 'handle_layer_buttons' */
+ {
+ PropertySubType subtype = RNA_property_subtype(prop);
+
+ if ((rna_type == PROP_BOOLEAN) &&
+ ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER) &&
+ is_array &&
+ /* could check for 'handle_layer_buttons' */
+ but->func)
+ {
+ wmWindow *win = CTX_wm_window(C);
+ if (!win->eventstate->shift) {
+ const int len = RNA_property_array_length(&but->rnapoin, prop);
+ int *tmparray = MEM_callocN(sizeof(int) * len, __func__);
+
+ tmparray[index] = true;
+
+ for (i = 0; i < selctx_data->elems_len; i++) {
+ uiSelectContextElem *other = &selctx_data->elems[i];
+ PointerRNA lptr = other->ptr;
+ RNA_property_boolean_set_array(&lptr, lprop, tmparray);
+ RNA_property_update(C, &lptr, lprop);
+ }
+
+ MEM_freeN(tmparray);
+
+ return;
+ }
+ }
+ }
+#endif
+
+ for (i = 0; i < selctx_data->elems_len; i++) {
+ uiSelectContextElem *other = &selctx_data->elems[i];
+ PointerRNA lptr = other->ptr;
+
+ if (rna_type == PROP_FLOAT) {
+ float other_value = use_delta ? (other->val_f + delta.f) : delta.f;
+ CLAMP(other_value, min.f, max.f);
+ if (is_array) {
+ RNA_property_float_set_index(&lptr, lprop, index, other_value);
+ }
+ else {
+ RNA_property_float_set(&lptr, lprop, other_value);
+ }
+ }
+ else if (rna_type == PROP_INT) {
+ int other_value = use_delta ? (other->val_i + delta.i) : delta.i;
+ CLAMP(other_value, min.i, max.i);
+ if (is_array) {
+ RNA_property_int_set_index(&lptr, lprop, index, other_value);
+ }
+ else {
+ RNA_property_int_set(&lptr, lprop, other_value);
+ }
+ }
+ else if (rna_type == PROP_BOOLEAN) {
+ const bool other_value = delta.b;
+ if (is_array) {
+ RNA_property_boolean_set_index(&lptr, lprop, index, other_value);
+ }
+ else {
+ RNA_property_boolean_set(&lptr, lprop, delta.b);
+ }
+ }
+ else if (rna_type == PROP_ENUM) {
+ const int other_value = delta.i;
+ BLI_assert(!is_array);
+ RNA_property_enum_set(&lptr, lprop, other_value);
+ }
+
+ RNA_property_update(C, &lptr, prop);
+ }
+ }
+}
+
+#endif /* USE_ALLSELECT */
+
+
static bool ui_but_contains_point_px_icon(uiBut *but, ARegion *ar, const wmEvent *event)
{
rcti rect;
@@ -1278,10 +1642,11 @@ static bool ui_but_drag_init(bContext *C, uiBut *but, uiHandleButtonData *data,
ar_prev = CTX_wm_region(C);
CTX_wm_region_set(C, data->region);
- WM_event_add_ui_handler(C, &data->window->modalhandlers,
- ui_handler_region_drag_toggle,
- ui_handler_region_drag_toggle_remove,
- drag_info, false);
+ WM_event_add_ui_handler(
+ C, &data->window->modalhandlers,
+ ui_handler_region_drag_toggle,
+ ui_handler_region_drag_toggle_remove,
+ drag_info, WM_HANDLER_BLOCKING);
CTX_wm_region_set(C, ar_prev);
}
@@ -1596,9 +1961,8 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
data->str = data->origstr;
data->origstr = NULL;
data->value = data->origvalue;
- data->origvalue = 0.0;
copy_v3_v3(data->vec, data->origvec);
- data->origvec[0] = data->origvec[1] = data->origvec[2] = 0.0f;
+ /* postpone clearing origdata */
}
else {
/* we avoid applying interactive edits a second time
@@ -1609,6 +1973,27 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
else if (data->applied_interactive) {
return;
}
+
+#ifdef USE_ALLSELECT
+# ifdef USE_DRAG_MULTINUM
+ if (but->flag & UI_BUT_DRAG_MULTI) {
+ /* pass */
+ }
+ else
+# endif
+ if (data->select_others.elems_len == 0) {
+ wmWindow *win = CTX_wm_window(C);
+ /* may have been enabled before activating */
+ if (data->select_others.is_enabled || IS_ALLSELECT_EVENT(win->eventstate)) {
+ ui_selectcontext_begin(C, but, &data->select_others);
+ data->select_others.is_enabled = true;
+ }
+ }
+ if (data->select_others.elems_len == 0) {
+ /* dont check again */
+ data->select_others.elems_len = -1;
+ }
+#endif
}
/* ensures we are writing actual values */
@@ -1629,7 +2014,6 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
ui_apply_but_BUT(C, but, data);
break;
case UI_BTYPE_TEXT:
- case UI_BTYPE_SEARCH_MENU_UNLINK:
case UI_BTYPE_SEARCH_MENU:
ui_apply_but_TEX(C, but, data);
break;
@@ -1705,7 +2089,7 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
if (data->multi_data.has_mbuts) {
if (data->multi_data.init == BUTTON_MULTI_INIT_ENABLE) {
if (data->cancel) {
- ui_multibut_restore(data, block);
+ ui_multibut_restore(C, data, block);
}
else {
ui_multibut_states_apply(C, data, block);
@@ -1714,6 +2098,15 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
}
#endif
+#ifdef USE_ALLSELECT
+ ui_selectcontext_apply(C, but, &data->select_others, data->value, data->origvalue);
+#endif
+
+ if (data->cancel) {
+ data->origvalue = 0.0;
+ zero_v3(data->origvec);
+ }
+
but->editstr = editstr;
but->editval = editval;
but->editvec = editvec;
@@ -1732,13 +2125,13 @@ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleB
for (wmd = drags->first; wmd; wmd = wmd->next) {
if (wmd->type == WM_DRAG_ID) {
/* align these types with UI_but_active_drop_name */
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
ID *id = (ID *)wmd->poin;
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
BLI_strncpy(data->str, id->name + 2, data->maxlen);
- if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_SEARCH_MENU)) {
but->changed = true;
ui_searchbox_update(C, data->searchbox, but, true);
}
@@ -1879,7 +2272,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
}
/* text/string and ID data */
- else if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ else if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
uiHandleButtonData *active_data = but->active;
if (but->poin == NULL && but->rnapoin.data == NULL) {
@@ -1899,7 +2292,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
else
BLI_strncpy(active_data->str, buf_paste, active_data->maxlen);
- if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (but->type == UI_BTYPE_SEARCH_MENU) {
/* else uiSearchboxData.active member is not updated [#26856] */
but->changed = true;
ui_searchbox_update(C, data->searchbox, but, true);
@@ -1974,15 +2367,17 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
}
}
-/* ************************ password text ******************************
+/**
+ * Password Text
+ * =============
*
* Functions to convert password strings that should not be displayed
- * to asterisk representation (e.g. mysecretpasswd -> *************)
+ * to asterisk representation (e.g. 'mysecretpasswd' -> '*************')
*
* It converts every UTF-8 character to an asterisk, and also remaps
* the cursor position and selection start/end.
*
- * Note: remaping is used, because password could contain UTF-8 characters.
+ * \note: remaping is used, because password could contain UTF-8 characters.
*
*/
@@ -2092,7 +2487,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con
BLI_strncpy(origstr, but->editstr, data->maxlen);
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
if (but->flag & UI_HAS_ICON) {
startx += UI_DPI_ICON_SIZE / aspect;
}
@@ -2182,11 +2577,13 @@ static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data,
ui_but_update(but);
}
-/* this is used for both utf8 and ascii, its meant to be used for single keys,
+/**
+ * This is used for both utf8 and ascii, its meant to be used for single keys,
* notice the buffer is either copied or not, so its not suitable for pasting in
* - campbell */
-static bool ui_textedit_type_buf(uiBut *but, uiHandleButtonData *data,
- const char *utf8_buf, int utf8_buf_len)
+static bool ui_textedit_type_buf(
+ uiBut *but, uiHandleButtonData *data,
+ const char *utf8_buf, int utf8_buf_len)
{
char *str;
int len;
@@ -2230,8 +2627,9 @@ static bool ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char as
return ui_textedit_type_buf(but, data, buf, 1);
}
-static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, strCursorJumpDirection direction,
- const bool select, strCursorJumpType jump)
+static void ui_textedit_move(
+ uiBut *but, uiHandleButtonData *data, strCursorJumpDirection direction,
+ const bool select, strCursorJumpType jump)
{
const char *str = data->str;
const int len = strlen(str);
@@ -2447,6 +2845,18 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in
}
#ifdef WITH_INPUT_IME
+/* test if the translation context allows IME input - used to
+ * avoid weird character drawing if IME inputs non-ascii chars */
+static bool ui_ime_is_lang_supported(void)
+{
+ const char *uilng = BLF_lang_get();
+ const bool is_lang_supported = STREQ(uilng, "zh_CN") ||
+ STREQ(uilng, "zh_TW") ||
+ STREQ(uilng, "ja_JP");
+
+ return ((U.transopts & USER_DOTRANSLATE) && is_lang_supported);
+}
+
/* enable ime, and set up uibut ime data */
static void ui_textedit_ime_begin(wmWindow *win, uiBut *UNUSED(but))
{
@@ -2477,8 +2887,7 @@ void ui_but_ime_reposition(uiBut *but, int x, int y, bool complete)
wm_window_IME_begin(but->active->window, x, y - 4, 0, 0, complete);
}
-/* should be ui_but_ime_data_get */
-wmIMEData *ui_but_get_ime_data(uiBut *but)
+wmIMEData *ui_but_ime_data_get(uiBut *but)
{
if (but->active && but->active->window) {
return but->active->window->ime_data;
@@ -2512,6 +2921,16 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
}
#endif
+#ifdef USE_ALLSELECT
+ if (is_num_but) {
+ if (IS_ALLSELECT_EVENT(win->eventstate)) {
+ data->select_others.is_enabled = true;
+ data->select_others.is_copy = true;
+
+ }
+ }
+#endif
+
/* retrieve string */
data->maxlen = ui_but_string_get_max_length(but);
data->str = MEM_callocN(sizeof(char) * data->maxlen + 1, "textedit str");
@@ -2539,7 +2958,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
but->selend = len;
/* optional searchbox */
- if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (but->type == UI_BTYPE_SEARCH_MENU) {
data->searchbox = ui_searchbox_create(C, data->region, but);
ui_searchbox_update(C, data->searchbox, but, true); /* true = reset */
}
@@ -2552,7 +2971,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
WM_cursor_modal_set(win, BC_TEXTEDITCURSOR);
#ifdef WITH_INPUT_IME
- if (is_num_but == false) {
+ if (is_num_but == false && ui_ime_is_lang_supported()) {
ui_textedit_ime_begin(win, but);
}
#endif
@@ -2789,6 +3208,9 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
ui_searchbox_event(C, data->searchbox, but, event);
break;
}
+ if (event->type == WHEELDOWNMOUSE) {
+ break;
+ }
/* fall-through */
case ENDKEY:
ui_textedit_move(but, data, STRCUR_DIR_NEXT,
@@ -2804,6 +3226,9 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
ui_searchbox_event(C, data->searchbox, but, event);
break;
}
+ if (event->type == WHEELUPMOUSE) {
+ break;
+ }
/* fall-through */
case HOMEKEY:
ui_textedit_move(but, data, STRCUR_DIR_PREV,
@@ -2854,8 +3279,6 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
if (autocomplete == AUTOCOMPLETE_FULL_MATCH)
button_activate_state(C, but, BUTTON_STATE_EXIT);
-
- update = true; /* do live update for tab key */
}
/* the hotkey here is not well defined, was G.qual so we check all */
else if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
@@ -2934,7 +3357,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
#endif
if (changed) {
- /* only update when typing for TAB key */
+ /* only do live update when but flag request it (UI_BUT_TEXTEDIT_UPDATE). */
if (update && data->interactive) {
ui_apply_but(C, block, but, data, true);
}
@@ -3092,6 +3515,15 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
data->menu->popup = but->block->handle->popup;
}
+#ifdef USE_ALLSELECT
+ {
+ wmWindow *win = CTX_wm_window(C);
+ if (IS_ALLSELECT_EVENT(win->eventstate)) {
+ data->select_others.is_enabled = true;
+ }
+ }
+#endif
+
/* this makes adjacent blocks auto open from now on */
//if (but->block->auto_open == 0) but->block->auto_open = 1;
}
@@ -3121,9 +3553,13 @@ int ui_but_menu_direction(uiBut *but)
return 0;
}
-/* Hack for uiList UI_BTYPE_LISTROW buttons to "give" events to overlaying UI_BTYPE_TEXT buttons (cltr-clic rename feature & co). */
-static uiBut *ui_but_list_row_text_activate(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event,
- uiButtonActivateType activate_type)
+/**
+ * Hack for #uiList #UI_BTYPE_LISTROW buttons to "give" events to overlaying #UI_BTYPE_TEXT buttons
+ * (Ctrl-Click rename feature & co).
+ */
+static uiBut *ui_but_list_row_text_activate(
+ bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event,
+ uiButtonActivateType activate_type)
{
ARegion *ar = CTX_wm_region(C);
uiBut *labelbut = ui_but_find_mouse_over_ex(ar, event->x, event->y, true);
@@ -3293,9 +3729,11 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
+ uiButExtraIconType extra_icon_type;
+
/* unlink icon is on right */
- if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS &&
- ui_but_is_search_unlink_visible(but))
+ if ((ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY)) &&
+ ((extra_icon_type = ui_but_icon_extra_get(but)) != UI_BUT_ICONEXTRA_NONE))
{
ARegion *ar = data->region;
rcti rect;
@@ -3306,14 +3744,29 @@ static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHa
BLI_rcti_rctf_copy(&rect, &but->rect);
rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect));
+ /* handle click on unlink/eyedropper icon */
if (BLI_rcti_isect_pt(&rect, x, y)) {
- /* most likely NULL, but let's check, and give it temp zero string */
- if (data->str == NULL)
- data->str = MEM_callocN(1, "temp str");
- data->str[0] = 0;
+ /* doing this on KM_PRESS calls eyedropper after clicking unlink icon */
+ if (event->val == KM_RELEASE) {
+ /* unlink */
+ if (extra_icon_type == UI_BUT_ICONEXTRA_UNLINK) {
+ /* most likely NULL, but let's check, and give it temp zero string */
+ if (data->str == NULL) {
+ data->str = MEM_callocN(1, "temp str");
+ }
+ data->str[0] = 0;
- ui_apply_but_TEX(C, but, data);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
+ ui_apply_but_TEX(C, but, data);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ /* eyedropper */
+ else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
+ WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL);
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
return WM_UI_HANDLER_BREAK;
}
@@ -3352,7 +3805,7 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons
button_activate_state(C, but, BUTTON_STATE_EXIT);
return WM_UI_HANDLER_BREAK;
}
- else if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
+ else if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
/* Support alt+wheel on expanded enum rows */
if (but->type == UI_BTYPE_ROW) {
const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1;
@@ -3448,8 +3901,9 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con
}
/* var names match ui_numedit_but_NUM */
-static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, float softmax, float softrange,
- const enum eSnapType snap)
+static float ui_numedit_apply_snapf(
+ uiBut *but, float tempf, float softmin, float softmax, float softrange,
+ const enum eSnapType snap)
{
if (tempf == softmin || tempf == softmax || snap == SNAP_OFF) {
/* pass */
@@ -3477,15 +3931,25 @@ static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, floa
softrange /= fac;
}
+ /* workaround, too high snapping values */
+ /* snapping by 10's for float buttons is quite annoying (location, scale...),
+ * but allow for rotations */
+ if ((softrange > 2100.0f)) {
+ int unit_type = UI_but_unit_type_get(but);
+ if (!ELEM(unit_type, PROP_UNIT_ROTATION)) {
+ softrange = 20.0f;
+ }
+ }
+
if (snap == SNAP_ON) {
- if (softrange < 2.10f) tempf = 0.1f * floorf(10.0f * tempf);
- else if (softrange < 21.0f) tempf = floorf(tempf);
- else tempf = 10.0f * floorf(tempf / 10.0f);
+ if (softrange < 2.10f) tempf = roundf(tempf * 10.0f) * 0.1f;
+ else if (softrange < 21.0f) tempf = roundf(tempf);
+ else tempf = roundf(tempf * 0.1f) * 10.0f;
}
else if (snap == SNAP_ON_SMALL) {
- if (softrange < 2.10f) tempf = 0.01f * floorf(100.0f * tempf);
- else if (softrange < 21.0f) tempf = 0.1f * floorf(10.0f * tempf);
- else tempf = floor(tempf);
+ if (softrange < 2.10f) tempf = roundf(tempf * 100.0f) * 0.01f;
+ else if (softrange < 21.0f) tempf = roundf(tempf * 10.0f) * 0.1f;
+ else tempf = roundf(tempf);
}
else {
BLI_assert(0);
@@ -3498,8 +3962,9 @@ static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, floa
return tempf;
}
-static float ui_numedit_apply_snap(int temp, float softmin, float softmax,
- const enum eSnapType snap)
+static float ui_numedit_apply_snap(
+ int temp, float softmin, float softmax,
+ const enum eSnapType snap)
{
if (temp == softmin || temp == softmax)
return temp;
@@ -3518,9 +3983,10 @@ static float ui_numedit_apply_snap(int temp, float softmin, float softmax,
return temp;
}
-static bool ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data,
- int mx,
- const enum eSnapType snap, float fac)
+static bool ui_numedit_but_NUM(
+ uiBut *but, uiHandleButtonData *data,
+ int mx,
+ const enum eSnapType snap, float fac)
{
float deler, tempf, softmin, softmax, softrange;
int lvalue, temp;
@@ -3636,7 +4102,7 @@ static bool ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data,
if (!is_float) {
- temp = floorf(tempf + 0.5f);
+ temp = iroundf(tempf);
temp = ui_numedit_apply_snap(temp, softmin, softmax, snap);
@@ -3689,11 +4155,11 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
/* XXX hardcoded keymap check.... */
if (type == MOUSEPAN && event->alt)
retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */
- else if (type == WHEELDOWNMOUSE && event->alt) {
+ else if (type == WHEELDOWNMOUSE && event->ctrl) {
mx = but->rect.xmin;
click = 1;
}
- else if (type == WHEELUPMOUSE && event->alt) {
+ else if (type == WHEELUPMOUSE && event->ctrl) {
mx = but->rect.xmax;
click = 1;
}
@@ -3759,7 +4225,6 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
fac = 1.0f;
if (event->shift) fac /= 10.0f;
- if (event->alt) fac /= 20.0f;
if (ui_numedit_but_NUM(but, data, (ui_but_is_cursor_warp(but) ? screen_mx : mx), snap, fac))
ui_numedit_apply(C, block, but, data);
@@ -3854,9 +4319,10 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
return retval;
}
-static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
- int mx, const bool is_horizontal,
- const bool snap, const bool shift)
+static bool ui_numedit_but_SLI(
+ uiBut *but, uiHandleButtonData *data,
+ int mx, const bool is_horizontal,
+ const bool snap, const bool shift)
{
float deler, f, tempf, softmin, softmax, softrange;
int temp, lvalue;
@@ -3909,7 +4375,7 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
tempf = softmin + f * softrange;
- temp = floorf(tempf + 0.5f);
+ temp = iroundf(tempf);
if (snap) {
if (tempf == softmin || tempf == softmax) {
@@ -3919,14 +4385,14 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
if (shift) {
if (tempf == softmin || tempf == softmax) {}
- else if (softmax - softmin < 2.10f) tempf = 0.01f * floorf(100.0f * tempf);
- else if (softmax - softmin < 21.0f) tempf = 0.1f * floorf(10.0f * tempf);
- else tempf = floorf(tempf);
+ else if (softrange < 2.10f) tempf = roundf(tempf * 100.0f) * 0.01f;
+ else if (softrange < 21.0f) tempf = roundf(tempf * 10.0f) * 0.1f;
+ else tempf = roundf(tempf);
}
else {
- if (softmax - softmin < 2.10f) tempf = 0.1f * floorf(10.0f * tempf);
- else if (softmax - softmin < 21.0f) tempf = floorf(tempf);
- else tempf = 10.0f * floorf(tempf / 10.0f);
+ if (softrange < 2.10f) tempf = roundf(tempf * 10.0f) * 0.1f;
+ else if (softrange < 21.0f) tempf = roundf(tempf);
+ else tempf = roundf(tempf * 0.1f) * 10.0f;
}
}
else {
@@ -3936,7 +4402,7 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
}
if (!ui_but_is_float(but)) {
- lvalue = floor(data->value + 0.5);
+ lvalue = round(data->value);
CLAMP(temp, softmin, softmax);
@@ -3978,11 +4444,11 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
/* XXX hardcoded keymap check.... */
if (type == MOUSEPAN && event->alt)
retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */
- else if (type == WHEELDOWNMOUSE && event->alt) {
+ else if (type == WHEELDOWNMOUSE && event->ctrl) {
mx = but->rect.xmin;
click = 2;
}
- else if (type == WHEELUPMOUSE && event->alt) {
+ else if (type == WHEELUPMOUSE && event->ctrl) {
mx = but->rect.xmax;
click = 2;
}
@@ -3991,6 +4457,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
retval = WM_UI_HANDLER_BREAK;
}
+#ifndef USE_ALLSELECT
/* alt-click on sides to get "arrows" like in UI_BTYPE_NUM buttons, and match wheel usage above */
else if (event->type == LEFTMOUSE && event->alt) {
int halfpos = BLI_rctf_cent_x(&but->rect);
@@ -4000,6 +4467,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
else
mx = but->rect.xmax;
}
+#endif
else if (event->type == LEFTMOUSE) {
data->dragstartx = mx;
data->draglastx = mx;
@@ -4286,7 +4754,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
return WM_UI_HANDLER_BREAK;
}
else if (but->type == UI_BTYPE_MENU) {
- if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
+ if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1;
data->value = ui_but_menu_step(but, direction);
@@ -4342,9 +4810,10 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
return WM_UI_HANDLER_CONTINUE;
}
-static bool ui_numedit_but_UNITVEC(uiBut *but, uiHandleButtonData *data,
- int mx, int my,
- const enum eSnapType snap)
+static bool ui_numedit_but_UNITVEC(
+ uiBut *but, uiHandleButtonData *data,
+ int mx, int my,
+ const enum eSnapType snap)
{
float dx, dy, rad, radsq, mrad, *fp;
int mdx, mdy;
@@ -4410,7 +4879,7 @@ static bool ui_numedit_but_UNITVEC(uiBut *but, uiHandleButtonData *data,
* do this in "angle" space - this gives increments of same size */
for (i = 0; i < 3; i++) {
angle = asinf(fp[i]);
- angle_snap = floorf(0.5f + (angle / snap_steps_angle)) * snap_steps_angle;
+ angle_snap = roundf((angle / snap_steps_angle)) * snap_steps_angle;
fp[i] = sinf(angle_snap);
}
normalize_v3(fp);
@@ -4460,7 +4929,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
return WM_UI_HANDLER_BREAK;
}
- else if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
+ else if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
ColorPicker *cpicker = but->custom_data;
float hsv_static[3] = {0.0f};
float *hsv = cpicker ? cpicker->color_data : hsv_static;
@@ -4494,6 +4963,12 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
BKE_palette_color_remove(palette, color);
button_activate_state(C, but, BUTTON_STATE_EXIT);
+
+ /* this is risky. it works OK for now,
+ * but if it gives trouble we should delay execution */
+ but->rnapoin = PointerRNA_NULL;
+ but->rnaprop = NULL;
+
return WM_UI_HANDLER_BREAK;
}
}
@@ -4638,9 +5113,10 @@ static void ui_color_picker_to_rgb_HSVCUBE_v(uiBut *but, const float hsv[3], flo
hsv_to_rgb_v(hsv, rgb);
}
-static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
- int mx, int my,
- const enum eSnapType snap, const bool shift)
+static bool ui_numedit_but_HSVCUBE(
+ uiBut *but, uiHandleButtonData *data,
+ int mx, int my,
+ const enum eSnapType snap, const bool shift)
{
ColorPicker *cpicker = but->custom_data;
float *hsv = cpicker->color_data;
@@ -4699,8 +5175,8 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
switch ((int)but->a1) {
case UI_GRAD_SV:
- hsv[2] = x;
- hsv[1] = y;
+ hsv[1] = x;
+ hsv[2] = y;
break;
case UI_GRAD_HV:
hsv[0] = x;
@@ -4757,9 +5233,10 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
return changed;
}
-static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
- const wmNDOFMotionData *ndof,
- const enum eSnapType snap, const bool shift)
+static void ui_ndofedit_but_HSVCUBE(
+ uiBut *but, uiHandleButtonData *data,
+ const wmNDOFMotionData *ndof,
+ const enum eSnapType snap, const bool shift)
{
ColorPicker *cpicker = but->custom_data;
float *hsv = cpicker->color_data;
@@ -4777,8 +5254,8 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
switch ((int)but->a1) {
case UI_GRAD_SV:
- hsv[2] += ndof->rvec[2] * sensitivity;
- hsv[1] += ndof->rvec[0] * sensitivity;
+ hsv[1] += ndof->rvec[2] * sensitivity;
+ hsv[2] += ndof->rvec[0] * sensitivity;
break;
case UI_GRAD_HV:
hsv[0] += ndof->rvec[2] * sensitivity;
@@ -4922,9 +5399,10 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
return WM_UI_HANDLER_CONTINUE;
}
-static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
- float mx, float my,
- const enum eSnapType snap, const bool shift)
+static bool ui_numedit_but_HSVCIRCLE(
+ uiBut *but, uiHandleButtonData *data,
+ float mx, float my,
+ const enum eSnapType snap, const bool shift)
{
rcti rect;
bool changed = true;
@@ -5019,9 +5497,10 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
return changed;
}
-static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
- const wmNDOFMotionData *ndof,
- const enum eSnapType snap, const bool shift)
+static void ui_ndofedit_but_HSVCIRCLE(
+ uiBut *but, uiHandleButtonData *data,
+ const wmNDOFMotionData *ndof,
+ const enum eSnapType snap, const bool shift)
{
ColorPicker *cpicker = but->custom_data;
float *hsv = cpicker->color_data;
@@ -5280,7 +5759,8 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandle
return WM_UI_HANDLER_CONTINUE;
}
-static bool ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData *data,
+static bool ui_numedit_but_CURVE(
+ uiBlock *block, uiBut *but, uiHandleButtonData *data,
int evtx, int evty,
bool snap, const bool shift)
{
@@ -5330,8 +5810,8 @@ static bool ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData
cmp[a].x += fx;
cmp[a].y += fy;
if (snap) {
- cmp[a].x = 0.125f * floorf(0.5f + 8.0f * cmp[a].x);
- cmp[a].y = 0.125f * floorf(0.5f + 8.0f * cmp[a].y);
+ cmp[a].x = 0.125f * roundf(8.0f * cmp[a].x);
+ cmp[a].y = 0.125f * roundf(8.0f * cmp[a].y);
}
if (cmp[a].x != origx || cmp[a].y != origy)
moved_point = true;
@@ -5714,9 +6194,10 @@ static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, con
return WM_UI_HANDLER_CONTINUE;
}
-static bool ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data,
- int mx, int my,
- const bool shift)
+static bool ui_numedit_but_TRACKPREVIEW(
+ bContext *C, uiBut *but, uiHandleButtonData *data,
+ int mx, int my,
+ const bool shift)
{
MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
bool changed = true;
@@ -5925,7 +6406,7 @@ static void menu_add_shortcut_cancel(struct bContext *C, void *arg1)
static void popup_change_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
{
uiBut *but = (uiBut *)arg1;
- button_timers_tooltip_remove(C, but);
+ UI_but_tooltip_timer_remove(C, but);
UI_popup_block_invoke(C, menu_change_shortcut, but);
}
@@ -5946,7 +6427,7 @@ static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
{
uiBut *but = (uiBut *)arg1;
- button_timers_tooltip_remove(C, but);
+ UI_but_tooltip_timer_remove(C, but);
UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but);
}
@@ -5995,7 +6476,7 @@ static bool ui_but_menu(bContext *C, uiBut *but)
return false;
}
- button_timers_tooltip_remove(C, but);
+ UI_but_tooltip_timer_remove(C, but);
/* highly unlikely getting the label ever fails */
UI_but_string_info_get(C, but, &label, NULL);
@@ -6064,7 +6545,7 @@ static bool ui_but_menu(bContext *C, uiBut *but)
}
}
- if (but->flag & UI_BUT_ANIMATED) {
+ if ((but->flag & UI_BUT_ANIMATED) && (but->rnapoin.type != &RNA_NlaStrip)) {
if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 1);
@@ -6211,7 +6692,7 @@ static bool ui_but_menu(bContext *C, uiBut *but)
}
/* Show header tools for header buttons. */
- {
+ if (ui_block_is_menu(but->block) == false) {
ARegion *ar = CTX_wm_region(C);
if (ar && (ar->regiontype == RGN_TYPE_HEADER)) {
uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
@@ -6223,14 +6704,9 @@ static bool ui_but_menu(bContext *C, uiBut *but)
char buf[512];
PointerRNA ptr_props;
- if (but->rnapoin.data && but->rnaprop) {
- BLI_snprintf(buf, sizeof(buf), "%s.%s",
- RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop));
-
- WM_operator_properties_create(&ptr_props, "WM_OT_doc_view_manual");
- RNA_string_set(&ptr_props, "doc_id", buf);
- uiItemFullO(layout, "WM_OT_doc_view_manual", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"),
- ICON_NONE, ptr_props.data, WM_OP_EXEC_DEFAULT, 0);
+ if (UI_but_online_manual_id(but, buf, sizeof(buf))) {
+ uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"),
+ ICON_NONE, "WM_OT_doc_view_manual_ui_context");
WM_operator_properties_create(&ptr_props, "WM_OT_doc_view");
RNA_string_set(&ptr_props, "doc_id", buf);
@@ -6246,30 +6722,6 @@ static bool ui_but_menu(bContext *C, uiBut *but)
uiItemFullO(layout, "WM_OT_doc_edit", "Submit Description", ICON_NONE, ptr_props.data, WM_OP_INVOKE_DEFAULT, 0);
#endif
}
- else if (but->optype) {
- WM_operator_py_idname(buf, but->optype->idname);
-
-
- WM_operator_properties_create(&ptr_props, "WM_OT_doc_view_manual");
- RNA_string_set(&ptr_props, "doc_id", buf);
- uiItemFullO(layout, "WM_OT_doc_view_manual", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"),
- ICON_NONE, ptr_props.data, WM_OP_EXEC_DEFAULT, 0);
-
- WM_operator_properties_create(&ptr_props, "WM_OT_doc_view");
- RNA_string_set(&ptr_props, "doc_id", buf);
- uiItemFullO(layout, "WM_OT_doc_view", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Online Python Reference"),
- ICON_NONE, ptr_props.data, WM_OP_EXEC_DEFAULT, 0);
-
- /* XXX inactive option, not for public! */
-#if 0
- WM_operator_properties_create(&ptr_props, "WM_OT_doc_edit");
- RNA_string_set(&ptr_props, "doc_id", buf);
- RNA_string_set(&ptr_props, "doc_new", but->optype->description);
-
- uiItemFullO(layout, "WM_OT_doc_edit", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Submit Description"),
- ICON_NONE, ptr_props.data, WM_OP_INVOKE_DEFAULT, 0);
-#endif
- }
}
/* perhaps we should move this into (G.debug & G_DEBUG) - campbell */
@@ -6325,7 +6777,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
WM_operator_name_call(C, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, NULL);
return WM_UI_HANDLER_BREAK;
}
- else if (but->type == UI_BTYPE_SEARCH_MENU_UNLINK) {
+ else if ((but->type == UI_BTYPE_SEARCH_MENU) &&
+ (but->flag & UI_BUT_SEARCH_UNLINK))
+ {
if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_POINTER) {
StructRNA *type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
const short idcode = RNA_type_to_ID_code(type);
@@ -6482,11 +6936,16 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
break;
case UI_BTYPE_TEXT:
case UI_BTYPE_SEARCH_MENU:
+ if ((but->type == UI_BTYPE_SEARCH_MENU) &&
+ (but->flag & UI_BUT_SEARCH_UNLINK))
+ {
+ retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
+ if (retval & WM_UI_HANDLER_BREAK) {
+ break;
+ }
+ }
retval = ui_do_but_TEX(C, block, but, data, event);
break;
- case UI_BTYPE_SEARCH_MENU_UNLINK:
- retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
- break;
case UI_BTYPE_MENU:
case UI_BTYPE_BLOCK:
case UI_BTYPE_PULLDOWN:
@@ -6586,8 +7045,13 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
/* just to be sure, check we're dragging more hoz then virt */
abs(event->prevx - event->x) > abs(event->prevy - event->y)))
{
- ui_multibut_states_create(but, data);
- data->multi_data.init = BUTTON_MULTI_INIT_ENABLE;
+ if (data->multi_data.has_mbuts) {
+ ui_multibut_states_create(but, data);
+ data->multi_data.init = BUTTON_MULTI_INIT_ENABLE;
+ }
+ else {
+ data->multi_data.init = BUTTON_MULTI_INIT_DISABLE;
+ }
}
}
@@ -6725,7 +7189,7 @@ bool UI_but_active_drop_name(bContext *C)
uiBut *but = ui_but_find_active_in_region(ar);
if (but) {
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK))
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU))
return 1;
}
@@ -6840,13 +7304,6 @@ static bool ui_but_is_interactive(const uiBut *but, const bool labeledit)
return true;
}
-bool ui_but_is_search_unlink_visible(const uiBut *but)
-{
- BLI_assert(but->type == UI_BTYPE_SEARCH_MENU_UNLINK);
- return ((but->editstr == NULL) &&
- (but->drawstr[0] != '\0'));
-}
-
/* x and y are only used in case event is NULL... */
static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, const bool labeledit)
{
@@ -6934,7 +7391,8 @@ static bool button_modal_state(uiHandleButtonState state)
BUTTON_STATE_MENU_OPEN);
}
-static void button_timers_tooltip_remove(bContext *C, uiBut *but)
+/* removes tooltip timer from active but (meaning tooltip is disabled until it's reenabled again) */
+void UI_but_tooltip_timer_remove(bContext *C, uiBut *but)
{
uiHandleButtonData *data;
@@ -7018,7 +7476,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
}
else {
but->flag |= UI_SELECT;
- button_timers_tooltip_remove(C, but);
+ UI_but_tooltip_timer_remove(C, but);
}
/* text editing */
@@ -7080,7 +7538,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
if (!(but->block->handle && but->block->handle->popup)) {
if (button_modal_state(state)) {
if (!button_modal_state(data->state))
- WM_event_add_ui_handler(C, &data->window->modalhandlers, ui_handler_region_menu, NULL, data, false);
+ WM_event_add_ui_handler(C, &data->window->modalhandlers, ui_handler_region_menu, NULL, data, 0);
}
else {
if (button_modal_state(data->state)) {
@@ -7125,7 +7583,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
copy_v2_fl(data->ungrab_mval, FLT_MAX);
#endif
- if (ELEM(but->type, UI_BTYPE_CURVE, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_CURVE, UI_BTYPE_SEARCH_MENU)) {
/* XXX curve is temp */
}
else {
@@ -7185,8 +7643,9 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
}
}
-static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *data,
- const bool mousemove, const bool onfree)
+static void button_activate_exit(
+ bContext *C, uiBut *but, uiHandleButtonData *data,
+ const bool mousemove, const bool onfree)
{
uiBlock *block = but->block;
uiBut *bt;
@@ -7258,6 +7717,10 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da
if (data->origstr)
MEM_freeN(data->origstr);
+#ifdef USE_ALLSELECT
+ ui_selectcontext_end(but, &data->select_others);
+#endif
+
/* redraw (data is but->active!) */
ED_region_tag_redraw(data->region);
@@ -7464,7 +7927,7 @@ void UI_context_update_anim_flag(const bContext *C)
/************** handle activating a button *************/
-static uiBut *uit_but_find_open_event(ARegion *ar, const wmEvent *event)
+static uiBut *ui_but_find_open_event(ARegion *ar, const wmEvent *event)
{
uiBlock *block;
uiBut *but;
@@ -7495,7 +7958,7 @@ static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *ar)
}
}
else if (event->type == EVT_BUT_OPEN) {
- but = uit_but_find_open_event(ar, event);
+ but = ui_but_find_open_event(ar, event);
if (but) {
button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
ui_do_button(C, but->block, but, event);
@@ -7599,7 +8062,8 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
uiBut *but_other = ui_but_find_mouse_over(ar, event);
bool exit = false;
- if ((!ui_block_is_menu(block) || ui_block_is_pie_menu(but->block)) &&
+ /* always deactivate button for pie menus, else moving to blank space will leave activated */
+ if ((!ui_block_is_menu(block) || ui_block_is_pie_menu(block)) &&
!ui_but_contains_point_px(ar, but, event->x, event->y))
{
exit = true;
@@ -7647,7 +8111,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
case WHEELDOWNMOUSE:
case MIDDLEMOUSE:
case MOUSEPAN:
- button_timers_tooltip_remove(C, but);
+ UI_but_tooltip_timer_remove(C, but);
/* fall-through */
default:
/* handle button type specific events */
@@ -7808,7 +8272,7 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
if (val == KM_PRESS) {
if (ELEM(type, UPARROWKEY, DOWNARROWKEY) ||
- ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt)))
+ ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->ctrl)))
{
const int value_orig = RNA_property_int_get(&but->rnapoin, but->rnaprop);
int value, min, max, inc;
@@ -7958,13 +8422,14 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u
/* ************************* menu handling *******************************/
-/* function used to prevent loosing the open menu when using nested pulldowns,
+/**
+ * Function used to prevent loosing the open menu when using nested pulldowns,
* when moving mouse towards the pulldown menu over other buttons that could
* steal the highlight from the current button, only checks:
*
* - while mouse moves in triangular area defined old mouse position and
- * left/right side of new menu
- * - only for 1 second
+ * left/right side of new menu.
+ * - only for 1 second.
*/
static void ui_mouse_motion_towards_init_ex(uiPopupBlockHandle *menu, const int xy[2], const bool force)
@@ -7993,8 +8458,9 @@ static void ui_mouse_motion_towards_reinit(uiPopupBlockHandle *menu, const int x
ui_mouse_motion_towards_init_ex(menu, xy, true);
}
-static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *menu, const int xy[2],
- const bool use_wiggle_room)
+static bool ui_mouse_motion_towards_check(
+ uiBlock *block, uiPopupBlockHandle *menu, const int xy[2],
+ const bool use_wiggle_room)
{
float p1[2], p2[2], p3[2], p4[2];
float oldp[2] = {menu->towards_xy[0], menu->towards_xy[1]};
@@ -8182,8 +8648,9 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt)
*
* Without this keyboard navigation from menu's wont work.
*/
-static bool ui_menu_pass_event_to_parent_if_nonactive(uiPopupBlockHandle *menu, const uiBut *but,
- const int level, const int retval)
+static bool ui_menu_pass_event_to_parent_if_nonactive(
+ uiPopupBlockHandle *menu, const uiBut *but,
+ const int level, const int retval)
{
if ((level != 0) && (but == NULL)) {
menu->menuretval = UI_RETURN_OUT | UI_RETURN_OUT_PARENT;
@@ -8553,7 +9020,7 @@ static int ui_handle_menu_event(
ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE);
}
else {
- printf("%s: error, but->menu_key type: %d\n", __func__, but->type);
+ printf("%s: error, but->menu_key type: %u\n", __func__, but->type);
}
break;
@@ -8622,7 +9089,7 @@ static int ui_handle_menu_event(
{
if (!but || !ui_but_contains_point_px(ar, but, event->x, event->y)) {
if (but) {
- button_timers_tooltip_remove(C, but);
+ UI_but_tooltip_timer_remove(C, but);
}
menu->is_grab = true;
@@ -8701,6 +9168,9 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo
block = ar->uiblocks.first;
but = ui_but_find_active_in_region(ar);
+
+ BLI_assert(but);
+
data = but->active;
submenu = data->menu;
@@ -9100,7 +9570,7 @@ static int ui_handle_menus_recursive(
/* now handle events for our own menu */
if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
- const bool do_but_search = (but && ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK));
+ const bool do_but_search = (but && (but->type == UI_BTYPE_SEARCH_MENU));
if (submenu && submenu->menuretval) {
const bool do_ret_out_parent = (submenu->menuretval & UI_RETURN_OUT_PARENT) != 0;
retval = ui_handle_menu_return_submenu(C, event, menu);
@@ -9384,12 +9854,12 @@ static void ui_popup_handler_remove(bContext *C, void *userdata)
void UI_region_handlers_add(ListBase *handlers)
{
WM_event_remove_ui_handler(handlers, ui_region_handler, ui_region_handler_remove, NULL, false);
- WM_event_add_ui_handler(NULL, handlers, ui_region_handler, ui_region_handler_remove, NULL, false);
+ WM_event_add_ui_handler(NULL, handlers, ui_region_handler, ui_region_handler_remove, NULL, 0);
}
-void UI_popup_handlers_add(bContext *C, ListBase *handlers, uiPopupBlockHandle *popup, const bool accept_dbl_click)
+void UI_popup_handlers_add(bContext *C, ListBase *handlers, uiPopupBlockHandle *popup, const char flag)
{
- WM_event_add_ui_handler(C, handlers, ui_popup_handler, ui_popup_handler_remove, popup, accept_dbl_click);
+ WM_event_add_ui_handler(C, handlers, ui_popup_handler, ui_popup_handler_remove, popup, flag);
}
void UI_popup_handlers_remove(ListBase *handlers, uiPopupBlockHandle *popup)
@@ -9402,8 +9872,9 @@ void UI_popup_handlers_remove_all(bContext *C, ListBase *handlers)
WM_event_free_ui_handler_all(C, handlers, ui_popup_handler, ui_popup_handler_remove);
}
-bool UI_textbutton_activate_rna(const bContext *C, ARegion *ar,
- const void *rna_poin_data, const char *rna_prop_id)
+bool UI_textbutton_activate_rna(
+ const bContext *C, ARegion *ar,
+ const void *rna_poin_data, const char *rna_prop_id)
{
uiBlock *block;
uiBut *but = NULL;
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 679681cb372..db1eacf57dc 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -55,6 +55,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "IMB_thumbs.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -888,11 +889,9 @@ int UI_icon_get_height(int icon_id)
void UI_icons_init(int first_dyn_id)
{
-#ifdef WITH_HEADLESS
- (void)first_dyn_id;
-#else
- init_iconfile_list(&iconfilelist);
BKE_icons_init(first_dyn_id);
+#ifndef WITH_HEADLESS
+ init_iconfile_list(&iconfilelist);
init_internal_icons();
init_brush_icons();
init_matcap_icons();
@@ -904,10 +903,13 @@ void UI_icons_init(int first_dyn_id)
static int preview_render_size(enum eIconSizes size)
{
switch (size) {
- case ICON_SIZE_ICON: return 32;
- case ICON_SIZE_PREVIEW: return PREVIEW_DEFAULT_HEIGHT;
+ case ICON_SIZE_ICON:
+ return ICON_RENDER_DEFAULT_HEIGHT;
+ case ICON_SIZE_PREVIEW:
+ return PREVIEW_RENDER_DEFAULT_HEIGHT;
+ default:
+ return 0;
}
- return 0;
}
/* Create rect for the icon
@@ -923,12 +925,49 @@ static void icon_create_rect(struct PreviewImage *prv_img, enum eIconSizes size)
else if (!prv_img->rect[size]) {
prv_img->w[size] = render_size;
prv_img->h[size] = render_size;
- prv_img->changed[size] = 1;
+ prv_img->flag[size] |= PRV_CHANGED;
prv_img->changed_timestamp[size] = 0;
prv_img->rect[size] = MEM_callocN(render_size * render_size * sizeof(unsigned int), "prv_rect");
}
}
+void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool big)
+{
+ Icon *icon = BKE_icon_get(icon_id);
+
+ if (icon) {
+ DrawInfo *di = (DrawInfo *)icon->drawinfo;
+
+ if (!di) {
+ di = icon_create_drawinfo();
+
+ icon->drawinfo = di;
+ icon->drawinfo_free = UI_icons_free_drawinfo;
+ }
+
+ if (di) {
+ if (di->type == ICON_TYPE_PREVIEW) {
+ PreviewImage *prv = (icon->type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) : icon->obj;
+
+ if (prv) {
+ const int size = big ? ICON_SIZE_PREVIEW : ICON_SIZE_ICON;
+
+ if (!prv->use_deferred || prv->rect[size] || (prv->flag[size] & PRV_USER_EDITED)) {
+ return;
+ }
+
+ icon_create_rect(prv, size);
+
+ /* Always using job (background) version. */
+ ED_preview_icon_job(C, prv, NULL, prv->rect[size], prv->w[size], prv->h[size]);
+
+ prv->flag[size] &= ~PRV_CHANGED;
+ }
+ }
+ }
+ }
+}
+
/* only called when icon has changed */
/* only call with valid pointer from UI_icon_draw */
static void icon_set_image(
@@ -940,6 +979,11 @@ static void icon_set_image(
return;
}
+ if (prv_img->flag[size] & PRV_USER_EDITED) {
+ /* user-edited preview, do not auto-update! */
+ return;
+ }
+
icon_create_rect(prv_img, size);
if (use_job) {
@@ -951,7 +995,7 @@ static void icon_set_image(
scene = CTX_data_scene(C);
}
/* Immediate version */
- ED_preview_icon_render(scene, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]);
+ ED_preview_icon_render(CTX_data_main(C), scene, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]);
}
}
@@ -961,22 +1005,32 @@ PreviewImage *UI_icon_to_preview(int icon_id)
if (icon) {
DrawInfo *di = (DrawInfo *)icon->drawinfo;
- if (di && di->data.buffer.image) {
- ImBuf *bbuf;
-
- bbuf = IMB_ibImageFromMemory(di->data.buffer.image->datatoc_rect, di->data.buffer.image->datatoc_size, IB_rect, NULL, "<matcap buffer>");
- if (bbuf) {
- PreviewImage *prv = BKE_previewimg_create();
-
- prv->rect[0] = bbuf->rect;
+ if (di) {
+ if (di->type == ICON_TYPE_PREVIEW) {
+ PreviewImage *prv = (icon->type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) : icon->obj;
- prv->w[0] = bbuf->x;
- prv->h[0] = bbuf->y;
-
- bbuf->rect = NULL;
- IMB_freeImBuf(bbuf);
-
- return prv;
+ if (prv) {
+ return BKE_previewimg_copy(prv);
+ }
+ }
+ else if (di->data.buffer.image) {
+ ImBuf *bbuf;
+
+ bbuf = IMB_ibImageFromMemory(di->data.buffer.image->datatoc_rect, di->data.buffer.image->datatoc_size,
+ IB_rect, NULL, __func__);
+ if (bbuf) {
+ PreviewImage *prv = BKE_previewimg_create();
+
+ prv->rect[0] = bbuf->rect;
+
+ prv->w[0] = bbuf->x;
+ prv->h[0] = bbuf->y;
+
+ bbuf->rect = NULL;
+ IMB_freeImBuf(bbuf);
+
+ return prv;
+ }
}
}
}
@@ -987,6 +1041,10 @@ static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect),
unsigned int *rect, float alpha, const float rgb[3], const bool is_preview)
{
ImBuf *ima = NULL;
+ int draw_w = w;
+ int draw_h = h;
+ int draw_x = x;
+ int draw_y = y;
/* sanity check */
if (w <= 0 || h <= 0 || w > 2000 || h > 2000) {
@@ -1006,21 +1064,34 @@ static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect),
}
/* rect contains image in 'rendersize', we only scale if needed */
- if (rw != w && rh != h) {
+ if (rw != w || rh != h) {
+ /* preserve aspect ratio and center */
+ if (rw > rh) {
+ draw_w = w;
+ draw_h = (int)(((float)rh / (float)rw) * (float)w);
+ draw_y += (h - draw_h) / 2;
+ }
+ else if (rw < rh) {
+ draw_w = (int)(((float)rw / (float)rh) * (float)h);
+ draw_h = h;
+ draw_x += (w - draw_w) / 2;
+ }
+ /* if the image is squared, the draw_ initialization values are good */
+
/* first allocate imbuf for scaling and copy preview into it */
ima = IMB_allocImBuf(rw, rh, 32, IB_rect);
memcpy(ima->rect, rect, rw * rh * sizeof(unsigned int));
- IMB_scaleImBuf(ima, w, h); /* scale it */
+ IMB_scaleImBuf(ima, draw_w, draw_h); /* scale it */
rect = ima->rect;
}
/* draw */
if (is_preview) {
- glaDrawPixelsSafe(x, y, w, h, w, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ glaDrawPixelsSafe(draw_x, draw_y, draw_w, draw_h, draw_w, GL_RGBA, GL_UNSIGNED_BYTE, rect);
}
else {
- glRasterPos2f(x, y);
- glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ glRasterPos2f(draw_x, draw_y);
+ glDrawPixels(draw_w, draw_h, GL_RGBA, GL_UNSIGNED_BYTE, rect);
}
if (ima)
@@ -1037,8 +1108,9 @@ static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect),
}
}
-static void icon_draw_texture(float x, float y, float w, float h, int ix, int iy,
- int UNUSED(iw), int ih, float alpha, const float rgb[3])
+static void icon_draw_texture(
+ float x, float y, float w, float h, int ix, int iy,
+ int UNUSED(iw), int ih, float alpha, const float rgb[3])
{
float x1, x2, y1, y2;
@@ -1080,16 +1152,20 @@ static void icon_draw_texture(float x, float y, float w, float h, int ix, int iy
static int get_draw_size(enum eIconSizes size)
{
switch (size) {
- case ICON_SIZE_ICON: return ICON_DEFAULT_HEIGHT;
- case ICON_SIZE_PREVIEW: return PREVIEW_DEFAULT_HEIGHT;
+ case ICON_SIZE_ICON:
+ return ICON_DEFAULT_HEIGHT;
+ case ICON_SIZE_PREVIEW:
+ return PREVIEW_DEFAULT_HEIGHT;
+ default:
+ return 0;
}
- return 0;
}
-static void icon_draw_size(float x, float y, int icon_id, float aspect, float alpha, const float rgb[3],
- enum eIconSizes size, int draw_size, const bool UNUSED(nocreate), const bool is_preview)
+static void icon_draw_size(
+ float x, float y, int icon_id, float aspect, float alpha, const float rgb[3],
+ enum eIconSizes size, int draw_size, const bool UNUSED(nocreate), const bool is_preview)
{
bTheme *btheme = UI_GetTheme();
Icon *icon = NULL;
@@ -1145,15 +1221,21 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (di->type == ICON_TYPE_PREVIEW) {
- PreviewImage *pi = BKE_previewimg_get((ID *)icon->obj);
+ PreviewImage *pi = (icon->type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) : icon->obj;
if (pi) {
/* no create icon on this level in code */
if (!pi->rect[size]) return; /* something has gone wrong! */
/* preview images use premul alpha ... */
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- icon_draw_rect(x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], 1.0f, NULL, is_preview);
+ if (GLEW_VERSION_1_4) {
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ }
+ else {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ icon_draw_rect(x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, rgb, is_preview);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
}
@@ -1162,17 +1244,17 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
static void ui_id_preview_image_render_size(
const bContext *C, Scene *scene, ID *id, PreviewImage *pi, int size, const bool use_job)
{
- if ((pi->changed[size] || !pi->rect[size])) { /* changed only ever set by dynamic icons */
+ if (((pi->flag[size] & PRV_CHANGED) || !pi->rect[size])) { /* changed only ever set by dynamic icons */
/* create the rect if necessary */
icon_set_image(C, scene, id, pi, size, use_job);
- pi->changed[size] = 0;
+ pi->flag[size] &= ~PRV_CHANGED;
}
}
void UI_id_icon_render(const bContext *C, Scene *scene, ID *id, const bool big, const bool use_job)
{
- PreviewImage *pi = BKE_previewimg_get(id);
+ PreviewImage *pi = BKE_previewimg_id_ensure(id);
if (pi) {
if (big)
@@ -1184,7 +1266,7 @@ void UI_id_icon_render(const bContext *C, Scene *scene, ID *id, const bool big,
static void ui_id_brush_render(const bContext *C, ID *id)
{
- PreviewImage *pi = BKE_previewimg_get(id);
+ PreviewImage *pi = BKE_previewimg_id_ensure(id);
enum eIconSizes i;
if (!pi)
@@ -1193,9 +1275,9 @@ static void ui_id_brush_render(const bContext *C, ID *id)
for (i = 0; i < NUM_ICON_SIZES; i++) {
/* check if rect needs to be created; changed
* only set by dynamic icons */
- if ((pi->changed[i] || !pi->rect[i])) {
+ if (((pi->flag[i] & PRV_CHANGED) || !pi->rect[i])) {
icon_set_image(C, NULL, id, pi, i, true);
- pi->changed[i] = 0;
+ pi->flag[i] &= ~PRV_CHANGED;
}
}
}
@@ -1206,7 +1288,7 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id)
Brush *br = (Brush *)id;
if (br->flag & BRUSH_CUSTOM_ICON) {
- BKE_icon_getid(id);
+ BKE_icon_id_ensure(id);
ui_id_brush_render(C, id);
}
else {
@@ -1268,7 +1350,7 @@ int ui_id_icon_get(const bContext *C, ID *id, const bool big)
case ID_IM: /* fall through */
case ID_WO: /* fall through */
case ID_LA: /* fall through */
- iconid = BKE_icon_getid(id);
+ iconid = BKE_icon_id_ensure(id);
/* checks if not exists, or changed */
UI_id_icon_render(C, NULL, id, big, true);
break;
@@ -1317,8 +1399,9 @@ int UI_rnaptr_icon_get(bContext *C, PointerRNA *ptr, int rnaicon, const bool big
return rnaicon;
}
-static void icon_draw_at_size(float x, float y, int icon_id, float aspect, float alpha,
- enum eIconSizes size, const bool nocreate)
+static void icon_draw_at_size(
+ float x, float y, int icon_id, float aspect, float alpha,
+ enum eIconSizes size, const bool nocreate)
{
int draw_size = get_draw_size(size);
icon_draw_size(x, y, icon_id, aspect, alpha, NULL, size, draw_size, nocreate, false);
@@ -1356,8 +1439,8 @@ void UI_icon_draw_preview_aspect(float x, float y, int icon_id, float aspect)
icon_draw_at_size(x, y, icon_id, aspect, 1.0f, ICON_SIZE_PREVIEW, 0);
}
-void UI_icon_draw_preview_aspect_size(float x, float y, int icon_id, float aspect, int size)
+void UI_icon_draw_preview_aspect_size(float x, float y, int icon_id, float aspect, float alpha, int size)
{
- icon_draw_size(x, y, icon_id, aspect, 1.0f, NULL, ICON_SIZE_PREVIEW, size, false, true);
+ icon_draw_size(x, y, icon_id, aspect, alpha, NULL, ICON_SIZE_PREVIEW, size, false, true);
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 03816a255ad..9461547a164 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -40,11 +40,9 @@
struct ARegion;
struct bContext;
-struct IDProperty;
struct uiHandleButtonData;
struct wmEvent;
struct wmOperatorType;
-struct wmWindow;
struct wmTimer;
struct uiStyle;
struct uiWidgetColors;
@@ -123,6 +121,14 @@ enum {
/* warn: rest of uiBut->flag in UI_interface.h */
};
+/* some buttons display icons only under special conditions
+ * (e.g. 'x' icon in search menu) - used with ui_but_icon_extra_get */
+typedef enum uiButExtraIconType {
+ UI_BUT_ICONEXTRA_NONE = 1,
+ UI_BUT_ICONEXTRA_UNLINK,
+ UI_BUT_ICONEXTRA_EYEDROPPER,
+} uiButExtraIconType;
+
/* but->pie_dir */
typedef enum RadialDirection {
UI_RADIAL_NONE = -1,
@@ -445,8 +451,9 @@ extern void ui_but_hsv_set(uiBut *but);
extern void ui_but_v3_get(uiBut *but, float vec[3]);
extern void ui_but_v3_set(uiBut *but, const float vec[3]);
-extern void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rect,
- const float mx, const float my);
+extern void ui_hsvcircle_vals_from_pos(
+ float *val_rad, float *val_dist, const rcti *rect,
+ const float mx, const float my);
extern void ui_hsvcircle_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xpos, float *ypos);
extern void ui_hsvcube_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xp, float *yp);
bool ui_but_is_colorpicker_display_space(struct uiBut *but);
@@ -459,6 +466,9 @@ extern bool ui_but_string_set_eval_num(struct bContext *C, uiBut *but, const cha
extern int ui_but_string_get_max_length(uiBut *but);
extern uiBut *ui_but_drag_multi_edit_get(uiBut *but);
+void ui_def_but_icon(uiBut *but, const int icon, const int flag);
+extern uiButExtraIconType ui_but_icon_extra_get(uiBut *but);
+
extern void ui_but_default_set(struct bContext *C, const bool all, const bool use_afterfunc);
extern void ui_but_update(uiBut *but);
@@ -468,7 +478,6 @@ extern bool ui_but_is_unit(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
extern bool ui_but_is_compatible(const uiBut *but_a, const uiBut *but_b) ATTR_WARN_UNUSED_RESULT;
extern bool ui_but_is_rna_valid(uiBut *but) ATTR_WARN_UNUSED_RESULT;
extern bool ui_but_is_utf8(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
-extern bool ui_but_is_search_unlink_visible(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
extern int ui_but_is_pushed_ex(uiBut *but, double *value) ATTR_WARN_UNUSED_RESULT;
extern int ui_but_is_pushed(uiBut *but) ATTR_WARN_UNUSED_RESULT;
@@ -575,20 +584,22 @@ bool ui_searchbox_apply(uiBut *but, struct ARegion *ar);
void ui_searchbox_free(struct bContext *C, struct ARegion *ar);
void ui_but_search_refresh(uiBut *but);
-uiBlock *ui_popup_block_refresh(struct bContext *C, uiPopupBlockHandle *handle,
- ARegion *butregion, uiBut *but);
+uiBlock *ui_popup_block_refresh(
+ struct bContext *C, uiPopupBlockHandle *handle,
+ ARegion *butregion, uiBut *but);
-uiPopupBlockHandle *ui_popup_block_create(struct bContext *C, struct ARegion *butregion, uiBut *but,
- uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func,
- void *arg);
-uiPopupBlockHandle *ui_popup_menu_create(struct bContext *C, struct ARegion *butregion, uiBut *but,
- uiMenuCreateFunc create_func, void *arg);
+uiPopupBlockHandle *ui_popup_block_create(
+ struct bContext *C, struct ARegion *butregion, uiBut *but,
+ uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func,
+ void *arg);
+uiPopupBlockHandle *ui_popup_menu_create(
+ struct bContext *C, struct ARegion *butregion, uiBut *but,
+ uiMenuCreateFunc create_func, void *arg);
void ui_popup_block_free(struct bContext *C, uiPopupBlockHandle *handle);
int ui_but_menu_step(uiBut *but, int step);
-struct AutoComplete;
/* interface_panel.c */
extern int ui_handler_panel_region(struct bContext *C, const struct wmEvent *event, struct ARegion *ar);
@@ -635,7 +646,7 @@ uiBut *ui_but_find_new(uiBlock *block_old, const uiBut *but_new);
#ifdef WITH_INPUT_IME
void ui_but_ime_reposition(uiBut *but, int x, int y, bool complete);
-struct wmIMEData *ui_but_get_ime_data(uiBut *but);
+struct wmIMEData *ui_but_ime_data_get(uiBut *but);
#endif
/* interface_widgets.c */
@@ -664,6 +675,7 @@ void ui_draw_preview_item(struct uiFontStyle *fstyle, rcti *rect, const char *na
void uiStyleInit(void);
/* interface_icons.c */
+void ui_icon_ensure_deferred(const struct bContext *C, const int icon_id, const bool big);
int ui_id_icon_get(const struct bContext *C, struct ID *id, const bool big);
/* resources.c */
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 44c1ed474d5..a61b208278d 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -356,9 +356,10 @@ static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index)
}
/* create buttons for an item with an RNA array */
-static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, int icon,
- PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int UNUSED(h),
- bool expand, bool slider, bool toggle, bool icon_only)
+static void ui_item_array(
+ uiLayout *layout, uiBlock *block, const char *name, int icon,
+ PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int UNUSED(h),
+ bool expand, bool slider, bool toggle, bool icon_only)
{
uiStyle *style = layout->root->style;
uiBut *but;
@@ -545,8 +546,9 @@ static void ui_item_enum_expand_handle(bContext *C, void *arg1, void *arg2)
RNA_property_enum_set(&but->rnapoin, but->rnaprop, current_value);
}
}
-static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop,
- const char *uiname, int h, bool icon_only)
+static void ui_item_enum_expand(
+ uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop,
+ const char *uiname, int h, bool icon_only)
{
/* XXX The way this function currently handles uiname parameter is insane and inconsistent with general UI API:
* * uiname is the *enum property* label.
@@ -681,14 +683,17 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n
return but;
}
-void UI_context_active_but_prop_get_filebrowser(const bContext *C, PointerRNA *ptr, PropertyRNA **prop)
+void UI_context_active_but_prop_get_filebrowser(
+ const bContext *C,
+ PointerRNA *r_ptr, PropertyRNA **r_prop, bool *r_is_undo)
{
ARegion *ar = CTX_wm_region(C);
uiBlock *block;
uiBut *but, *prevbut;
- memset(ptr, 0, sizeof(*ptr));
- *prop = NULL;
+ memset(r_ptr, 0, sizeof(*r_ptr));
+ *r_prop = NULL;
+ *r_is_undo = false;
if (!ar)
return;
@@ -700,8 +705,9 @@ void UI_context_active_but_prop_get_filebrowser(const bContext *C, PointerRNA *p
/* find the button before the active one */
if ((but->flag & UI_BUT_LAST_ACTIVE) && prevbut && prevbut->rnapoin.data) {
if (RNA_property_type(prevbut->rnaprop) == PROP_STRING) {
- *ptr = prevbut->rnapoin;
- *prop = prevbut->rnaprop;
+ *r_ptr = prevbut->rnapoin;
+ *r_prop = prevbut->rnaprop;
+ *r_is_undo = (prevbut->flag & UI_BUT_UNDO) != 0;
return;
}
}
@@ -877,8 +883,9 @@ void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int ico
}
-void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname, IDProperty *properties,
- int context, int flag)
+void uiItemsFullEnumO(
+ uiLayout *layout, const char *opname, const char *propname, IDProperty *properties,
+ int context, int flag)
{
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
@@ -1129,8 +1136,9 @@ void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
/* RNA property items */
-static void ui_item_rna_size(uiLayout *layout, const char *name, int icon, PointerRNA *ptr, PropertyRNA *prop,
- int index, bool icon_only, int *r_w, int *r_h)
+static void ui_item_rna_size(
+ uiLayout *layout, const char *name, int icon, PointerRNA *ptr, PropertyRNA *prop,
+ int index, bool icon_only, int *r_w, int *r_h)
{
PropertyType type;
PropertySubType subtype;
@@ -1573,11 +1581,14 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
/* turn button into search button */
if (searchprop) {
- but->type = RNA_property_is_unlink(prop) ? UI_BTYPE_SEARCH_MENU_UNLINK : UI_BTYPE_SEARCH_MENU;
+ but->type = UI_BTYPE_SEARCH_MENU;
but->hardmax = MAX2(but->hardmax, 256.0f);
but->rnasearchpoin = *searchptr;
but->rnasearchprop = searchprop;
but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT;
+ if (RNA_property_is_unlink(prop)) {
+ but->flag |= UI_BUT_SEARCH_UNLINK;
+ }
if (RNA_property_type(prop) == PROP_ENUM) {
/* XXX, this will have a menu string,
@@ -1677,8 +1688,9 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
}
-static uiBut *ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN,
- const char *tip, bool force_menu)
+static uiBut *ui_item_menu(
+ uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN,
+ const char *tip, bool force_menu)
{
uiBlock *block = layout->root->block;
uiBut *but;
@@ -2139,7 +2151,11 @@ static void ui_litem_layout_column(uiLayout *litem)
static RadialDirection ui_get_radialbut_vec(float vec[2], short itemnum)
{
RadialDirection dir;
- BLI_assert(itemnum < 8);
+
+ if (itemnum >= 8) {
+ itemnum %= 8;
+ printf("Warning: Pie menus with more than 8 items are currently unsupported\n");
+ }
dir = ui_radial_dir_order[itemnum];
ui_but_pie_dir(dir, vec);
@@ -2717,7 +2733,8 @@ uiLayout *uiLayoutBox(uiLayout *layout)
return (uiLayout *)ui_layout_box(layout, UI_BTYPE_ROUNDBOX);
}
-/* Check all buttons defined in this layout, and set any button flagged as UI_BUT_LIST_ITEM as active/selected.
+/**
+ * Check all buttons defined in this layout, and set any button flagged as UI_BUT_LIST_ITEM as active/selected.
* Needed to handle correctly text colors of active (selected) list item.
*/
void ui_layout_list_set_labels_active(uiLayout *layout)
@@ -2733,8 +2750,9 @@ void ui_layout_list_set_labels_active(uiLayout *layout)
}
}
-uiLayout *uiLayoutListBox(uiLayout *layout, uiList *ui_list, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *actptr,
- PropertyRNA *actprop)
+uiLayout *uiLayoutListBox(
+ uiLayout *layout, uiList *ui_list, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *actptr,
+ PropertyRNA *actprop)
{
uiLayoutItemBx *box = ui_layout_box(layout, UI_BTYPE_LISTBOX);
uiBut *but = box->roundbox;
@@ -3333,9 +3351,10 @@ static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C), void *op_pt,
#endif
/* this function does not initialize the layout, functions can be called on the layout before and after */
-void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
- bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *),
- const char label_align, const short flag)
+void uiLayoutOperatorButs(
+ const bContext *C, uiLayout *layout, wmOperator *op,
+ bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *),
+ const char label_align, const short flag)
{
if (!op->properties) {
IDPropertyTemplate val = {0};
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 41d2a90e548..23b20591275 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -33,6 +33,7 @@
#include "DNA_screen_types.h"
#include "DNA_text_types.h" /* for UI_OT_reports_to_text */
+#include "DNA_object_types.h" /* for OB_DATA_SUPPORT_ID */
#include "BLI_blenlib.h"
#include "BLI_math_color.h"
@@ -43,6 +44,7 @@
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_global.h"
+#include "BKE_node.h"
#include "BKE_text.h" /* for UI_OT_reports_to_text */
#include "BKE_report.h"
@@ -261,7 +263,7 @@ static void UI_OT_unset_property_button(wmOperatorType *ot)
/* Copy To Selected Operator ------------------------ */
-static bool copy_to_selected_list(
+bool UI_context_copy_to_selected_list(
bContext *C, PointerRNA *ptr, PropertyRNA *prop,
ListBase *r_lb, bool *r_use_path_from_id, char **r_path)
{
@@ -277,6 +279,49 @@ static bool copy_to_selected_list(
else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
*r_lb = CTX_data_collection_get(C, "selected_editable_sequences");
}
+ else if (RNA_struct_is_a(ptr->type, &RNA_Node) ||
+ RNA_struct_is_a(ptr->type, &RNA_NodeSocket))
+ {
+ ListBase lb = {NULL, NULL};
+ char *path = NULL;
+ bNode *node = NULL;
+
+ /* Get the node we're editing */
+ if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
+ bNodeTree *ntree = ptr->id.data;
+ bNodeSocket *sock = ptr->data;
+ if (nodeFindNode(ntree, sock, &node, NULL)) {
+ if ((path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Node)) != NULL) {
+ /* we're good! */
+ }
+ else {
+ node = NULL;
+ }
+ }
+ }
+ else {
+ node = ptr->data;
+ }
+
+ /* Now filter by type */
+ if (node) {
+ CollectionPointerLink *link, *link_next;
+ lb = CTX_data_collection_get(C, "selected_nodes");
+
+ for (link = lb.first; link; link = link_next) {
+ bNode *node_data = link->ptr.data;
+ link_next = link->next;
+
+ if (node_data->type != node->type) {
+ BLI_remlink(&lb, link);
+ MEM_freeN(link);
+ }
+ }
+ }
+
+ *r_lb = lb;
+ *r_path = path;
+ }
else if (ptr->id.data) {
ID *id = ptr->id.data;
@@ -285,6 +330,51 @@ static bool copy_to_selected_list(
*r_use_path_from_id = true;
*r_path = RNA_path_from_ID_to_property(ptr, prop);
}
+ else if (OB_DATA_SUPPORT_ID(GS(id->name))) {
+ /* check we're using the active object */
+ const short id_code = GS(id->name);
+ ListBase lb = CTX_data_collection_get(C, "selected_editable_objects");
+ char *path = RNA_path_from_ID_to_property(ptr, prop);
+
+ /* de-duplicate obdata */
+ if (!BLI_listbase_is_empty(&lb)) {
+ CollectionPointerLink *link, *link_next;
+
+ for (link = lb.first; link; link = link->next) {
+ Object *ob = link->ptr.id.data;
+ if (ob->data) {
+ ID *id_data = ob->data;
+ id_data->flag |= LIB_DOIT;
+ }
+ }
+
+ for (link = lb.first; link; link = link_next) {
+ Object *ob = link->ptr.id.data;
+ ID *id_data = ob->data;
+ link_next = link->next;
+
+ if ((id_data == NULL) ||
+ (id_data->flag & LIB_DOIT) == 0 ||
+ (id_data->lib) ||
+ (GS(id_data->name) != id_code))
+ {
+ BLI_remlink(&lb, link);
+ MEM_freeN(link);
+ }
+ else {
+ /* avoid prepending 'data' to the path */
+ RNA_id_pointer_create(id_data, &link->ptr);
+ }
+
+ if (id_data) {
+ id_data->flag &= ~LIB_DOIT;
+ }
+ }
+ }
+
+ *r_lb = lb;
+ *r_path = path;
+ }
else if (GS(id->name) == ID_SCE) {
/* Sequencer's ID is scene :/ */
/* Try to recursively find an RNA_Sequence ancestor, to handle situations like T41062... */
@@ -325,7 +415,7 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll)
CollectionPointerLink *link;
ListBase lb;
- if (!copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path))
+ if (!UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path))
return success;
for (link = lb.first; link; link = link->next) {
@@ -553,8 +643,9 @@ void UI_editsource_active_but_test(uiBut *but)
BLI_ghash_insert(ui_editsource_info->hash, but, but_store);
}
-static int editsource_text_edit(bContext *C, wmOperator *op,
- char filepath[FILE_MAX], int line)
+static int editsource_text_edit(
+ bContext *C, wmOperator *op,
+ char filepath[FILE_MAX], int line)
{
struct Main *bmain = CTX_data_main(C);
Text *text;
@@ -613,6 +704,7 @@ static int editsource_exec(bContext *C, wmOperator *op)
/* redraw and get active button python info */
ED_region_do_draw(C, ar);
+ ar->do_draw = false;
for (BLI_ghashIterator_init(&ghi, ui_editsource_info->hash);
BLI_ghashIterator_done(&ghi) == false;
@@ -667,10 +759,12 @@ static void UI_OT_editsource(wmOperatorType *ot)
}
/* ------------------------------------------------------------------------- */
-/* EditTranslation utility funcs and operator,
- * Note: this includes utility functions and button matching checks.
- * this only works in conjunction with a py operator! */
+/**
+ * EditTranslation utility funcs and operator,
+ * \note: this includes utility functions and button matching checks.
+ * this only works in conjunction with a py operator!
+ */
static void edittranslation_find_po_file(const char *root, const char *uilng, char *path, const size_t maxlen)
{
char tstr[32]; /* Should be more than enough! */
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index d165e2719c5..665266edb9f 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -82,6 +82,14 @@
/* only show pin header button for pinned panels */
#define USE_PIN_HIDDEN
+/* the state of the mouse position relative to the panel */
+typedef enum uiPanelMouseState {
+ PANEL_MOUSE_OUTSIDE, /* mouse is not in the panel */
+ PANEL_MOUSE_INSIDE_CONTENT, /* mouse is in the actual panel content */
+ PANEL_MOUSE_INSIDE_HEADER, /* mouse is in the panel header */
+ PANEL_MOUSE_INSIDE_SCALE, /* mouse is inside panel scale widget */
+} uiPanelMouseState;
+
typedef enum uiHandlePanelState {
PANEL_STATE_DRAG,
PANEL_STATE_DRAG_SCALE,
@@ -202,8 +210,9 @@ static void ui_panel_copy_offset(Panel *pa, Panel *papar)
}
-/* XXX Disabled paneltab handling for now. Old 2.4x feature, *DO NOT* confuse it with new tool tabs in 2.70. ;)
- * See also T41704.
+/**
+ * XXX Disabled paneltab handling for now. Old 2.4x feature, *DO NOT* confuse it with new tool tabs in 2.70. ;)
+ * See also T41704.
*/
/* #define UI_USE_PANELTAB */
@@ -560,6 +569,8 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
rcti headrect;
rctf itemrect;
int ofsx;
+ const bool is_closed_x = (panel->flag & PNL_CLOSEDX) ? true : false;
+ const bool is_closed_y = (panel->flag & PNL_CLOSEDY) ? true : false;
if (panel->paneltab) return;
if (panel->type && (panel->type->flag & PNL_NO_HEADER)) return;
@@ -572,7 +583,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
{
float minx = rect->xmin;
- float maxx = rect->xmax;
+ float maxx = is_closed_x ? (minx + PNL_HEADER / block->aspect) : rect->xmax;
float y = headrect.ymax;
glEnable(GL_BLEND);
@@ -587,8 +598,11 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
}
else if (!(panel->runtime_flag & PNL_FIRST)) {
/* draw embossed separator */
- minx += 5.0f / block->aspect;
- maxx -= 5.0f / block->aspect;
+
+ if (is_closed_x == false) {
+ minx += 5.0f / block->aspect;
+ maxx -= 5.0f / block->aspect;
+ }
glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
fdrawline(minx, y, maxx, y);
@@ -615,7 +629,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
}
/* horizontal title */
- if (!(panel->flag & PNL_CLOSEDX)) {
+ if (is_closed_x == false) {
ui_draw_aligned_panel_header(style, block, &headrect, 'h');
/* itemrect smaller */
@@ -631,9 +645,10 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
/* if the panel is minimized vertically:
* (------)
*/
- if (panel->flag & PNL_CLOSEDY) {
+ if (is_closed_y) {
+ /* skip */
}
- else if (panel->flag & PNL_CLOSEDX) {
+ else if (is_closed_x) {
/* draw vertical title */
ui_draw_aligned_panel_header(style, block, &headrect, 'v');
}
@@ -680,9 +695,9 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
BLI_rctf_scale(&itemrect, 0.35f);
- if (panel->flag & PNL_CLOSEDY)
+ if (is_closed_y)
ui_draw_tria_rect(&itemrect, 'h');
- else if (panel->flag & PNL_CLOSEDX)
+ else if (is_closed_x)
ui_draw_tria_rect(&itemrect, 'h');
else
ui_draw_tria_rect(&itemrect, 'v');
@@ -729,11 +744,13 @@ typedef struct PanelSort {
Panel *pa, *orig;
} PanelSort;
-/* note about sorting;
+/**
+ * \note about sorting;
* the sortorder has a lower value for new panels being added.
* however, that only works to insert a single panel, when more new panels get
* added the coordinates of existing panels and the previously stored to-be-inserted
- * panels do not match for sorting */
+ * panels do not match for sorting
+ */
static int find_leftmost_panel(const void *a1, const void *a2)
{
@@ -1128,6 +1145,157 @@ static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel)
/******************* region level panel interaction *****************/
+static uiPanelMouseState ui_panel_mouse_state_get(const uiBlock *block, const Panel *pa, const int mx, const int my)
+{
+ /* open panel */
+ if (pa->flag & PNL_CLOSEDX) {
+ if ((block->rect.xmin <= mx) && (block->rect.xmin + PNL_HEADER >= mx)) {
+ return PANEL_MOUSE_INSIDE_HEADER;
+ }
+ }
+ /* outside left/right side */
+ else if ((block->rect.xmin > mx) || (block->rect.xmax < mx)) {
+ /* pass */
+ }
+ else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
+ return PANEL_MOUSE_INSIDE_HEADER;
+ }
+ /* open panel */
+ else if (!(pa->flag & PNL_CLOSEDY)) {
+ if (pa->control & UI_PNL_SCALE) {
+ if (block->rect.xmax - PNL_HEADER <= mx) {
+ if (block->rect.ymin + PNL_HEADER >= my) {
+ return PANEL_MOUSE_INSIDE_SCALE;
+ }
+ }
+ }
+ if ((block->rect.xmin <= mx) && (block->rect.xmax >= mx)) {
+ if ((block->rect.ymin <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
+ return PANEL_MOUSE_INSIDE_CONTENT;
+ }
+ }
+ }
+ return PANEL_MOUSE_OUTSIDE;
+}
+
+typedef struct uiPanelDragCollapseHandle {
+ bool was_first_open;
+ int xy_init[2];
+} uiPanelDragCollapseHandle;
+
+static void ui_panel_drag_collapse_handler_remove(bContext *UNUSED(C), void *userdata)
+{
+ uiPanelDragCollapseHandle *dragcol_data = userdata;
+ MEM_freeN(dragcol_data);
+}
+
+static void ui_panel_drag_collapse(bContext *C, uiPanelDragCollapseHandle *dragcol_data, const int xy_dst[2])
+{
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ uiBlock *block;
+ Panel *pa;
+
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ float xy_a_block[2] = {UNPACK2(dragcol_data->xy_init)};
+ float xy_b_block[2] = {UNPACK2(xy_dst)};
+ rctf rect = block->rect;
+ int oldflag;
+ const bool is_horizontal = (panel_aligned(sa, ar) == BUT_HORIZONTAL);
+
+ if ((pa = block->panel) == 0 || (pa->type && (pa->type->flag & PNL_NO_HEADER))) {
+ continue;
+ }
+ oldflag = pa->flag;
+
+ /* lock one axis */
+ if (is_horizontal) {
+ xy_b_block[1] = dragcol_data->xy_init[1];
+ }
+ else {
+ xy_b_block[0] = dragcol_data->xy_init[0];
+ }
+
+ /* use cursor coords in block space */
+ 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]);
+
+ /* set up rect to match header size */
+ rect.ymin = rect.ymax;
+ rect.ymax = rect.ymin + PNL_HEADER;
+ if (pa->flag & PNL_CLOSEDX) {
+ rect.xmax = rect.xmin + PNL_HEADER;
+ }
+
+ /* touch all panels between last mouse coord and the current one */
+ if (BLI_rctf_isect_segment(&rect, xy_a_block, xy_b_block)) {
+ /* force panel to close */
+ if (dragcol_data->was_first_open == true) {
+ pa->flag |= (is_horizontal ? PNL_CLOSEDX : PNL_CLOSEDY);
+ }
+ /* force panel to open */
+ else {
+ pa->flag &= ~PNL_CLOSED;
+ }
+
+ /* if pa->flag has changed this means a panel was opened/closed here */
+ if (pa->flag != oldflag) {
+ panel_activate_state(C, pa, PANEL_STATE_ANIMATION);
+ }
+ }
+ }
+}
+
+/**
+ * Panel drag-collapse (modal handler)
+ * Clicking and dragging over panels toggles their collapse state based on the panel that was first
+ * dragged over. If it was open all affected panels incl the initial one are closed and vise versa.
+ */
+static int ui_panel_drag_collapse_handler(bContext *C, const wmEvent *event, void *userdata)
+{
+ wmWindow *win = CTX_wm_window(C);
+ uiPanelDragCollapseHandle *dragcol_data = userdata;
+ short retval = WM_UI_HANDLER_CONTINUE;
+
+ switch (event->type) {
+ case MOUSEMOVE:
+ ui_panel_drag_collapse(C, dragcol_data, &event->x);
+
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ case LEFTMOUSE:
+ if (event->val == KM_RELEASE) {
+ /* done! */
+ WM_event_remove_ui_handler(
+ &win->modalhandlers,
+ ui_panel_drag_collapse_handler,
+ ui_panel_drag_collapse_handler_remove,
+ dragcol_data, true);
+ ui_panel_drag_collapse_handler_remove(C, dragcol_data);
+ }
+ /* don't let any left-mouse event fall through! */
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ }
+
+ return retval;
+}
+
+static void ui_panel_drag_collapse_handler_add(const bContext *C, const bool was_open)
+{
+ wmWindow *win = CTX_wm_window(C);
+ wmEvent *event = win->eventstate;
+ uiPanelDragCollapseHandle *dragcol_data = MEM_mallocN(sizeof(*dragcol_data), __func__);
+
+ dragcol_data->was_first_open = was_open;
+ copy_v2_v2_int(dragcol_data->xy_init, &event->x);
+
+ WM_event_add_ui_handler(
+ C, &win->modalhandlers,
+ ui_panel_drag_collapse_handler,
+ ui_panel_drag_collapse_handler_remove,
+ dragcol_data, 0);
+}
/* this function is supposed to call general window drawing too */
/* also it supposes a block has panel, and isn't a menu */
@@ -1187,23 +1355,39 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
ED_region_tag_redraw(ar);
}
else { /* collapse */
- if (ctrl)
+ if (ctrl) {
panels_collapse_all(sa, ar, block->panel);
+ /* reset the view - we don't want to display a view without content */
+ UI_view2d_offset(&ar->v2d, 0.0f, 1.0f);
+ }
+
if (block->panel->flag & PNL_CLOSED) {
block->panel->flag &= ~PNL_CLOSED;
/* snap back up so full panel aligns with screen edge */
if (block->panel->snap & PNL_SNAP_BOTTOM)
block->panel->ofsy = 0;
+
+ if (event == LEFTMOUSE) {
+ ui_panel_drag_collapse_handler_add(C, false);
+ }
}
else if (align == BUT_HORIZONTAL) {
block->panel->flag |= PNL_CLOSEDX;
+
+ if (event == LEFTMOUSE) {
+ ui_panel_drag_collapse_handler_add(C, true);
+ }
}
else {
- /* snap down to bottom screen edge*/
+ /* snap down to bottom screen edge */
block->panel->flag |= PNL_CLOSEDY;
if (block->panel->snap & PNL_SNAP_BOTTOM)
block->panel->ofsy = -block->panel->sizey;
+
+ if (event == LEFTMOUSE) {
+ ui_panel_drag_collapse_handler_add(C, true);
+ }
}
for (pa = ar->panels.first; pa; pa = pa->next) {
@@ -1332,10 +1516,11 @@ void UI_panel_category_clear_all(ARegion *ar)
}
/* based on UI_draw_roundbox_gl_mode, check on making a version which allows us to skip some sides */
-static void ui_panel_category_draw_tab(int mode, float minx, float miny, float maxx, float maxy, float rad,
- int roundboxtype,
- const bool use_highlight, const bool use_shadow,
- const unsigned char highlight_fade[3])
+static void ui_panel_category_draw_tab(
+ int mode, float minx, float miny, float maxx, float maxy, float rad,
+ int roundboxtype,
+ const bool use_highlight, const bool use_shadow,
+ const unsigned char highlight_fade[3])
{
float vec[4][2] = {
{0.195, 0.02},
@@ -1718,8 +1903,8 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar)
}
for (block = ar->uiblocks.last; block; block = block->prev) {
- bool inside = false, inside_header = false, inside_scale = false;
-
+ uiPanelMouseState mouse_state;
+
mx = event->x;
my = event->y;
ui_window_to_block(ar, block, &mx, &my);
@@ -1731,32 +1916,11 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar)
continue;
if (pa->type && pa->type->flag & PNL_NO_HEADER) /* XXX - accessed freed panels when scripts reload, need to fix. */
continue;
-
- /* clicked at panel header? */
- if (pa->flag & PNL_CLOSEDX) {
- if (block->rect.xmin <= mx && block->rect.xmin + PNL_HEADER >= mx)
- inside_header = true;
- }
- else if (block->rect.xmin > mx || block->rect.xmax < mx) {
- /* outside left/right side */
- }
- else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
- inside_header = true;
- }
- else if (!(pa->flag & PNL_CLOSEDY)) {
- /* open panel */
- if (pa->control & UI_PNL_SCALE) {
- if (block->rect.xmax - PNL_HEADER <= mx)
- if (block->rect.ymin + PNL_HEADER >= my)
- inside_scale = true;
- }
- if (block->rect.xmin <= mx && block->rect.xmax >= mx)
- if (block->rect.ymin <= my && block->rect.ymax + PNL_HEADER >= my)
- inside = true;
- }
-
+
+ mouse_state = ui_panel_mouse_state_get(block, pa, mx, my);
+
/* XXX hardcoded key warning */
- if ((inside || inside_header) && event->val == KM_PRESS) {
+ if (ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER) && event->val == KM_PRESS) {
if (event->type == AKEY && ((event->ctrl + event->oskey + event->shift + event->alt) == 0)) {
if (pa->flag & PNL_CLOSEDY) {
@@ -1775,13 +1939,13 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar)
if (ui_but_is_active(ar))
continue;
- if (inside || inside_header) {
+ if (ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER)) {
if (event->val == KM_PRESS) {
/* open close on header */
if (ELEM(event->type, RETKEY, PADENTER)) {
- if (inside_header) {
+ if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) {
ui_handle_panel_header(C, block, mx, my, RETKEY, event->ctrl, event->shift);
retval = WM_UI_HANDLER_BREAK;
break;
@@ -1791,12 +1955,12 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar)
/* all inside clicks should return in break - overlapping/float panels */
retval = WM_UI_HANDLER_BREAK;
- if (inside_header) {
- ui_handle_panel_header(C, block, mx, my, 0, event->ctrl, event->shift);
+ if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) {
+ ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl, event->shift);
retval = WM_UI_HANDLER_BREAK;
break;
}
- else if (inside_scale && !(pa->flag & PNL_CLOSED)) {
+ else if ((mouse_state == PANEL_MOUSE_INSIDE_SCALE) && !(pa->flag & PNL_CLOSED)) {
panel_activate_state(C, pa, PANEL_STATE_DRAG_SCALE);
retval = WM_UI_HANDLER_BREAK;
break;
@@ -1804,7 +1968,7 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar)
}
else if (event->type == RIGHTMOUSE) {
- if (inside_header) {
+ if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) {
ui_panel_menu(C, ar, block->panel);
retval = WM_UI_HANDLER_BREAK;
break;
@@ -1943,7 +2107,7 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
data = MEM_callocN(sizeof(uiHandlePanelData), "uiHandlePanelData");
pa->activedata = data;
- WM_event_add_ui_handler(C, &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa, false);
+ WM_event_add_ui_handler(C, &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa, 0);
}
if (ELEM(state, PANEL_STATE_ANIMATION, PANEL_STATE_DRAG))
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 6e5f6af3c5f..6aabbbe76b6 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -70,8 +70,9 @@
#include "interface_intern.h"
-#define MENU_TOP 8
+#define MENU_TOP (int)(8 * UI_DPI_FAC)
#define MENU_PADDING (int)(0.2f * UI_UNIT_Y)
+#define MENU_BORDER (int)(0.3f * U.widget_unit)
static int rna_property_enum_step(const bContext *C, PointerRNA *ptr, PropertyRNA *prop, int direction)
{
@@ -179,9 +180,10 @@ typedef struct uiTooltipData {
BLI_STATIC_ASSERT(UI_TIP_LC_MAX == UI_TIP_LC_ALERT + 1, "invalid lc-max");
BLI_STATIC_ASSERT(sizeof(((uiTooltipData *)NULL)->format[0]) <= sizeof(int), "oversize");
-static void rgb_tint(float col[3],
- float h, float h_strength,
- float v, float v_strength)
+static void rgb_tint(
+ float col[3],
+ float h, float h_strength,
+ float v, float v_strength)
{
float col_hsv_from[3];
float col_hsv_to[3];
@@ -241,10 +243,10 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
/* tone_fg = rgb_to_grayscale(main_color); */
/* mix the colors */
- rgb_tint(value_color, 0.0f, 0.0f, tone_bg, 0.2f); /* light grey */
+ rgb_tint(value_color, 0.0f, 0.0f, tone_bg, 0.2f); /* light gray */
rgb_tint(active_color, 0.6f, 0.2f, tone_bg, 0.2f); /* light blue */
- rgb_tint(normal_color, 0.0f, 0.0f, tone_bg, 0.4f); /* grey */
- rgb_tint(python_color, 0.0f, 0.0f, tone_bg, 0.5f); /* dark grey */
+ rgb_tint(normal_color, 0.0f, 0.0f, tone_bg, 0.4f); /* gray */
+ rgb_tint(python_color, 0.0f, 0.0f, tone_bg, 0.5f); /* dark gray */
rgb_tint(alert_color, 0.0f, 0.8f, tone_bg, 0.1f); /* red */
/* draw text */
@@ -261,7 +263,7 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
/* override text-style */
fstyle_header.shadow = 1;
- fstyle_header.shadowcolor = rgb_to_luma(tip_colors[UI_TIP_LC_MAIN]);
+ fstyle_header.shadowcolor = rgb_to_grayscale(tip_colors[UI_TIP_LC_MAIN]);
fstyle_header.shadx = fstyle_header.shady = 0;
fstyle_header.shadowalpha = 1.0f;
@@ -394,7 +396,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
data->totline++;
}
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
/* better not show the value of a password */
if ((but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PASSWORD)) == 0) {
/* full string */
@@ -815,7 +817,7 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step)
}
else {
/* only let users step into an 'unset' state for unlink buttons */
- data->active = (but->type == UI_BTYPE_SEARCH_MENU_UNLINK) ? -1 : 0;
+ data->active = (but->flag & UI_BUT_SEARCH_UNLINK) ? -1 : 0;
}
}
@@ -826,8 +828,8 @@ static void ui_searchbox_butrect(rcti *r_rect, uiSearchboxData *data, int itemnr
{
/* thumbnail preview */
if (data->preview) {
- int butw = BLI_rcti_size_x(&data->bbox) / data->prv_cols;
- int buth = (BLI_rcti_size_y(&data->bbox) - 2 * MENU_TOP) / data->prv_rows;
+ int butw = (BLI_rcti_size_x(&data->bbox) - 2 * MENU_BORDER) / data->prv_cols;
+ int buth = (BLI_rcti_size_y(&data->bbox) - 2 * MENU_BORDER) / data->prv_rows;
int row, col;
*r_rect = data->bbox;
@@ -835,10 +837,10 @@ static void ui_searchbox_butrect(rcti *r_rect, uiSearchboxData *data, int itemnr
col = itemnr % data->prv_cols;
row = itemnr / data->prv_cols;
- r_rect->xmin += col * butw;
+ r_rect->xmin += MENU_BORDER + (col * butw);
r_rect->xmax = r_rect->xmin + butw;
- r_rect->ymax = data->bbox.ymax - MENU_TOP - (row * buth);
+ r_rect->ymax -= MENU_BORDER + (row * buth);
r_rect->ymin = r_rect->ymax - buth;
}
/* list view */
@@ -886,7 +888,7 @@ bool ui_searchbox_apply(uiBut *but, ARegion *ar)
return true;
}
- else if (but->type == UI_BTYPE_SEARCH_MENU_UNLINK) {
+ else if (but->flag & UI_BUT_SEARCH_UNLINK) {
/* It is valid for _UNLINK flavor to have no active element (it's a valid way to unlink). */
but->editstr[0] = '\0';
@@ -1044,14 +1046,8 @@ static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
ui_searchbox_butrect(&rect, data, a);
/* widget itself */
- if (data->preview) {
- ui_draw_preview_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a],
- (a == data->active) ? UI_ACTIVE : 0);
- }
- else {
- ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a],
- (a == data->active) ? UI_ACTIVE : 0, data->use_sep);
- }
+ ui_draw_preview_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a],
+ (a == data->active) ? UI_ACTIVE : 0);
}
/* indicate more */
@@ -1164,25 +1160,27 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
/* compute position */
if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
- const int margin = UI_POPUP_MARGIN;
+ const int margin_x = UI_POPUP_MARGIN;
+ const int margin_y = MENU_TOP;
+ const int search_but_h = BLI_rctf_size_y(&but->rect) + 10;
/* this case is search menu inside other menu */
/* we copy region size */
ar->winrct = butregion->winrct;
/* widget rect, in region coords */
- data->bbox.xmin = margin;
- data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - margin;
+ data->bbox.xmin = margin_x;
+ data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - margin_x;
/* Do not use shadow width for height, gives insane margin with big shadows, and issue T41548 with small ones */
- data->bbox.ymin = 8 * UI_DPI_FAC;
- data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - 8 * UI_DPI_FAC;
+ data->bbox.ymin = margin_y;
+ data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - margin_y;
/* check if button is lower half */
if (but->rect.ymax < BLI_rctf_cent_y(&but->block->rect)) {
- data->bbox.ymin += BLI_rctf_size_y(&but->rect);
+ data->bbox.ymin += search_but_h;
}
else {
- data->bbox.ymax -= BLI_rctf_size_y(&but->rect);
+ data->bbox.ymax -= search_but_h;
}
}
else {
@@ -1426,7 +1424,8 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
if (down || top) {
if (dir1 == UI_DIR_UP && top == 0) dir1 = UI_DIR_DOWN;
if (dir1 == UI_DIR_DOWN && down == 0) dir1 = UI_DIR_UP;
- if (dir2 == UI_DIR_UP && top == 0) dir2 = UI_DIR_DOWN;
+ BLI_assert(dir2 != UI_DIR_UP);
+// if (dir2 == UI_DIR_UP && top == 0) dir2 = UI_DIR_DOWN;
if (dir2 == UI_DIR_DOWN && down == 0) dir2 = UI_DIR_UP;
}
@@ -1638,7 +1637,7 @@ static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle)
}
/**
- * Called for creatign new popups and refreshing existing ones.
+ * Called for creating new popups and refreshing existing ones.
*/
uiBlock *ui_popup_block_refresh(
bContext *C, uiPopupBlockHandle *handle,
@@ -1684,13 +1683,8 @@ uiBlock *ui_popup_block_refresh(
ar->regiondata = handle;
/* set UI_BLOCK_NUMSELECT before UI_block_end() so we get alphanumeric keys assigned */
- if (but) {
- if (but->type == UI_BTYPE_PULLDOWN) {
- block->flag |= UI_BLOCK_NUMSELECT;
- }
- }
- else {
- block->flag |= UI_BLOCK_POPUP | UI_BLOCK_NUMSELECT;
+ if (but == NULL) {
+ block->flag |= UI_BLOCK_POPUP;
}
block->flag |= UI_BLOCK_LOOP;
@@ -1808,9 +1802,10 @@ uiBlock *ui_popup_block_refresh(
return block;
}
-uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut *but,
- uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func,
- void *arg)
+uiPopupBlockHandle *ui_popup_block_create(
+ bContext *C, ARegion *butregion, uiBut *but,
+ uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func,
+ void *arg)
{
wmWindow *window = CTX_wm_window(C);
static ARegionType type;
@@ -2571,8 +2566,9 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
return pup->block;
}
-uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut *but,
- uiMenuCreateFunc menu_func, void *arg)
+uiPopupBlockHandle *ui_popup_menu_create(
+ bContext *C, ARegion *butregion, uiBut *but,
+ uiMenuCreateFunc menu_func, void *arg)
{
wmWindow *window = CTX_wm_window(C);
uiStyle *style = UI_style_get_dpi();
@@ -2619,7 +2615,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut
if (!but) {
handle->popup = true;
- UI_popup_handlers_add(C, &window->modalhandlers, handle, false);
+ UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
WM_event_add_mousemove(C);
}
@@ -2681,7 +2677,7 @@ void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
menu = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_POPUP, pup);
menu->popup = true;
- UI_popup_handlers_add(C, &window->modalhandlers, menu, false);
+ UI_popup_handlers_add(C, &window->modalhandlers, menu, 0);
WM_event_add_mousemove(C);
MEM_freeN(pup);
@@ -2807,7 +2803,9 @@ void UI_pie_menu_end(bContext *C, uiPieMenu *pie)
menu->popup = true;
menu->towardstime = PIL_check_seconds_timer();
- UI_popup_handlers_add(C, &window->modalhandlers, menu, true);
+ UI_popup_handlers_add(
+ C, &window->modalhandlers,
+ menu, WM_HANDLER_ACCEPT_DBL_CLICK);
WM_event_add_mousemove(C);
MEM_freeN(pie);
@@ -2850,8 +2848,9 @@ int UI_pie_menu_invoke(struct bContext *C, const char *idname, const wmEvent *ev
return OPERATOR_INTERFACE;
}
-int UI_pie_menu_invoke_from_operator_enum(struct bContext *C, const char *title, const char *opname,
- const char *propname, const wmEvent *event)
+int UI_pie_menu_invoke_from_operator_enum(
+ struct bContext *C, const char *title, const char *opname,
+ const char *propname, const wmEvent *event)
{
uiPieMenu *pie;
uiLayout *layout;
@@ -2867,8 +2866,9 @@ int UI_pie_menu_invoke_from_operator_enum(struct bContext *C, const char *title,
return OPERATOR_INTERFACE;
}
-int UI_pie_menu_invoke_from_rna_enum(struct bContext *C, const char *title, const char *path,
- const wmEvent *event)
+int UI_pie_menu_invoke_from_rna_enum(
+ struct bContext *C, const char *title, const char *path,
+ const wmEvent *event)
{
PointerRNA ctx_ptr;
PointerRNA r_ptr;
@@ -2997,7 +2997,7 @@ void UI_popup_block_invoke_ex(bContext *C, uiBlockCreateFunc func, void *arg, co
handle->optype = (opname) ? WM_operatortype_find(opname, 0) : NULL;
handle->opcontext = opcontext;
- UI_popup_handlers_add(C, &window->modalhandlers, handle, false);
+ UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
WM_event_add_mousemove(C);
}
@@ -3020,7 +3020,7 @@ void UI_popup_block_ex(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc po
handle->cancel_func = cancel_func;
// handle->opcontext = opcontext;
- UI_popup_handlers_add(C, &window->modalhandlers, handle, false);
+ UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
WM_event_add_mousemove(C);
}
@@ -3039,17 +3039,15 @@ void uiPupBlockOperator(bContext *C, uiBlockCreateFunc func, wmOperator *op, int
handle->cancel_func = confirm_cancel_operator;
handle->opcontext = opcontext;
- UI_popup_handlers_add(C, &window->modalhandlers, handle);
+ UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
WM_event_add_mousemove(C);
}
#endif
-void UI_popup_block_close(bContext *C, uiBlock *block)
+void UI_popup_block_close(bContext *C, wmWindow *win, uiBlock *block)
{
+ /* if loading new .blend while popup is open, window will be NULL */
if (block->handle) {
- wmWindow *win = CTX_wm_window(C);
-
- /* if loading new .blend while popup is open, window will be NULL */
if (win) {
UI_popup_handlers_remove(&win->modalhandlers, block->handle);
ui_popup_block_free(C, block->handle);
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index 2f46c0906ae..10575fcbc54 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -64,7 +64,7 @@
/* style + theme + layout-engine = UI */
-/*
+/**
* This is a complete set of layout rules, the 'state' of the Layout
* Engine. Multiple styles are possible, defined via C or Python. Styles
* get a name, and will typically get activated per region type, like
@@ -323,10 +323,14 @@ void UI_fontstyle_draw_simple_backdrop(
/* XXX: read a style configure */
uiStyle *UI_style_get(void)
{
+#if 0
uiStyle *style = NULL;
/* offset is two struct uiStyle pointers */
- /* style = BLI_findstring(&U.uistyles, "Unifont Style", sizeof(style) * 2) */;
+ style = BLI_findstring(&U.uistyles, "Unifont Style", sizeof(style) * 2);
return (style != NULL) ? style : U.uistyles.first;
+#else
+ return U.uistyles.first;
+#endif
}
/* for drawing, scaled with DPI setting */
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index b3c31a1a644..c3b58e2d1c1 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -187,10 +187,10 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
/* preview thumbnails */
if (template.prv_rows > 0 && template.prv_cols > 0) {
int w = 4 * U.widget_unit * template.prv_cols;
- int h = 4 * U.widget_unit * template.prv_rows + U.widget_unit;
+ int h = 5 * U.widget_unit * template.prv_rows;
/* fake button, it holds space for search items */
- uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL);
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y,
template.prv_rows, template.prv_cols, "");
@@ -273,8 +273,11 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
RNA_property_pointer_set(&template->ptr, template->prop, idptr);
RNA_property_update(C, &template->ptr, template->prop);
- if (id && CTX_wm_window(C)->eventstate->shift) /* useful hidden functionality, */
+ if (id && CTX_wm_window(C)->eventstate->shift) {
+ /* only way to force-remove data (on save) */
+ id->flag &= ~LIB_FAKEUSER;
id->us = 0;
+ }
break;
case UI_ID_FAKE_USER:
@@ -359,49 +362,23 @@ static const char *template_id_browse_tip(StructRNA *type)
return N_("Browse ID data to be linked");
}
-/* Return a type-based i18n context, needed e.g. by "New" button.
+/**
+ * \return a type-based i18n context, needed e.g. by "New" button.
* In most languages, this adjective takes different form based on gender of type name...
*/
#ifdef WITH_INTERNATIONAL
static const char *template_id_context(StructRNA *type)
{
if (type) {
- switch (RNA_type_to_ID_code(type)) {
- case ID_SCE: return BLF_I18NCONTEXT_ID_SCENE;
- case ID_OB: return BLF_I18NCONTEXT_ID_OBJECT;
- case ID_ME: return BLF_I18NCONTEXT_ID_MESH;
- case ID_CU: return BLF_I18NCONTEXT_ID_CURVE;
- case ID_MB: return BLF_I18NCONTEXT_ID_METABALL;
- case ID_MA: return BLF_I18NCONTEXT_ID_MATERIAL;
- case ID_TE: return BLF_I18NCONTEXT_ID_TEXTURE;
- case ID_IM: return BLF_I18NCONTEXT_ID_IMAGE;
- case ID_LS: return BLF_I18NCONTEXT_ID_FREESTYLELINESTYLE;
- case ID_LT: return BLF_I18NCONTEXT_ID_LATTICE;
- case ID_LA: return BLF_I18NCONTEXT_ID_LAMP;
- case ID_CA: return BLF_I18NCONTEXT_ID_CAMERA;
- case ID_WO: return BLF_I18NCONTEXT_ID_WORLD;
- case ID_SCR: return BLF_I18NCONTEXT_ID_SCREEN;
- case ID_TXT: return BLF_I18NCONTEXT_ID_TEXT;
- case ID_SPK: return BLF_I18NCONTEXT_ID_SPEAKER;
- case ID_SO: return BLF_I18NCONTEXT_ID_SOUND;
- case ID_AR: return BLF_I18NCONTEXT_ID_ARMATURE;
- case ID_AC: return BLF_I18NCONTEXT_ID_ACTION;
- case ID_NT: return BLF_I18NCONTEXT_ID_NODETREE;
- case ID_BR: return BLF_I18NCONTEXT_ID_BRUSH;
- case ID_PA: return BLF_I18NCONTEXT_ID_PARTICLESETTINGS;
- case ID_GD: return BLF_I18NCONTEXT_ID_GPENCIL;
- case ID_MC: return BLF_I18NCONTEXT_ID_MOVIECLIP;
- case ID_MSK: return BLF_I18NCONTEXT_ID_MASK;
- case ID_PAL: return BLF_I18NCONTEXT_ID_PALETTE;
- case ID_PC: return BLF_I18NCONTEXT_ID_PAINTCURVE;
- }
+ return BKE_idcode_to_translation_context(RNA_type_to_ID_code(type));
}
return BLF_I18NCONTEXT_DEFAULT;
}
#endif
-static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, short idcode, int flag,
- const char *newop, const char *openop, const char *unlinkop)
+static void template_ID(
+ bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, short idcode, int flag,
+ const char *newop, const char *openop, const char *unlinkop)
{
uiBut *but;
uiBlock *block;
@@ -426,8 +403,8 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6,
TIP_(template_id_browse_tip(type)));
- but->icon = id ? ui_id_icon_get(C, id, true) : RNA_struct_ui_icon(type);
- UI_but_flag_enable(but, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+ ui_def_but_icon(but, id ? ui_id_icon_get(C, id, true) : RNA_struct_ui_icon(type),
+ UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
if ((idfrom && idfrom->lib) || !editable)
UI_but_flag_enable(but, UI_BUT_DISABLED);
@@ -437,10 +414,9 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
else if (flag & UI_ID_BROWSE) {
but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y,
TIP_(template_id_browse_tip(type)));
- but->icon = RNA_struct_ui_icon(type);
+ ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
/* default dragging of icon for id browse buttons */
UI_but_drag_set_id(but, id);
- UI_but_flag_enable(but, UI_HAS_ICON);
UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
if ((idfrom && idfrom->lib) || !editable)
@@ -617,8 +593,9 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
UI_block_align_end(block);
}
-static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
- const char *openop, const char *unlinkop, int flag, int prv_rows, int prv_cols)
+static void ui_template_id(
+ uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
+ const char *openop, const char *unlinkop, int flag, int prv_rows, int prv_cols)
{
TemplateID *template;
PropertyRNA *prop;
@@ -658,21 +635,24 @@ static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const
MEM_freeN(template);
}
-void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
- const char *openop, const char *unlinkop)
+void uiTemplateID(
+ uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
+ const char *openop, const char *unlinkop)
{
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop,
UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE, 0, 0);
}
-void uiTemplateIDBrowse(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
- const char *openop, const char *unlinkop)
+void uiTemplateIDBrowse(
+ uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
+ const char *openop, const char *unlinkop)
{
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE | UI_ID_RENAME, 0, 0);
}
-void uiTemplateIDPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
- const char *openop, const char *unlinkop, int rows, int cols)
+void uiTemplateIDPreview(
+ uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
+ const char *openop, const char *unlinkop, int rows, int cols)
{
ui_template_id(layout, C, ptr, propname, newop, openop, unlinkop,
UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE | UI_ID_PREVIEWS, rows, cols);
@@ -680,13 +660,15 @@ void uiTemplateIDPreview(uiLayout *layout, bContext *C, PointerRNA *ptr, const c
/************************ ID Chooser Template ***************************/
-/* This is for selecting the type of ID-block to use, and then from the relevant type choosing the block to use
+/**
+ * This is for selecting the type of ID-block to use, and then from the relevant type choosing the block to use
*
* - propname: property identifier for property that ID-pointer gets stored to
* - proptypename: property identifier for property used to determine the type of ID-pointer that can be used
*/
-void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *proptypename,
- const char *text)
+void uiTemplateAnyID(
+ uiLayout *layout, PointerRNA *ptr, const char *propname, const char *proptypename,
+ const char *text)
{
PropertyRNA *propID, *propType;
uiLayout *split, *row, *sub;
@@ -739,7 +721,8 @@ void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, co
/* ---------- */
-/* This is creating/editing RNA-Paths
+/**
+ * This is creating/editing RNA-Paths
*
* - ptr: struct which holds the path property
* - propname: property identifier for property that path gets stored to
@@ -820,10 +803,11 @@ static int modifier_is_simulation(ModifierData *md)
}
}
-static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
- ModifierData *md, int index, int cageIndex, int lastCageIndex)
+static uiLayout *draw_modifier(
+ uiLayout *layout, Scene *scene, Object *ob,
+ ModifierData *md, int index, int cageIndex, int lastCageIndex)
{
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
PointerRNA ptr;
uiBut *but;
uiBlock *block;
@@ -1065,7 +1049,8 @@ static void do_constraint_panels(bContext *C, void *ob_pt, int event)
case B_CONSTRAINT_CHANGETARGET:
{
Main *bmain = CTX_data_main(C);
- if (ob->pose) ob->pose->flag |= POSE_RECALC; /* checks & sorts pose channels */
+ if (ob->pose)
+ BKE_pose_tag_recalc(bmain, ob->pose); /* checks & sorts pose channels */
DAG_relations_tag_update(bmain);
break;
}
@@ -1095,7 +1080,7 @@ static void constraint_active_func(bContext *UNUSED(C), void *ob_v, void *con_v)
static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
{
bPoseChannel *pchan = BKE_pose_channel_active(ob);
- bConstraintTypeInfo *cti;
+ const bConstraintTypeInfo *cti;
uiBlock *block;
uiLayout *result = NULL, *col, *box, *row;
PointerRNA ptr;
@@ -1283,8 +1268,9 @@ static void do_preview_buttons(bContext *C, void *arg, int event)
}
}
-void uiTemplatePreview(uiLayout *layout, bContext *C, ID *id, int show_buttons, ID *parent, MTex *slot,
- const char *preview_id)
+void uiTemplatePreview(
+ uiLayout *layout, bContext *C, ID *id, int show_buttons, ID *parent, MTex *slot,
+ const char *preview_id)
{
uiLayout *row, *col;
uiBlock *block;
@@ -1492,8 +1478,9 @@ static void colorband_update_cb(bContext *UNUSED(C), void *bt_v, void *coba_v)
bt->rnapoin.data = coba->data + coba->cur;
}
-static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand *coba, const rctf *butr,
- RNAUpdateCb *cb, int expand)
+static void colorband_buttons_layout(
+ uiLayout *layout, uiBlock *block, ColorBand *coba, const rctf *butr,
+ RNAUpdateCb *cb, int expand)
{
uiLayout *row, *split, *subsplit;
uiBut *bt;
@@ -1558,6 +1545,7 @@ static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand
row = uiLayoutRow(split, false);
uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE);
bt = block->buttons.last;
+ bt->a1 = 1.0f; /* gives a bit more precision for modifying position */
UI_but_func_set(bt, colorband_update_cb, bt, coba);
row = uiLayoutRow(layout, false);
@@ -1575,6 +1563,7 @@ static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand
row = uiLayoutRow(subsplit, false);
uiItemR(row, &ptr, "position", UI_ITEM_R_SLIDER, IFACE_("Pos"), ICON_NONE);
bt = block->buttons.last;
+ bt->a1 = 1.0f; /* gives a bit more precision for modifying position */
UI_but_func_set(bt, colorband_update_cb, bt, coba);
row = uiLayoutRow(split, false);
@@ -1622,44 +1611,57 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname
/********************* Icon viewer Template ************************/
+typedef struct IconViewMenuArgs {
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int show_labels;
+} IconViewMenuArgs;
/* ID Search browse menu, open */
static uiBlock *ui_icon_view_menu_cb(bContext *C, ARegion *ar, void *arg_litem)
{
- static RNAUpdateCb cb;
+ static IconViewMenuArgs args;
uiBlock *block;
uiBut *but;
- int icon;
+ int icon, value;
EnumPropertyItem *item;
int a;
bool free;
/* arg_litem is malloced, can be freed by parent button */
- cb = *((RNAUpdateCb *)arg_litem);
-
- /* unused */
- // icon = RNA_property_enum_get(&cb.ptr, cb.prop);
-
- block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+ args = *((IconViewMenuArgs *) arg_litem);
+
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS_PULLDOWN);
UI_block_flag_enable(block, UI_BLOCK_LOOP);
-
-
- RNA_property_enum_items(C, &cb.ptr, cb.prop, &item, NULL, &free);
-
+
+ RNA_property_enum_items(C, &args.ptr, args.prop, &item, NULL, &free);
+
for (a = 0; item[a].identifier; a++) {
int x, y;
-
- /* XXX hardcoded size to 5 x unit */
- x = (a % 8) * UI_UNIT_X * 5;
- y = (a / 8) * UI_UNIT_X * 5;
-
+ /* XXX hardcoded size to 5 units */
+ const int w = UI_UNIT_X * 5;
+ const int h = args.show_labels ? 6 * UI_UNIT_Y : UI_UNIT_Y * 5;
+
+ x = (a % 8) * w;
+ y = (a / 8) * h;
+
icon = item[a].icon;
- but = uiDefIconButR_prop(block, UI_BTYPE_ROW, 0, icon, x, y, UI_UNIT_X * 5, UI_UNIT_Y * 5, &cb.ptr, cb.prop, -1, 0, icon, -1, -1, NULL);
- UI_but_flag_enable(but, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+ value = item[a].value;
+ if (args.show_labels) {
+ but = uiDefIconTextButR_prop(
+ block, UI_BTYPE_ROW, 0, icon, item[a].name, x, y, w, h,
+ &args.ptr, args.prop, -1, 0, value, -1, -1, NULL);
+ }
+ else {
+ but = uiDefIconButR_prop(
+ block, UI_BTYPE_ROW, 0, icon, x, y, w, h,
+ &args.ptr, args.prop, -1, 0, value, -1, -1, NULL);
+ }
+ ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
}
UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
- UI_block_direction_set(block, UI_DIR_UP);
+ UI_block_direction_set(block, UI_DIR_DOWN);
if (free) {
MEM_freeN(item);
@@ -1668,40 +1670,39 @@ static uiBlock *ui_icon_view_menu_cb(bContext *C, ARegion *ar, void *arg_litem)
return block;
}
-void uiTemplateIconView(uiLayout *layout, PointerRNA *ptr, const char *propname)
+void uiTemplateIconView(uiLayout *layout, PointerRNA *ptr, const char *propname, int show_labels)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- RNAUpdateCb *cb;
+ IconViewMenuArgs *cb_args;
+ EnumPropertyItem *items;
uiBlock *block;
uiBut *but;
-// rctf rect; /* UNUSED */
- int icon;
-
- if (!prop || RNA_property_type(prop) != PROP_ENUM)
+ int value, icon = ICON_NONE, tot_items;
+ bool free_items;
+
+ if (!prop || RNA_property_type(prop) != PROP_ENUM) {
+ RNA_warning("property of type Enum not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
return;
-
- icon = RNA_property_enum_get(ptr, prop);
-
- cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
- cb->ptr = *ptr;
- cb->prop = prop;
-
-// rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
-// rect.ymin = 0; rect.ymax = 10.0f * UI_UNIT_X;
-
+ }
+
block = uiLayoutAbsoluteBlock(layout);
- but = uiDefBlockButN(block, ui_icon_view_menu_cb, MEM_dupallocN(cb), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, "");
+ RNA_property_enum_items(block->evil_C, ptr, prop, &items, &tot_items, &free_items);
+ value = RNA_property_enum_get(ptr, prop);
+ RNA_enum_icon_from_value(items, value, &icon);
-
-// but = uiDefIconButR_prop(block, UI_BTYPE_ROW, 0, icon, 0, 0, BLI_rctf_size_x(&rect), BLI_rctf_size_y(&rect), ptr, prop, -1, 0, icon, -1, -1, NULL);
-
- but->icon = icon;
- UI_but_flag_enable(but, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
-
- UI_but_funcN_set(but, rna_update_cb, MEM_dupallocN(cb), NULL);
-
- MEM_freeN(cb);
+ cb_args = MEM_callocN(sizeof(IconViewMenuArgs), __func__);
+ cb_args->ptr = *ptr;
+ cb_args->prop = prop;
+ cb_args->show_labels = show_labels;
+
+ but = uiDefBlockButN(block, ui_icon_view_menu_cb, cb_args, "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, "");
+
+ ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+
+ if (free_items) {
+ MEM_freeN(items);
+ }
}
/********************* Histogram Template ************************/
@@ -2071,8 +2072,9 @@ static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v)
}
/* still unsure how this call evolves... we use labeltype for defining what curve-channels to show */
-static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labeltype, int levels,
- int brush, int neg_slope, RNAUpdateCb *cb)
+static void curvemap_buttons_layout(
+ uiLayout *layout, PointerRNA *ptr, char labeltype, int levels,
+ int brush, int neg_slope, RNAUpdateCb *cb)
{
CurveMapping *cumap = ptr->data;
CurveMap *cm = &cumap->cm[cumap->cur];
@@ -2233,8 +2235,9 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
UI_block_funcN_set(block, NULL, NULL, NULL);
}
-void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propname, int type,
- int levels, int brush, int neg_slope)
+void uiTemplateCurveMapping(
+ uiLayout *layout, PointerRNA *ptr, const char *propname, int type,
+ int levels, int brush, int neg_slope)
{
RNAUpdateCb *cb;
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
@@ -2277,8 +2280,9 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propn
#define WHEEL_SIZE (5 * U.widget_unit)
/* This template now follows User Preference for type - name is not correct anymore... */
-void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propname, int value_slider,
- int lock, int lock_luminosity, int cubic)
+void uiTemplateColorPicker(
+ uiLayout *layout, PointerRNA *ptr, const char *propname, int value_slider,
+ int lock, int lock_luminosity, int cubic)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
uiBlock *block = uiLayoutGetBlock(layout);
@@ -2398,9 +2402,6 @@ void uiTemplatePalette(uiLayout *layout, PointerRNA *ptr, const char *propname,
palette = cptr.data;
- /* first delete any pending colors */
- BKE_palette_cleanup(palette);
-
color = palette->colors.first;
col = uiLayoutColumn(layout, true);
@@ -2452,12 +2453,13 @@ static void handle_layer_buttons(bContext *C, void *arg1, void *arg2)
/* see view3d_header.c */
}
-/* TODO:
- * - for now, grouping of layers is determined by dividing up the length of
- * the array of layer bitflags */
-
-void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, const char *propname,
- PointerRNA *used_ptr, const char *used_propname, int active_layer)
+/**
+ * \todo for now, grouping of layers is determined by dividing up the length of
+ * the array of layer bitflags
+ */
+void uiTemplateLayers(
+ uiLayout *layout, PointerRNA *ptr, const char *propname,
+ PointerRNA *used_ptr, const char *used_propname, int active_layer)
{
uiLayout *uRow, *uCol;
PropertyRNA *prop, *used_prop = NULL;
@@ -2523,8 +2525,9 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, const char *propname,
}
}
-void uiTemplateGameStates(uiLayout *layout, PointerRNA *ptr, const char *propname,
- PointerRNA *used_ptr, const char *used_propname, int active_state)
+void uiTemplateGameStates(
+ uiLayout *layout, PointerRNA *ptr, const char *propname,
+ PointerRNA *used_ptr, const char *used_propname, int active_state)
{
uiLayout *uRow, *uCol;
PropertyRNA *prop, *used_prop = NULL;
@@ -2594,10 +2597,11 @@ void uiTemplateGameStates(uiLayout *layout, PointerRNA *ptr, const char *propnam
/************************* List Template **************************/
-static void uilist_draw_item_default(struct uiList *ui_list, struct bContext *UNUSED(C), struct uiLayout *layout,
- struct PointerRNA *UNUSED(dataptr), struct PointerRNA *itemptr, int icon,
- struct PointerRNA *UNUSED(active_dataptr), const char *UNUSED(active_propname),
- int UNUSED(index), int UNUSED(flt_flag))
+static void uilist_draw_item_default(
+ struct uiList *ui_list, struct bContext *UNUSED(C), struct uiLayout *layout,
+ struct PointerRNA *UNUSED(dataptr), struct PointerRNA *itemptr, int icon,
+ struct PointerRNA *UNUSED(active_dataptr), const char *UNUSED(active_propname),
+ int UNUSED(index), int UNUSED(flt_flag))
{
PropertyRNA *nameprop = RNA_struct_name_property(itemptr->type);
@@ -2764,8 +2768,9 @@ typedef struct {
int end_idx; /* Index of last item to display + 1. */
} uiListLayoutdata;
-static void uilist_prepare(uiList *ui_list, int len, int activei, int rows, int maxrows, int columns,
- uiListLayoutdata *layoutdata)
+static void uilist_prepare(
+ uiList *ui_list, int len, int activei, int rows, int maxrows, int columns,
+ uiListLayoutdata *layoutdata)
{
uiListDyn *dyn_data = ui_list->dyn_data;
int activei_row, max_scroll;
@@ -2851,9 +2856,10 @@ static char *uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const cha
return BLI_sprintfN("%s - %s", tip, dyn_tooltip);
}
-void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, const char *list_id,
- PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname,
- const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns)
+void uiTemplateList(
+ uiLayout *layout, bContext *C, const char *listtype_name, const char *list_id,
+ PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname,
+ const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns)
{
uiListType *ui_list_type;
uiList *ui_list = NULL;
@@ -3199,7 +3205,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
/* add scrollbar */
if (len > layoutdata.visual_items) {
- col = uiLayoutColumn(row, false);
+ /* col = */ uiLayoutColumn(row, false);
uiDefButI(block, UI_BTYPE_SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * dyn_data->visual_height,
&ui_list->list_scroll, 0, dyn_data->height - dyn_data->visual_height,
dyn_data->visual_height, 0, "");
@@ -3277,17 +3283,18 @@ static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char
for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
+ const char *ot_ui_name = CTX_IFACE_(ot->translation_context, ot->name);
if ((ot->flag & OPTYPE_INTERNAL) && (G.debug & G_DEBUG_WM) == 0)
continue;
- if (BLI_strcasestr(ot->name, str)) {
+ if (BLI_strcasestr(ot_ui_name, str)) {
if (WM_operator_poll((bContext *)C, ot)) {
char name[256];
- int len = strlen(ot->name);
+ int len = strlen(ot_ui_name);
/* display name for menu, can hold hotkey */
- BLI_strncpy(name, ot->name, sizeof(name));
+ BLI_strncpy(name, ot_ui_name, sizeof(name));
/* check for hotkey */
if (len < sizeof(name) - 6) {
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 28bd637ae59..0823238fcb1 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -52,6 +52,9 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
#include "interface_intern.h"
@@ -154,9 +157,10 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
* \a check_prop callback filters functions to avoid drawing certain properties,
* in cases where PROP_HIDDEN flag can't be used for a property.
*/
-int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr,
- bool (*check_prop)(PointerRNA *, PropertyRNA *),
- const char label_align)
+int uiDefAutoButsRNA(
+ uiLayout *layout, PointerRNA *ptr,
+ bool (*check_prop)(PointerRNA *, PropertyRNA *),
+ const char label_align)
{
uiLayout *split, *col;
int flag;
@@ -309,6 +313,34 @@ int UI_calc_float_precision(int prec, double value)
return prec;
}
+bool UI_but_online_manual_id(const uiBut *but, char *r_str, size_t maxlength)
+{
+ if (but->rnapoin.id.data && but->rnapoin.data && but->rnaprop) {
+ BLI_snprintf(r_str, maxlength, "%s.%s", RNA_struct_identifier(but->rnapoin.type),
+ RNA_property_identifier(but->rnaprop));
+ return true;
+ }
+ else if (but->optype) {
+ WM_operator_py_idname(r_str, but->optype->idname);
+ return true;
+ }
+
+ *r_str = '\0';
+ return false;
+}
+
+bool UI_but_online_manual_id_from_active(const struct bContext *C, char *r_str, size_t maxlength)
+{
+ uiBut *but = UI_context_active_but_get(C);
+
+ if (but) {
+ return UI_but_online_manual_id(but, r_str, maxlength);
+ }
+
+ *r_str = '\0';
+ return false;
+}
+
/* -------------------------------------------------------------------- */
/* Modal Button Store API */
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 91186a14b49..253f4616843 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -27,7 +27,6 @@
* \ingroup edinterface
*/
-
#include <limits.h>
#include <stdlib.h>
#include <string.h>
@@ -56,7 +55,6 @@
#include "UI_interface.h"
#include "UI_interface_icons.h"
-
#include "interface_intern.h"
#ifdef WITH_INPUT_IME
@@ -67,12 +65,12 @@
#define ICON_SIZE_FROM_BUTRECT(rect) (0.8f * BLI_rcti_size_y(rect))
/* ************** widget base functions ************** */
-/*
+/**
* - in: roundbox codes for corner types and radius
- * - return: array of [size][2][x,y] points, the edges of the roundbox, + UV coords
+ * - return: array of `[size][2][x, y]` points, the edges of the roundbox, + UV coords
*
* - draw black box with alpha 0 on exact button boundbox
- * - for ever AA step:
+ * - for every AA step:
* - draw the inner part for a round filled box, with color blend codes or texture coords
* - draw outline in outline color
* - draw outer part, bottom half, extruded 1 pixel to bottom, for emboss shadow
@@ -102,14 +100,14 @@ typedef struct uiWidgetBase {
float inner_v[WIDGET_SIZE_MAX][2];
float inner_uv[WIDGET_SIZE_MAX][2];
- bool inner, outline, emboss, shadedir;
+ bool draw_inner, draw_outline, draw_emboss, draw_shadedir;
uiWidgetTrias tria1;
uiWidgetTrias tria2;
} uiWidgetBase;
-/* uiWidgetType: for time being only for visual appearance,
+/** uiWidgetType: for time being only for visual appearance,
* later, a handling callback can be added too
*/
typedef struct uiWidgetType {
@@ -239,10 +237,10 @@ static void widget_init(uiWidgetBase *wtb)
wtb->tria1.tot = 0;
wtb->tria2.tot = 0;
- wtb->inner = 1;
- wtb->outline = 1;
- wtb->emboss = 1;
- wtb->shadedir = 1;
+ wtb->draw_inner = true;
+ wtb->draw_outline = true;
+ wtb->draw_emboss = true;
+ wtb->draw_shadedir = true;
}
/* helper call, makes shadow rect, with 'sun' above menu, so only shadow to left/right/bottom */
@@ -549,12 +547,12 @@ static void widget_menu_trias(uiWidgetTrias *tria, const rcti *rect)
{
float centx, centy, size;
int a;
-
+
/* center position and size */
centx = rect->xmax - 0.32f * BLI_rcti_size_y(rect);
centy = rect->ymin + 0.50f * BLI_rcti_size_y(rect);
- size = 0.4f * (float)BLI_rcti_size_y(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;
@@ -587,7 +585,6 @@ static void widget_check_trias(uiWidgetTrias *tria, const rcti *rect)
/* prepares shade colors */
static void shadecolors4(char coltop[4], char coldown[4], const char *color, short shadetop, short shadedown)
{
-
coltop[0] = CLAMPIS(color[0] + shadetop, 0, 255);
coltop[1] = CLAMPIS(color[1] + shadetop, 0, 255);
coltop[2] = CLAMPIS(color[2] + shadetop, 0, 255);
@@ -604,10 +601,10 @@ static void round_box_shade_col4_r(unsigned char r_col[4], const char col1[4], c
const int faci = FTOCHAR(fac);
const int facm = 255 - faci;
- r_col[0] = (faci * col1[0] + facm * col2[0]) >> 8;
- r_col[1] = (faci * col1[1] + facm * col2[1]) >> 8;
- r_col[2] = (faci * col1[2] + facm * col2[2]) >> 8;
- r_col[3] = (faci * col1[3] + facm * col2[3]) >> 8;
+ r_col[0] = (faci * col1[0] + facm * col2[0]) / 256;
+ r_col[1] = (faci * col1[1] + facm * col2[1]) / 256;
+ r_col[2] = (faci * col1[2] + facm * col2[2]) / 256;
+ r_col[3] = (faci * col1[3] + facm * col2[3]) / 256;
}
static void widget_verts_to_triangle_strip(uiWidgetBase *wtb, const int totvert, float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2])
@@ -650,7 +647,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
glEnable(GL_BLEND);
/* backdrop non AA */
- if (wtb->inner) {
+ if (wtb->draw_inner) {
if (wcol->shaded == 0) {
if (wcol->alpha_check) {
float inner_v_half[WIDGET_SIZE_MAX][2];
@@ -716,7 +713,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
glShadeModel(GL_SMOOTH);
for (a = 0; a < wtb->totvert; a++, col_pt += 4) {
- round_box_shade_col4_r(col_pt, col1, col2, wtb->inner_uv[a][wtb->shadedir]);
+ round_box_shade_col4_r(col_pt, col1, col2, wtb->inner_uv[a][wtb->draw_shadedir ? 1 : 0]);
}
glEnableClientState(GL_VERTEX_ARRAY);
@@ -732,7 +729,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
}
/* for each AA step */
- if (wtb->outline) {
+ if (wtb->draw_outline) {
float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2]; /* + 2 because the last pair is wrapped */
float triangle_strip_emboss[WIDGET_SIZE_MAX * 2][2]; /* only for emboss */
@@ -743,7 +740,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
widget_verts_to_triangle_strip(wtb, wtb->totvert, triangle_strip);
- if (wtb->emboss) {
+ if (wtb->draw_emboss) {
widget_verts_to_triangle_strip_open(wtb, wtb->halfwayvert, triangle_strip_emboss);
}
@@ -761,7 +758,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
glDrawArrays(GL_TRIANGLE_STRIP, 0, wtb->totvert * 2 + 2);
/* emboss bottom shadow */
- if (wtb->emboss) {
+ if (wtb->draw_emboss) {
UI_GetThemeColor4ubv(TH_WIDGET_EMBOSS, emboss);
if (emboss[3]) {
@@ -783,6 +780,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
wcol->item[1],
wcol->item[2],
(unsigned char)((float)wcol->item[3] / WIDGET_AA_JITTER)};
+
/* for each AA step */
for (j = 0; j < WIDGET_AA_JITTER; j++) {
glTranslatef(jit[j][0], jit[j][1], 0.0f);
@@ -801,7 +799,6 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
}
glDisable(GL_BLEND);
-
}
/* *********************** text/icon ************************************** */
@@ -810,7 +807,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
#define PREVIEW_PAD 4
-static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), const rcti *rect)
+static void widget_draw_preview(BIFIconID icon, float alpha, const rcti *rect)
{
int w, h, size;
@@ -826,7 +823,7 @@ static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), const rcti
int x = rect->xmin + w / 2 - size / 2;
int y = rect->ymin + h / 2 - size / 2;
- UI_icon_draw_preview_aspect_size(x, y, icon, 1.0f, size);
+ UI_icon_draw_preview_aspect_size(x, y, icon, 1.0f, alpha, size);
}
}
@@ -838,8 +835,9 @@ static int ui_but_draw_menu_icon(const uiBut *but)
/* icons have been standardized... and this call draws in untransformed coordinates */
-static void widget_draw_icon(const uiBut *but, BIFIconID icon, float alpha, const rcti *rect,
- const bool show_menu_icon)
+static void widget_draw_icon(
+ const uiBut *but, BIFIconID icon, float alpha, const rcti *rect,
+ const bool show_menu_icon)
{
float xs = 0.0f, ys = 0.0f;
float aspect, height;
@@ -875,7 +873,7 @@ static void widget_draw_icon(const uiBut *but, BIFIconID icon, float alpha, cons
if (but->drawflag & UI_BUT_ICON_LEFT) {
if (but->block->flag & UI_BLOCK_LOOP) {
- if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK))
+ if (but->type == UI_BTYPE_SEARCH_MENU)
xs = rect->xmin + 4.0f * ofs;
else
xs = rect->xmin + ofs;
@@ -931,12 +929,14 @@ static void ui_text_clip_give_next_off(uiBut *but, const char *str)
but->ofs += bytes;
}
-/* Helper.
+/**
+ * Helper.
* This func assumes things like kerning handling have already been handled!
* Return the length of modified (right-clipped + ellipsis) string.
*/
-static void ui_text_clip_right_ex(uiFontStyle *fstyle, char *str, const size_t max_len, const float okwidth,
- const char *sep, const int sep_len, const float sep_strwidth, size_t *r_final_len)
+static void ui_text_clip_right_ex(
+ uiFontStyle *fstyle, char *str, const size_t max_len, const float okwidth,
+ const char *sep, const int sep_len, const float sep_strwidth, size_t *r_final_len)
{
float tmp;
int l_end;
@@ -968,11 +968,16 @@ static void ui_text_clip_right_ex(uiFontStyle *fstyle, char *str, const size_t m
* If rpart_sep is not Null, the part of str starting to first occurrence of rpart_sep is preserved at all cost (useful
* for strings with shortcuts, like 'AVeryLongFooBarLabelForMenuEntry|Ctrl O' -> 'AVeryLong...MenuEntry|Ctrl O').
*/
-static float ui_text_clip_middle_ex(uiFontStyle *fstyle, char *str, float okwidth, const float minwidth,
- const size_t max_len, const char *rpart_sep)
+float UI_text_clip_middle_ex(
+ uiFontStyle *fstyle, char *str, float okwidth, const float minwidth,
+ const size_t max_len, const char rpart_sep)
{
float strwidth;
+ /* Add some epsilon to OK width, avoids 'ellipsing' text that nearly fits!
+ * Better to have a small piece of the last char cut out, than two remaining chars replaced by an allipsis... */
+ okwidth += 1.0f + UI_DPI_FAC;
+
BLI_assert(str[0]);
/* need to set this first */
@@ -998,7 +1003,7 @@ static float ui_text_clip_middle_ex(uiFontStyle *fstyle, char *str, float okwidt
size_t final_lpart_len;
if (rpart_sep) {
- rpart = strstr(str, rpart_sep);
+ rpart = strrchr(str, rpart_sep);
if (rpart) {
rpart_len = strlen(rpart);
@@ -1069,7 +1074,7 @@ static float ui_text_clip_middle_ex(uiFontStyle *fstyle, char *str, float okwidt
}
/**
- * Wrapper around ui_text_clip_middle_ex.
+ * Wrapper around UI_text_clip_middle_ex.
*/
static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
{
@@ -1080,14 +1085,14 @@ static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rec
const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f;
but->ofs = 0;
- but->strwidth = ui_text_clip_middle_ex(fstyle, but->drawstr, okwidth, minwidth, max_len, NULL);
+ but->strwidth = UI_text_clip_middle_ex(fstyle, but->drawstr, okwidth, minwidth, max_len, '\0');
}
/**
* Like ui_text_clip_middle(), but protect/preserve at all cost the right part of the string after sep.
* Useful for strings with shortcuts (like 'AVeryLongFooBarLabelForMenuEntry|Ctrl O' -> 'AVeryLong...MenuEntry|Ctrl O').
*/
-static void ui_text_clip_middle_protect_right(uiFontStyle *fstyle, uiBut *but, const rcti *rect, const char *rsep)
+static void ui_text_clip_middle_protect_right(uiFontStyle *fstyle, uiBut *but, const rcti *rect, const char rsep)
{
/* No margin for labels! */
const int border = ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_MENU) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
@@ -1096,7 +1101,7 @@ static void ui_text_clip_middle_protect_right(uiFontStyle *fstyle, uiBut *but, c
const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f;
but->ofs = 0;
- but->strwidth = ui_text_clip_middle_ex(fstyle, but->drawstr, okwidth, minwidth, max_len, rsep);
+ but->strwidth = UI_text_clip_middle_ex(fstyle, but->drawstr, okwidth, minwidth, max_len, rsep);
}
/**
@@ -1217,7 +1222,6 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti
but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs);
if (but->strwidth < 10) break;
}
-
}
@@ -1320,7 +1324,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
#ifdef WITH_INPUT_IME
/* FIXME, IME is modifying 'const char *drawstr! */
- ime_data = ui_but_get_ime_data(but);
+ ime_data = ui_but_ime_data_get(but);
if (ime_data && ime_data->composite_len) {
/* insert composite string into cursor pos */
@@ -1384,7 +1388,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
t = 0;
}
- glColor3f(0.20, 0.6, 0.9);
+ glColor3f(0.2, 0.6, 0.9);
tx = rect->xmin + t + 2;
ty = rect->ymin + 2;
@@ -1505,6 +1509,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
const bool show_menu_icon = ui_but_draw_menu_icon(but);
float alpha = (float)wcol->text[3] / 255.0f;
char password_str[UI_MAX_DRAW_STR];
+ uiButExtraIconType extra_icon_type;
ui_but_text_password_hide(password_str, but, false);
@@ -1518,7 +1523,34 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
/* If there's an icon too (made with uiDefIconTextBut) then draw the icon
* and offset the text label to accommodate it */
- if (but->flag & UI_HAS_ICON || show_menu_icon) {
+ /* Big previews with optional text label below */
+ if (but->flag & UI_BUT_ICON_PREVIEW && ui_block_is_menu(but->block)) {
+ const BIFIconID icon = (but->flag & UI_HAS_ICON) ? but->icon + but->iconadd : ICON_NONE;
+ int icon_size = BLI_rcti_size_y(rect);
+ int text_size = 0;
+
+ /* This is a bit britle, but avoids adding an 'UI_BUT_HAS_LABEL' flag to but... */
+ if (icon_size > BLI_rcti_size_x(rect)) {
+ /* button is not square, it has extra height for label */
+ text_size = UI_UNIT_Y;
+ icon_size -= text_size;
+ }
+
+ /* draw icon in rect above the space reserved for the label */
+ rect->ymin += text_size;
+ glEnable(GL_BLEND);
+ widget_draw_preview(icon, alpha, rect);
+ glDisable(GL_BLEND);
+
+ /* offset rect to draw label in */
+ rect->ymin -= text_size;
+ rect->ymax -= icon_size;
+
+ /* vertically centering text */
+ rect->ymin += UI_UNIT_Y / 2;
+ }
+ /* Icons on the left with optional text label on the right */
+ else if (but->flag & UI_HAS_ICON || show_menu_icon) {
const BIFIconID icon = (but->flag & UI_HAS_ICON) ? but->icon + but->iconadd : ICON_NONE;
const float icon_size = ICON_SIZE_FROM_BUTRECT(rect);
@@ -1544,11 +1576,23 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
}
/* unlink icon for this button type */
- if ((but->type == UI_BTYPE_SEARCH_MENU_UNLINK) && ui_but_is_search_unlink_visible(but)) {
+ if ((but->type == UI_BTYPE_SEARCH_MENU) &&
+ ((extra_icon_type = ui_but_icon_extra_get(but)) != UI_BUT_ICONEXTRA_NONE))
+ {
rcti temp = *rect;
temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f);
- widget_draw_icon(but, ICON_X, alpha, &temp, false);
+
+ if (extra_icon_type == UI_BUT_ICONEXTRA_UNLINK) {
+ widget_draw_icon(but, ICON_X, alpha, &temp, false);
+ }
+ else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
+ widget_draw_icon(but, ICON_EYEDROPPER, alpha, &temp, false);
+ }
+ else {
+ BLI_assert(0);
+ }
+
rect->xmax -= ICON_SIZE_FROM_BUTRECT(rect);
}
@@ -1564,9 +1608,9 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
else if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) {
ui_text_clip_right_label(fstyle, but, rect);
}
- else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == UI_BTYPE_BUT)) {
+ else if (but->flag & UI_BUT_HAS_SEP_CHAR) {
/* Clip middle, but protect in all case right part containing the shortcut, if any. */
- ui_text_clip_middle_protect_right(fstyle, but, rect, "|");
+ ui_text_clip_middle_protect_right(fstyle, but, rect, UI_SEP_CHAR);
}
else {
ui_text_clip_middle(fstyle, but, rect);
@@ -1583,17 +1627,6 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
/* *********************** widget types ************************************* */
-
-/* uiWidgetStateColors
- * char inner_anim[4];
- * char inner_anim_sel[4];
- * char inner_key[4];
- * char inner_key_sel[4];
- * char inner_driven[4];
- * char inner_driven_sel[4];
- * float blend;
- */
-
static struct uiWidgetStateColors wcol_state_colors = {
{115, 190, 76, 255},
{90, 166, 51, 255},
@@ -1604,18 +1637,6 @@ static struct uiWidgetStateColors wcol_state_colors = {
0.5f, 0.0f
};
-/* uiWidgetColors
- * char outline[3];
- * char inner[4];
- * char inner_sel[4];
- * char item[3];
- * char text[3];
- * char text_sel[3];
- *
- * short shaded;
- * float shadetop, shadedown;
- */
-
static struct uiWidgetColors wcol_num = {
{25, 25, 25, 255},
{180, 180, 180, 255},
@@ -1746,7 +1767,7 @@ static struct uiWidgetColors wcol_tooltip = {
{45, 45, 45, 230},
{100, 100, 100, 255},
- {160, 160, 160, 255},
+ {255, 255, 255, 255},
{255, 255, 255, 255},
0,
@@ -2181,7 +2202,7 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir
widget_softshadow(rect, roundboxalign, 0.25f * U.widget_unit);
round_box_edges(&wtb, roundboxalign, rect, 0.25f * U.widget_unit);
- wtb.emboss = 0;
+ wtb.draw_emboss = false;
widgetbase_draw(&wtb, wcol);
glDisable(GL_BLEND);
@@ -2190,7 +2211,6 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir
static void ui_hsv_cursor(float x, float y)
{
-
glPushMatrix();
glTranslatef(x, y, 0.0f);
@@ -2205,7 +2225,6 @@ static void ui_hsv_cursor(float x, float y)
glDisable(GL_LINE_SMOOTH);
glPopMatrix();
-
}
void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rect,
@@ -2280,12 +2299,12 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
* Useful for color correction tools where you're only interested in hue. */
if (but->flag & UI_BUT_COLOR_LOCK) {
if (U.color_picker_type == USER_CP_CIRCLE_HSV)
- hsv[2] = 1.f;
+ hsv[2] = 1.0f;
else
hsv[2] = 0.5f;
}
- ui_color_picker_to_rgb(0.f, 0.f, hsv[2], colcent, colcent + 1, colcent + 2);
+ ui_color_picker_to_rgb(0.0f, 0.0f, hsv[2], colcent, colcent + 1, colcent + 2);
glShadeModel(GL_SMOOTH);
@@ -2331,7 +2350,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha)
{
/* allows for 4 steps (red->yellow) */
- const float color_step = (1.0 / 48.0);
+ const float color_step = 1.0f / 48.0f;
int a;
float h = hsv[0], s = hsv[1], v = hsv[2];
float dx, dy, sx1, sx2, sy;
@@ -2344,9 +2363,9 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons
switch (type) {
case UI_GRAD_SV:
hsv_to_rgb(h, 0.0, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
- hsv_to_rgb(h, 0.333, 0.0, &col1[1][0], &col1[1][1], &col1[1][2]);
- hsv_to_rgb(h, 0.666, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
- hsv_to_rgb(h, 1.0, 0.0, &col1[3][0], &col1[3][1], &col1[3][2]);
+ hsv_to_rgb(h, 0.0, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
+ hsv_to_rgb(h, 0.0, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
+ hsv_to_rgb(h, 0.0, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
break;
case UI_GRAD_HV:
hsv_to_rgb(0.0, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
@@ -2361,26 +2380,26 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons
hsv_to_rgb(0.0, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]);
break;
case UI_GRAD_H:
- hsv_to_rgb(0.0, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]);
+ hsv_to_rgb(0.0, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]);
copy_v3_v3(col1[1], col1[0]);
copy_v3_v3(col1[2], col1[0]);
copy_v3_v3(col1[3], col1[0]);
break;
case UI_GRAD_S:
- hsv_to_rgb(1.0, 0.0, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]);
+ hsv_to_rgb(1.0, 0.0, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]);
copy_v3_v3(col1[0], col1[1]);
copy_v3_v3(col1[2], col1[1]);
copy_v3_v3(col1[3], col1[1]);
break;
case UI_GRAD_V:
- hsv_to_rgb(1.0, 1.0, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
+ hsv_to_rgb(1.0, 1.0, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
copy_v3_v3(col1[0], col1[2]);
copy_v3_v3(col1[1], col1[2]);
copy_v3_v3(col1[3], col1[2]);
break;
default:
assert(!"invalid 'type' argument");
- hsv_to_rgb(1.0, 1.0, 1.0, &col1[2][0], &col1[2][1], &col1[2][2]);
+ hsv_to_rgb(1.0, 1.0, 1.0, &col1[2][0], &col1[2][1], &col1[2][2]);
copy_v3_v3(col1[0], col1[2]);
copy_v3_v3(col1[1], col1[2]);
copy_v3_v3(col1[3], col1[2]);
@@ -2401,10 +2420,10 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons
/* new color */
switch (type) {
case UI_GRAD_SV:
- hsv_to_rgb(h, 0.0, dx, &col1[0][0], &col1[0][1], &col1[0][2]);
- hsv_to_rgb(h, 0.333, dx, &col1[1][0], &col1[1][1], &col1[1][2]);
- hsv_to_rgb(h, 0.666, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
- hsv_to_rgb(h, 1.0, dx, &col1[3][0], &col1[3][1], &col1[3][2]);
+ hsv_to_rgb(h, dx, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
+ hsv_to_rgb(h, dx, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
+ hsv_to_rgb(h, dx, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
+ hsv_to_rgb(h, dx, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
break;
case UI_GRAD_HV:
hsv_to_rgb(dx_next, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
@@ -2419,23 +2438,21 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons
hsv_to_rgb(dx_next, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]);
break;
case UI_GRAD_H:
- {
/* annoying but without this the color shifts - could be solved some other way
* - campbell */
- hsv_to_rgb(dx_next, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]);
+ hsv_to_rgb(dx_next, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]);
copy_v3_v3(col1[1], col1[0]);
copy_v3_v3(col1[2], col1[0]);
copy_v3_v3(col1[3], col1[0]);
break;
- }
case UI_GRAD_S:
- hsv_to_rgb(h, dx, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]);
+ hsv_to_rgb(h, dx, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]);
copy_v3_v3(col1[0], col1[1]);
copy_v3_v3(col1[2], col1[1]);
copy_v3_v3(col1[3], col1[1]);
break;
case UI_GRAD_V:
- hsv_to_rgb(h, 1.0, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
+ hsv_to_rgb(h, 1.0, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
copy_v3_v3(col1[0], col1[2]);
copy_v3_v3(col1[1], col1[2]);
copy_v3_v3(col1[3], col1[2]);
@@ -2464,9 +2481,8 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons
}
glEnd();
}
-
+
glShadeModel(GL_FLAT);
-
}
bool ui_but_is_colorpicker_display_space(uiBut *but)
@@ -2487,7 +2503,7 @@ void ui_hsvcube_pos_from_vals(uiBut *but, const rcti *rect, float *hsv, float *x
switch ((int)but->a1) {
case UI_GRAD_SV:
- x = hsv[2]; y = hsv[1]; break;
+ x = hsv[1]; y = hsv[2]; break;
case UI_GRAD_HV:
x = hsv[0]; y = hsv[2]; break;
case UI_GRAD_HS:
@@ -2509,11 +2525,10 @@ void ui_hsvcube_pos_from_vals(uiBut *but, const rcti *rect, float *hsv, float *x
y = (hsv[2] - but->softmin) / (but->softmax - but->softmin);
break;
}
-
+
/* cursor */
*xp = rect->xmin + x * BLI_rcti_size_x(rect);
*yp = rect->ymin + y * BLI_rcti_size_y(rect);
-
}
static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
@@ -2594,9 +2609,8 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
x = rect->xmin + 0.5f * BLI_rcti_size_x(rect);
y = rect->ymin + v * BLI_rcti_size_y(rect);
CLAMP(y, rect->ymin + 3.0f, rect->ymax - 3.0f);
-
+
ui_hsv_cursor(x, y);
-
}
@@ -2681,7 +2695,8 @@ bool ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol)
BKE_curve_forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], &coord_array[0][0], resol, sizeof(float[2]));
BKE_curve_forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], &coord_array[0][1], resol, sizeof(float[2]));
- return 1;
+ /* TODO: why return anything if always true? */
+ return true;
}
#define LINK_RESOL 24
@@ -2690,9 +2705,10 @@ void ui_draw_link_bezier(const rcti *rect)
float coord_array[LINK_RESOL + 1][2];
if (ui_link_bezier_points(rect, coord_array, LINK_RESOL)) {
+#if 0 /* unused */
/* we can reuse the dist variable here to increment the GL curve eval amount*/
- // const float dist = 1.0f / (float)LINK_RESOL; // UNUSED
-
+ const float dist = 1.0f / (float)LINK_RESOL;
+#endif
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
@@ -2703,7 +2719,6 @@ void ui_draw_link_bezier(const rcti *rect)
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
-
}
}
@@ -2725,7 +2740,7 @@ void UI_draw_widget_scroll(uiWidgetColors *wcol, const rcti *rect, const rcti *s
else
rad = 0.5f * BLI_rcti_size_x(rect);
- wtb.shadedir = (horizontal) ? 1 : 0;
+ wtb.draw_shadedir = (horizontal) ? true : false;
/* draw back part, colors swapped and shading inverted */
if (horizontal)
@@ -2754,11 +2769,11 @@ void UI_draw_widget_scroll(uiWidgetColors *wcol, const rcti *rect, const rcti *s
}
/* draw */
- wtb.emboss = 0; /* only emboss once */
+ wtb.draw_emboss = false; /* only emboss once */
/* exception for progress bar */
if (state & UI_SCROLL_NO_OUTLINE) {
- SWAP(bool, outline, wtb.outline);
+ SWAP(bool, outline, wtb.draw_outline);
}
round_box_edges(&wtb, UI_CNR_ALL, slider, rad);
@@ -2781,7 +2796,7 @@ void UI_draw_widget_scroll(uiWidgetColors *wcol, const rcti *rect, const rcti *s
widgetbase_draw(&wtb, wcol);
if (state & UI_SCROLL_NO_OUTLINE) {
- SWAP(bool, outline, wtb.outline);
+ SWAP(bool, outline, wtb.draw_outline);
}
}
}
@@ -2908,7 +2923,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
toffs = offs * 0.75f;
round_box_edges(&wtb, roundboxalign, rect, offs);
- wtb.outline = 0;
+ wtb.draw_outline = false;
widgetbase_draw(&wtb, wcol);
/* draw left/right parts only when not in text editing */
@@ -2933,7 +2948,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
/* left part of slider, always rounded */
rect1.xmax = rect1.xmin + ceil(offs + U.pixelsize);
round_box_edges(&wtb1, roundboxalign & ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT), &rect1, offs);
- wtb1.outline = 0;
+ wtb1.draw_outline = false;
widgetbase_draw(&wtb1, wcol);
/* right part of slider, interpolate roundness */
@@ -2958,8 +2973,8 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
}
/* outline */
- wtb.outline = 1;
- wtb.inner = 0;
+ wtb.draw_outline = true;
+ wtb.draw_inner = false;
widgetbase_draw(&wtb, wcol);
/* add space at either side of the button so text aligns with numbuttons (which have arrow icons) */
@@ -2967,7 +2982,6 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
rect->xmax -= toffs;
rect->xmin += toffs;
}
-
}
/* I think 3 is sufficient border to indicate keyed status */
@@ -3027,7 +3041,7 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
float width = rect->xmax - rect->xmin;
float height = rect->ymax - rect->ymin;
/* find color luminance and change it slightly */
- float bw = rgb_to_bw(col);
+ float bw = rgb_to_grayscale(col);
bw += (bw < 0.5f) ? 0.5f : -0.5f;
@@ -3052,7 +3066,7 @@ static void widget_icon_has_anim(uiBut *but, uiWidgetColors *wcol, rcti *rect, i
float rad;
widget_init(&wtb);
- wtb.outline = 0;
+ wtb.draw_outline = false;
/* rounded */
rad = 0.5f * BLI_rcti_size_y(rect);
@@ -3082,7 +3096,6 @@ static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roun
round_box_edges(&wtb, roundboxalign, rect, rad);
widgetbase_draw(&wtb, wcol);
-
}
@@ -3168,7 +3181,7 @@ static void widget_menu_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(sta
widget_init(&wtb);
/* not rounded, no outline */
- wtb.outline = 0;
+ wtb.draw_outline = false;
round_box_edges(&wtb, 0, rect, 0.0f);
widgetbase_draw(&wtb, wcol);
@@ -3182,7 +3195,7 @@ static void widget_menu_radial_itembut(uiBut *but, uiWidgetColors *wcol, rcti *r
widget_init(&wtb);
- wtb.emboss = 0;
+ wtb.draw_emboss = false;
rad = 0.5f * BLI_rcti_size_y(rect);
round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
@@ -3205,7 +3218,7 @@ static void widget_list_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(sta
widget_init(&wtb);
/* rounded, but no outline */
- wtb.outline = 0;
+ wtb.draw_outline = false;
rad = 0.2f * U.widget_unit;
round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
@@ -3278,7 +3291,6 @@ static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state),
round_box_edges(&wtb, roundboxalign, rect, rad);
widgetbase_draw(&wtb, wcol);
-
}
static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
@@ -3319,7 +3331,6 @@ static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int
round_box_edges(&wtb, roundboxalign, rect, rad);
widgetbase_draw(&wtb, wcol);
-
}
static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
@@ -3360,10 +3371,9 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
/* outline */
round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
- wtb.outline = 1;
- wtb.inner = 0;
+ wtb.draw_outline = true;
+ wtb.draw_inner = false;
widgetbase_draw(&wtb, &wt->wcol);
-
}
static uiWidgetType *widget_type(uiWidgetTypeEnum type)
@@ -3653,8 +3663,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
case UI_BTYPE_TEXT:
wt = widget_type(UI_WTYPE_NAME);
break;
-
- case UI_BTYPE_SEARCH_MENU_UNLINK:
+
case UI_BTYPE_SEARCH_MENU:
wt = widget_type(UI_WTYPE_NAME);
if (but->block->flag & UI_BLOCK_LOOP)
@@ -3931,7 +3940,6 @@ static void draw_disk_shaded(
glVertex2f(c * radius_ext, s * radius_ext);
}
glEnd();
-
}
void ui_draw_pie_center(uiBlock *block)
@@ -4020,7 +4028,6 @@ void ui_draw_search_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect)
wt->draw(&wt->wcol, rect, block->flag, UI_CNR_ALL);
else
wt->draw(&wt->wcol, rect, 0, UI_CNR_ALL);
-
}
@@ -4070,7 +4077,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
const float minwidth = (float)(UI_DPI_ICON_SIZE);
BLI_strncpy(drawstr, name, sizeof(drawstr));
- ui_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, NULL);
+ UI_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, '\0');
glColor4ubv((unsigned char *)wt->wcol.text);
UI_fontstyle_draw(fstyle, rect, drawstr);
@@ -4105,39 +4112,31 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state)
{
- rcti trect = *rect, bg_rect;
+ rcti trect = *rect;
+ const float text_size = UI_UNIT_Y;
float font_dims[2] = {0.0f, 0.0f};
uiWidgetType *wt = widget_type(UI_WTYPE_MENU_ITEM);
+ /* drawing button background */
wt->state(wt, state);
wt->draw(&wt->wcol, rect, 0, 0);
+ /* draw icon in rect above the space reserved for the label */
+ rect->ymin += text_size;
glEnable(GL_BLEND);
widget_draw_preview(iconid, 1.0f, rect);
+ glDisable(GL_BLEND);
BLF_width_and_height(fstyle->uifont_id, name, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]);
/* text rect */
trect.xmin += 0;
- trect.xmax = trect.xmin + font_dims[0] + 10;
- trect.ymin += 10;
+ trect.xmax = trect.xmin + font_dims[0] + U.widget_unit / 2;
+ trect.ymin += U.widget_unit / 2;
trect.ymax = trect.ymin + font_dims[1];
if (trect.xmax > rect->xmax - PREVIEW_PAD)
trect.xmax = rect->xmax - PREVIEW_PAD;
- bg_rect = trect;
- bg_rect.xmin = rect->xmin + PREVIEW_PAD;
- bg_rect.ymin = rect->ymin + PREVIEW_PAD;
- bg_rect.xmax = rect->xmax - PREVIEW_PAD;
- bg_rect.ymax += PREVIEW_PAD / 2;
-
- if (bg_rect.xmax > rect->xmax - PREVIEW_PAD)
- bg_rect.xmax = rect->xmax - PREVIEW_PAD;
-
- glColor4ubv((unsigned char *)wt->wcol_theme->inner_sel);
- glRecti(bg_rect.xmin, bg_rect.ymin, bg_rect.xmax, bg_rect.ymax);
- glDisable(GL_BLEND);
-
{
char drawstr[UI_MAX_DRAW_STR];
const float okwidth = (float)BLI_rcti_size_x(&trect);
@@ -4145,7 +4144,7 @@ void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, const char *name, int
const float minwidth = (float)(UI_DPI_ICON_SIZE);
BLI_strncpy(drawstr, name, sizeof(drawstr));
- ui_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, NULL);
+ UI_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, '\0');
glColor4ubv((unsigned char *)wt->wcol.text);
UI_fontstyle_draw(fstyle, &trect, drawstr);
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index a9cc53852c0..68016ae3dd8 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -569,6 +569,13 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
cp = ts->paint_curve_pivot;
break;
+ case TH_METADATA_BG:
+ cp = ts->metadatabg;
+ break;
+ case TH_METADATA_TEXT:
+ cp = ts->metadatatext;
+ break;
+
case TH_UV_OTHERS:
cp = ts->uv_others;
break;
@@ -817,8 +824,9 @@ static void ui_theme_space_init_handles_color(ThemeSpace *theme_space)
rgba_char_args_set(theme_space->act_spline, 0xdb, 0x25, 0x12, 255);
}
-/* initialize default theme
- * Note: when you add new colors, created & saved themes need initialized
+/**
+ * initialize default theme
+ * \note: when you add new colors, created & saved themes need initialized
* use function below, init_userdef_do_versions()
*/
void ui_theme_init_default(void)
@@ -1098,7 +1106,7 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->text.syntaxd, 50, 0, 140, 255); /* Decorator/Preprocessor Dir. Blue-purple */
rgba_char_args_set(btheme->text.syntaxr, 140, 60, 0, 255); /* Reserved Orange*/
rgba_char_args_set(btheme->text.syntaxb, 128, 0, 80, 255); /* Builtin Red-purple */
- rgba_char_args_set(btheme->text.syntaxs, 76, 76, 76, 255); /* Grey (mix between fg/bg) */
+ rgba_char_args_set(btheme->text.syntaxs, 76, 76, 76, 255); /* Gray (mix between fg/bg) */
/* space oops */
btheme->toops = btheme->tv3d;
@@ -1504,8 +1512,9 @@ void UI_GetColorPtrShade3ubv(const unsigned char cp[3], unsigned char col[3], in
}
/* get a 3 byte color, blended and shaded between two other char color pointers */
-void UI_GetColorPtrBlendShade3ubv(const unsigned char cp1[3], const unsigned char cp2[3], unsigned char col[3],
- float fac, int offset)
+void UI_GetColorPtrBlendShade3ubv(
+ const unsigned char cp1[3], const unsigned char cp2[3], unsigned char col[3],
+ float fac, int offset)
{
int r, g, b;
@@ -1603,8 +1612,8 @@ void init_userdef_do_versions(void)
U.tw_size = 25; /* percentage of window size */
U.tw_handlesize = 16; /* percentage of widget radius */
}
- if (U.pad_rot_angle == 0)
- U.pad_rot_angle = 15;
+ if (U.pad_rot_angle == 0.0f)
+ U.pad_rot_angle = 15.0f;
/* graph editor - unselected F-Curve visibility */
if (U.fcu_inactive_alpha == 0) {
@@ -2351,7 +2360,7 @@ void init_userdef_do_versions(void)
for (btheme = U.themes.first; btheme; btheme = btheme->next) {
rgba_char_args_set(btheme->text.syntaxd, 50, 0, 140, 255); /* Decorator/Preprocessor Dir. Blue-purple */
rgba_char_args_set(btheme->text.syntaxr, 140, 60, 0, 255); /* Reserved Orange */
- rgba_char_args_set(btheme->text.syntaxs, 76, 76, 76, 255); /* Grey (mix between fg/bg) */
+ rgba_char_args_set(btheme->text.syntaxs, 76, 76, 76, 255); /* Gray (mix between fg/bg) */
}
}
@@ -2602,7 +2611,22 @@ void init_userdef_do_versions(void)
cp[3] = 255;
}
}
-
+
+ if (U.versionfile < 274 || (U.versionfile == 274 && U.subversionfile < 5)) {
+ bTheme *btheme;
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ copy_v4_v4_char(btheme->tima.metadatatext, btheme->tima.text_hi);
+ copy_v4_v4_char(btheme->tseq.metadatatext, btheme->tseq.text_hi);
+ }
+ }
+
+ if (U.versionfile < 275 || (U.versionfile == 275 && U.subversionfile < 1)) {
+ bTheme *btheme;
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ copy_v4_v4_char(btheme->tclip.metadatatext, btheme->tseq.text_hi);
+ }
+ }
+
if (U.pixelsize == 0.0f)
U.pixelsize = 1.0f;
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index b4a120b2dea..4f4b5ab07ff 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -99,11 +99,12 @@ BLI_INLINE void clamp_rctf_to_rcti(rcti *dst, const rctf *src)
/* XXX still unresolved: scrolls hide/unhide vs region mask handling */
/* XXX there's V2D_SCROLL_HORIZONTAL_HIDE and V2D_SCROLL_HORIZONTAL_FULLR ... */
-/* helper to allow scrollbars to dynamically hide
- * - returns a copy of the scrollbar settings with the flags to display
- * horizontal/vertical scrollbars removed
- * - input scroll value is the v2d->scroll var
- * - hide flags are set per region at drawtime
+/**
+ * helper to allow scrollbars to dynamically hide
+ * - returns a copy of the scrollbar settings with the flags to display
+ * horizontal/vertical scrollbars removed
+ * - input scroll value is the v2d->scroll var
+ * - hide flags are set per region at drawtime
*/
static int view2d_scroll_mapped(int scroll)
{
@@ -197,11 +198,12 @@ static void view2d_masks(View2D *v2d, int check_scrollers)
/* Refresh and Validation */
-/* Initialize all relevant View2D data (including view rects if first time) and/or refresh mask sizes after view resize
- * - for some of these presets, it is expected that the region will have defined some
- * additional settings necessary for the customization of the 2D viewport to its requirements
- * - this function should only be called from region init() callbacks, where it is expected that
- * this is called before UI_view2d_size_update(), as this one checks that the rects are properly initialized.
+/**
+ * Initialize all relevant View2D data (including view rects if first time) and/or refresh mask sizes after view resize
+ * - for some of these presets, it is expected that the region will have defined some
+ * additional settings necessary for the customization of the 2D viewport to its requirements
+ * - this function should only be called from region init() callbacks, where it is expected that
+ * this is called before UI_view2d_size_update(), as this one checks that the rects are properly initialized.
*/
void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
{
@@ -320,7 +322,7 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
if (do_init) {
float panelzoom = (style) ? style->panelzoom : 1.0f;
- float scrolw = v2d->scroll & V2D_SCROLL_RIGHT ? V2D_SCROLL_WIDTH : 0.0f;
+ float scrolw = (v2d->scroll & V2D_SCROLL_RIGHT) ? V2D_SCROLL_WIDTH : 0.0f;
v2d->tot.xmin = 0.0f;
v2d->tot.xmax = winx - scrolw;
@@ -361,8 +363,9 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
}
-/* Ensure View2D rects remain in a viable configuration
- * - cur is not allowed to be: larger than max, smaller than min, or outside of tot
+/**
+ * Ensure View2D rects remain in a viable configuration
+ * 'cur' is not allowed to be: larger than max, smaller than min, or outside of 'tot'
*/
// XXX pre2.5 -> this used to be called test_view2d()
static void ui_view2d_curRect_validate_resize(View2D *v2d, int resize, int mask_scrollers)
@@ -842,7 +845,8 @@ void UI_view2d_sync(bScreen *screen, ScrArea *area, View2D *v2dcur, int flag)
}
-/* Restore 'cur' rect to standard orientation (i.e. optimal maximum view of tot)
+/**
+ * Restore 'cur' rect to standard orientation (i.e. optimal maximum view of tot)
* This does not take into account if zooming the view on an axis will improve the view (if allowed)
*/
void UI_view2d_curRect_reset(View2D *v2d)
@@ -1098,8 +1102,10 @@ void UI_view2d_view_ortho(View2D *v2d)
glLoadIdentity();
}
-/* Set view matrices to only use one axis of 'cur' only
- * - xaxis = if non-zero, only use cur x-axis, otherwise use cur-yaxis (mostly this will be used for x)
+/**
+ * Set view matrices to only use one axis of 'cur' only
+ *
+ * \param xaxis: if non-zero, only use cur x-axis, otherwise use cur-yaxis (mostly this will be used for x)
*/
void UI_view2d_view_orthoSpecial(ARegion *ar, View2D *v2d, const bool xaxis)
{
@@ -1192,20 +1198,23 @@ static void step_to_grid(float *step, int *power, int unit)
}
}
-/* Initialize settings necessary for drawing gridlines in a 2d-view
- * - Currently, will return pointer to View2DGrid struct that needs to
- * be freed with UI_view2d_grid_free()
- * - Is used for scrollbar drawing too (for units drawing)
- * - Units + clamping args will be checked, to make sure they are valid values that can be used
- * so it is very possible that we won't return grid at all!
- *
- * - xunits,yunits = V2D_UNIT_* grid steps in seconds or frames
- * - xclamp,yclamp = V2D_CLAMP_* only show whole-number intervals
- * - winx = width of region we're drawing to, note: not used but keeping for completeness.
- * - winy = height of region we're drawing into
+/**
+ * Initialize settings necessary for drawing gridlines in a 2d-view
+ *
+ * - Currently, will return pointer to View2DGrid struct that needs to
+ * be freed with UI_view2d_grid_free()
+ * - Is used for scrollbar drawing too (for units drawing)
+ * - Units + clamping args will be checked, to make sure they are valid values that can be used
+ * so it is very possible that we won't return grid at all!
+ *
+ * - xunits,yunits = V2D_UNIT_* grid steps in seconds or frames
+ * - xclamp,yclamp = V2D_CLAMP_* only show whole-number intervals
+ * - winx = width of region we're drawing to, note: not used but keeping for completeness.
+ * - winy = height of region we're drawing into
*/
-View2DGrid *UI_view2d_grid_calc(Scene *scene, View2D *v2d,
- short xunits, short xclamp, short yunits, short yclamp, int UNUSED(winx), int winy)
+View2DGrid *UI_view2d_grid_calc(
+ Scene *scene, View2D *v2d,
+ short xunits, short xclamp, short yunits, short yclamp, int UNUSED(winx), int winy)
{
View2DGrid *grid;
@@ -1483,9 +1492,11 @@ void UI_view2d_grid_free(View2DGrid *grid)
/* *********************************************************************** */
/* Scrollers */
-/* View2DScrollers is typedef'd in UI_view2d.h
- * WARNING: the start of this struct must not change, as view2d_ops.c uses this too.
- * For now, we don't need to have a separate (internal) header for structs like this...
+/**
+ * View2DScrollers is typedef'd in UI_view2d.h
+ *
+ * \warning The start of this struct must not change, as view2d_ops.c uses this too.
+ * For now, we don't need to have a separate (internal) header for structs like this...
*/
struct View2DScrollers {
/* focus bubbles */
@@ -1502,8 +1513,9 @@ struct View2DScrollers {
};
/* Calculate relevant scroller properties */
-View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d,
- short xunits, short xclamp, short yunits, short yclamp)
+View2DScrollers *UI_view2d_scrollers_calc(
+ const bContext *C, View2D *v2d,
+ short xunits, short xclamp, short yunits, short yclamp)
{
View2DScrollers *scrollers;
rcti vert, hor;
@@ -1885,18 +1897,22 @@ void UI_view2d_scrollers_free(View2DScrollers *scrollers)
/* *********************************************************************** */
/* List View Utilities */
-/* Get the view-coordinates of the nominated cell
- * - columnwidth, rowheight = size of each 'cell'
- * - startx, starty = coordinates (in 'tot' rect space) that the list starts from
- * This should be (0,0) for most views. However, for those where the starting row was offsetted
- * (like for Animation Editor channel lists, to make the first entry more visible), these will be
- * the min-coordinates of the first item.
- * - column, row = the 2d-coordinates (in 2D-view / 'tot' rect space) the cell exists at
- * - rect = coordinates of the cell (passed as single var instead of 4 separate, as it's more useful this way)
+/** Get the view-coordinates of the nominated cell
+ *
+ * \param columnwidth, rowheight: size of each 'cell'
+ * \param startx, starty: coordinates (in 'tot' rect space) that the list starts from.
+ * This should be (0,0) for most views. However, for those where the starting row was offsetted
+ * (like for Animation Editor channel lists, to make the first entry more visible), these will be
+ * the min-coordinates of the first item.
+ * \param column, row: The 2d-coordinates
+ * (in 2D-view / 'tot' rect space) the cell exists at
+ * \param rect: coordinates of the cell
+ * (passed as single var instead of 4 separate, as it's more useful this way)
*/
-void UI_view2d_listview_cell_to_view(View2D *v2d, float columnwidth, float rowheight,
- float startx, float starty,
- int column, int row, rctf *rect)
+void UI_view2d_listview_cell_to_view(
+ View2D *v2d, float columnwidth, float rowheight,
+ float startx, float starty,
+ int column, int row, rctf *rect)
{
/* sanity checks */
if (ELEM(NULL, v2d, rect)) {
@@ -1930,17 +1946,20 @@ void UI_view2d_listview_cell_to_view(View2D *v2d, float columnwidth, float rowhe
}
}
-/* Get the 'cell' (row, column) that the given 2D-view coordinates (i.e. in 'tot' rect space) lie in.
- * - columnwidth, rowheight = size of each 'cell'
- * - startx, starty = coordinates (in 'tot' rect space) that the list starts from
- * This should be (0,0) for most views. However, for those where the starting row was offsetted
- * (like for Animation Editor channel lists, to make the first entry more visible), these will be
- * the min-coordinates of the first item.
- * - viewx, viewy = 2D-coordinates (in 2D-view / 'tot' rect space) to get the cell for
- * - column, row = the 'coordinates' of the relevant 'cell'
+/**
+ * Get the 'cell' (row, column) that the given 2D-view coordinates (i.e. in 'tot' rect space) lie in.
+ *
+ * \param columnwidth, rowheight: size of each 'cell'
+ * \param startx, starty: coordinates (in 'tot' rect space) that the list starts from.
+ * This should be (0,0) for most views. However, for those where the starting row was offsetted
+ * (like for Animation Editor channel lists, to make the first entry more visible), these will be
+ * the min-coordinates of the first item.
+ * \param viewx, viewy: 2D-coordinates (in 2D-view / 'tot' rect space) to get the cell for
+ * \param column, row: the 'coordinates' of the relevant 'cell'
*/
-void UI_view2d_listview_view_to_cell(View2D *v2d, float columnwidth, float rowheight, float startx, float starty,
- float viewx, float viewy, int *column, int *row)
+void UI_view2d_listview_view_to_cell(
+ View2D *v2d, float columnwidth, float rowheight, float startx, float starty,
+ float viewx, float viewy, int *column, int *row)
{
/* adjust view coordinates to be all positive ints, corrected for the start offset */
const int x = (int)(floorf(fabsf(viewx) + 0.5f) - startx);
@@ -1967,13 +1986,16 @@ void UI_view2d_listview_view_to_cell(View2D *v2d, float columnwidth, float rowhe
*row = 0;
}
-/* Get the 'extreme' (min/max) column and row indices which are visible within the 'cur' rect
- * - columnwidth, rowheight = size of each 'cell'
- * - startx, starty = coordinates that the list starts from, which should be (0,0) for most views
- * - column/row_min/max = the starting and ending column/row indices
+/**
+ * Get the 'extreme' (min/max) column and row indices which are visible within the 'cur' rect
+ *
+ * \param columnwidth, rowheight: Size of each 'cell'
+ * \param startx, starty: Coordinates that the list starts from, which should be (0,0) for most views
+ * \param column_min, column_max, row_min, row_max: The starting and ending column/row indices
*/
-void UI_view2d_listview_visible_cells(View2D *v2d, float columnwidth, float rowheight, float startx, float starty,
- int *column_min, int *column_max, int *row_min, int *row_max)
+void UI_view2d_listview_visible_cells(
+ View2D *v2d, float columnwidth, float rowheight, float startx, float starty,
+ int *column_min, int *column_max, int *row_min, int *row_max)
{
/* using 'cur' rect coordinates, call the cell-getting function to get the cells for this */
if (v2d) {
@@ -1999,10 +2021,11 @@ float UI_view2d_region_to_view_y(struct View2D *v2d, float y)
return (v2d->cur.ymin + (BLI_rctf_size_y(&v2d->cur) * (y - v2d->mask.ymin) / BLI_rcti_size_y(&v2d->mask)));
}
-/* Convert from screen/region space to 2d-View space
- *
- * - x,y = coordinates to convert
- * - viewx,viewy = resultant coordinates
+/**
+ * Convert from screen/region space to 2d-View space
+ *
+ * \param x, y: coordinates to convert
+ * \param r_view_x, r_view_y: resultant coordinates
*/
void UI_view2d_region_to_view(View2D *v2d, float x, float y, float *r_view_x, float *r_view_y)
{
@@ -2030,11 +2053,12 @@ float UI_view2d_view_to_region_y(View2D *v2d, float y)
return (v2d->mask.ymin + (((y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur)) * BLI_rcti_size_y(&v2d->mask)));
}
-/* Convert from 2d-View space to screen/region space
- * - Coordinates are clamped to lie within bounds of region
+/**
+ * Convert from 2d-View space to screen/region space
+ * \note Coordinates are clamped to lie within bounds of region
*
- * - x,y = coordinates to convert
- * - regionx,regiony = resultant coordinates
+ * \param x, y: Coordinates to convert.
+ * \param r_region_x, r_region_y: Resultant coordinates.
*/
bool UI_view2d_view_to_region_clip(View2D *v2d, float x, float y, int *r_region_x, int *r_region_y)
{
@@ -2057,11 +2081,13 @@ bool UI_view2d_view_to_region_clip(View2D *v2d, float x, float y, int *r_region_
}
}
-/* Convert from 2d-view space to screen/region space
- * - Coordinates are NOT clamped to lie within bounds of region
+/**
+ * Convert from 2d-view space to screen/region space
+ *
+ * \note Coordinates are NOT clamped to lie within bounds of region.
*
- * - x,y = coordinates to convert
- * - regionx,regiony = resultant coordinates
+ * \param x, y: Coordinates to convert.
+ * \param r_region_x, r_region_y: Resultant coordinates.
*/
void UI_view2d_view_to_region(View2D *v2d, float x, float y, int *r_region_x, int *r_region_y)
{
@@ -2175,25 +2201,30 @@ View2D *UI_view2d_fromcontext_rwin(const bContext *C)
}
-/* Calculate the scale per-axis of the drawing-area
- * - Is used to inverse correct drawing of icons, etc. that need to follow view
- * but not be affected by scale
+/**
+ * Calculate the scale per-axis of the drawing-area
*
- * - x,y = scale on each axis
+ * Is used to inverse correct drawing of icons, etc. that need to follow view
+ * but not be affected by scale
+ *
+ * \param x, y: scale on each axis
*/
void UI_view2d_scale_get(View2D *v2d, float *x, float *y)
{
if (x) *x = BLI_rcti_size_x(&v2d->mask) / BLI_rctf_size_x(&v2d->cur);
if (y) *y = BLI_rcti_size_y(&v2d->mask) / BLI_rctf_size_y(&v2d->cur);
}
-/* Same as UI_view2d_scale_get() - 1.0f / x, y */
+/**
+ * Same as ``UI_view2d_scale_get() - 1.0f / x, y``
+ */
void UI_view2d_scale_get_inverse(View2D *v2d, float *x, float *y)
{
if (x) *x = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
if (y) *y = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
}
-/* Simple functions for consistent center offset access.
+/**
+ * Simple functions for consistent center offset access.
* Used by node editor to shift view center for each individual node tree.
*/
void UI_view2d_center_get(struct View2D *v2d, float *x, float *y)
@@ -2239,13 +2270,15 @@ void UI_view2d_offset(struct View2D *v2d, float xfac, float yfac)
UI_view2d_curRect_validate(v2d);
}
-/* Check if mouse is within scrollers
- * - Returns appropriate code for match
- * 'h' = in horizontal scroller
- * 'v' = in vertical scroller
- * 0 = not in scroller
- *
- * - x,y = mouse coordinates in screen (not region) space
+/**
+ * Check if mouse is within scrollers
+ *
+ * \param x, y: Mouse coordinates in screen (not region) space.
+ *
+ * \return appropriate code for match.
+ * - 'h' = in horizontal scroller.
+ * - 'v' = in vertical scroller.
+ * - 0 = not in scroller.
*/
short UI_view2d_mouse_in_scrollers(const bContext *C, View2D *v2d, int x, int y)
{
@@ -2288,8 +2321,9 @@ typedef struct View2DString {
static MemArena *g_v2d_strings_arena = NULL;
static View2DString *g_v2d_strings = NULL;
-void UI_view2d_text_cache_add(View2D *v2d, float x, float y,
- const char *str, size_t str_len, const char col[4])
+void UI_view2d_text_cache_add(
+ View2D *v2d, float x, float y,
+ const char *str, size_t str_len, const char col[4])
{
int mval[2];
@@ -2319,8 +2353,9 @@ void UI_view2d_text_cache_add(View2D *v2d, float x, float y,
}
/* no clip (yet) */
-void UI_view2d_text_cache_add_rectf(View2D *v2d, const rctf *rect_view,
- const char *str, size_t str_len, const char col[4])
+void UI_view2d_text_cache_add_rectf(
+ View2D *v2d, const rctf *rect_view,
+ const char *str, size_t str_len, const char col[4])
{
rcti rect;
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 88140d897ae..6fbe8509188 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -63,12 +63,13 @@ static int view2d_poll(bContext *C)
/* ********************************************************* */
/* VIEW PANNING OPERATOR */
-/* This group of operators come in several forms:
- * 1) Modal 'dragging' with MMB - where movement of mouse dictates amount to pan view by
- * 2) Scrollwheel 'steps' - rolling mousewheel by one step moves view by predefined amount
+/**
+ * This group of operators come in several forms:
+ * -# Modal 'dragging' with MMB - where movement of mouse dictates amount to pan view by
+ * -# Scrollwheel 'steps' - rolling mousewheel by one step moves view by predefined amount
*
- * In order to make sure this works, each operator must define the following RNA-Operator Props:
- * deltax, deltay - define how much to move view by (relative to zoom-correction factor)
+ * In order to make sure this works, each operator must define the following RNA-Operator Props:
+ * - `deltax, deltay` - define how much to move view by (relative to zoom-correction factor)
*/
/* ------------------ Shared 'core' stuff ---------------------- */
@@ -328,7 +329,7 @@ static void VIEW2D_OT_pan(wmOperatorType *ot)
ot->cancel = view_pan_cancel;
/* operator is modal */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
/* rna - must keep these in sync with the other operators */
RNA_def_int(ot->srna, "deltax", 0, INT_MIN, INT_MAX, "Delta X", "", INT_MIN, INT_MAX);
@@ -525,15 +526,18 @@ static void VIEW2D_OT_scroll_up(wmOperatorType *ot)
/* ********************************************************* */
/* SINGLE-STEP VIEW ZOOMING OPERATOR */
-/* This group of operators come in several forms:
- * 1) Scrollwheel 'steps' - rolling mousewheel by one step zooms view by predefined amount
- * 2) Scrollwheel 'steps' + alt + ctrl/shift - zooms view on one axis only (ctrl=x, shift=y) // XXX this could be implemented...
- * 3) Pad +/- Keys - pressing each key moves the zooms the view by a predefined amount
+/**
+ * This group of operators come in several forms:
+ * -# Scrollwheel 'steps' - rolling mousewheel by one step zooms view by predefined amount.
+ * -# Scrollwheel 'steps' + alt + ctrl/shift - zooms view on one axis only (ctrl=x, shift=y).
+ * XXX this could be implemented...
+ * -# Pad +/- Keys - pressing each key moves the zooms the view by a predefined amount.
*
* In order to make sure this works, each operator must define the following RNA-Operator Props:
- * zoomfacx, zoomfacy - These two zoom factors allow for non-uniform scaling.
- * It is safe to scale by 0, as these factors are used to determine
- * amount to enlarge 'cur' by
+ *
+ * - zoomfacx, zoomfacy - These two zoom factors allow for non-uniform scaling.
+ * It is safe to scale by 0, as these factors are used to determine.
+ * amount to enlarge 'cur' by.
*/
/* ------------------ 'Shared' stuff ------------------------ */
@@ -620,8 +624,9 @@ static int view_zoom_poll(bContext *C)
}
/* apply transform to view (i.e. adjust 'cur' rect) */
-static void view_zoomstep_apply_ex(bContext *C, v2dViewZoomData *vzd, const bool use_mousepos,
- const float facx, const float facy)
+static void view_zoomstep_apply_ex(
+ bContext *C, v2dViewZoomData *vzd, const bool use_mousepos,
+ const float facx, const float facy)
{
ARegion *ar = CTX_wm_region(C);
View2D *v2d = &ar->v2d;
@@ -661,7 +666,9 @@ static void view_zoomstep_apply_ex(bContext *C, v2dViewZoomData *vzd, const bool
const float zoomx = (float)(BLI_rcti_size_x(&v2d->mask) + 1) / BLI_rctf_size_x(&v2d->cur);
/* only move view to mouse if zoom fac is inside minzoom/maxzoom */
- if (IN_RANGE_INCL(zoomx, v2d->minzoom, v2d->maxzoom)) {
+ if (((v2d->keepzoom & V2D_LIMITZOOM) == 0) ||
+ IN_RANGE_INCL(zoomx, v2d->minzoom, v2d->maxzoom))
+ {
float mval_fac = (vzd->mx_2d - cur_old.xmin) / BLI_rctf_size_x(&cur_old);
float mval_faci = 1.0f - mval_fac;
float ofs = (mval_fac * dx) - (mval_faci * dx);
@@ -692,7 +699,9 @@ static void view_zoomstep_apply_ex(bContext *C, v2dViewZoomData *vzd, const bool
const float zoomy = (float)(BLI_rcti_size_y(&v2d->mask) + 1) / BLI_rctf_size_y(&v2d->cur);
/* only move view to mouse if zoom fac is inside minzoom/maxzoom */
- if (IN_RANGE_INCL(zoomy, v2d->minzoom, v2d->maxzoom)) {
+ if (((v2d->keepzoom & V2D_LIMITZOOM) == 0) ||
+ IN_RANGE_INCL(zoomy, v2d->minzoom, v2d->maxzoom))
+ {
float mval_fac = (vzd->my_2d - cur_old.ymin) / BLI_rctf_size_y(&cur_old);
float mval_faci = 1.0f - mval_fac;
float ofs = (mval_fac * dy) - (mval_faci * dy);
@@ -867,10 +876,11 @@ static void VIEW2D_OT_zoom_out(wmOperatorType *ot)
/* ********************************************************* */
/* DRAG-ZOOM OPERATOR */
-/* MMB Drag - allows non-uniform scaling by dragging mouse
+/**
+ * MMB Drag - allows non-uniform scaling by dragging mouse
*
- * In order to make sure this works, each operator must define the following RNA-Operator Props:
- * deltax, deltay - amounts to add to each side of the 'cur' rect
+ * In order to make sure this works, each operator must define the following RNA-Operator Props:
+ * - `deltax, deltay` - amounts to add to each side of the 'cur' rect
*/
/* apply transform to view (i.e. adjust 'cur' rect) */
@@ -1175,7 +1185,7 @@ static void VIEW2D_OT_zoom(wmOperatorType *ot)
ot->poll = view_zoom_poll;
/* operator is repeatable */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
/* rna - must keep these in sync with the other operators */
prop = RNA_def_float(ot->srna, "deltax", 0, -FLT_MAX, FLT_MAX, "Delta X", "", -FLT_MAX, FLT_MAX);
@@ -1187,10 +1197,12 @@ static void VIEW2D_OT_zoom(wmOperatorType *ot)
/* ********************************************************* */
/* BORDER-ZOOM */
-/* The user defines a rect using standard borderselect tools, and we use this rect to
+/**
+ * The user defines a rect using standard borderselect tools, and we use this rect to
* define the new zoom-level of the view in the following ways:
- * 1) LEFTMOUSE - zoom in to view
- * 2) RIGHTMOUSE - zoom out of view
+ *
+ * -# LEFTMOUSE - zoom in to view
+ * -# RIGHTMOUSE - zoom out of view
*
* Currently, these key mappings are hardcoded, but it shouldn't be too important to
* have custom keymappings for this...
@@ -1402,8 +1414,9 @@ static float smooth_view_rect_to_fac(const rctf *rect_a, const rctf *rect_b)
/* will start timer if appropriate */
/* the arguments are the desired situation */
-void UI_view2d_smooth_view(bContext *C, ARegion *ar,
- const rctf *cur, const int smooth_viewtx)
+void UI_view2d_smooth_view(
+ bContext *C, ARegion *ar,
+ const rctf *cur, const int smooth_viewtx)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
@@ -1528,13 +1541,14 @@ static void VIEW2D_OT_smoothview(wmOperatorType *ot)
/* ********************************************************* */
/* SCROLLERS */
-/* Scrollers should behave in the following ways, when clicked on with LMB (and dragged):
- * 1) 'Handles' on end of 'bubble' - when the axis that the scroller represents is zoomable,
- * enlarge 'cur' rect on the relevant side
- * 2) 'Bubble'/'bar' - just drag, and bar should move with mouse (view pans opposite)
+/**
+ * Scrollers should behave in the following ways, when clicked on with LMB (and dragged):
+ * -# 'Handles' on end of 'bubble' - when the axis that the scroller represents is zoomable,
+ * enlarge 'cur' rect on the relevant side.
+ * -# 'Bubble'/'bar' - just drag, and bar should move with mouse (view pans opposite).
*
- * In order to make sure this works, each operator must define the following RNA-Operator Props:
- * deltax, deltay - define how much to move view by (relative to zoom-correction factor)
+ * In order to make sure this works, each operator must define the following RNA-Operator Props:
+ * - `deltax, deltay` - define how much to move view by (relative to zoom-correction factor)
*/
/* customdata for scroller-invoke data */
@@ -1556,10 +1570,12 @@ typedef struct v2dScrollerMove {
} v2dScrollerMove;
-/* View2DScrollers is typedef'd in UI_view2d.h
+/**
+ * #View2DScrollers is typedef'd in UI_view2d.h
* This is a CUT DOWN VERSION of the 'real' version, which is defined in view2d.c, as we only need focus bubble info
- * WARNING: the start of this struct must not change, so that it stays in sync with the 'real' version
- * For now, we don't need to have a separate (internal) header for structs like this...
+ *
+ * \warning: The start of this struct must not change, so that it stays in sync with the 'real' version
+ * For now, we don't need to have a separate (internal) header for structs like this...
*/
struct View2DScrollers {
/* focus bubbles */
@@ -1578,10 +1594,12 @@ enum {
/* ------------------------ */
-/* check if mouse is within scroller handle
- * - mouse = relevant mouse coordinate in region space
- * - sc_min, sc_max = extents of scroller 'groove' (potential available space for scroller)
- * - sh_min, sh_max = positions of scrollbar handles
+/**
+ * Check if mouse is within scroller handle.
+ *
+ * \param mouse: relevant mouse coordinate in region space.
+ * \param sc_min, sc_max: extents of scroller 'groove' (potential available space for scroller).
+ * \param sh_min, sh_max: positions of scrollbar handles.
*/
static short mouse_in_scroller_handle(int mouse, int sc_min, int sc_max, int sh_min, int sh_max)
{
@@ -1785,7 +1803,10 @@ static void scroller_activate_apply(bContext *C, wmOperator *op)
UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
}
-/* handle user input for scrollers - calculations of mouse-movement need to be done here, not in the apply callback! */
+/**
+ * Handle user input for scrollers - calculations of mouse-movement need to be done here,
+ * not in the apply callback!
+ */
static int scroller_activate_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dScrollerMove *vsm = op->customdata;