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/CMakeLists.txt1
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c1
-rw-r--r--source/blender/editors/interface/interface_eyedropper_gpencil_color.c324
-rw-r--r--source/blender/editors/interface/interface_intern.h3
-rw-r--r--source/blender/editors/interface/interface_layout.c30
-rw-r--r--source/blender/editors/interface/interface_ops.c1
-rw-r--r--source/blender/editors/interface/interface_templates.c36
-rw-r--r--source/blender/editors/interface/interface_widgets.c33
8 files changed, 409 insertions, 20 deletions
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index bc8d25e8d9e..d33023c69a1 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -50,6 +50,7 @@ set(SRC
interface_eyedropper_datablock.c
interface_eyedropper_depth.c
interface_eyedropper_driver.c
+ interface_eyedropper_gpencil_color.c
interface_handlers.c
interface_icons.c
interface_icons_event.c
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index 3c26c37b610..988dea270f5 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -69,6 +69,7 @@ wmKeyMap *eyedropper_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_id");
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_depth");
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_driver");
+ WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_gpencil_color");
return keymap;
}
diff --git a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c
new file mode 100644
index 00000000000..02d4596e93c
--- /dev/null
+++ b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c
@@ -0,0 +1,324 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edinterface
+ *
+ * Eyedropper (RGB Color)
+ *
+ * Defines:
+ * - #UI_OT_eyedropper_gpencil_color
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_string.h"
+
+#include "BLT_translation.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_context.h"
+#include "BKE_gpencil.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
+#include "BKE_report.h"
+
+#include "UI_interface.h"
+
+#include "IMB_colormanagement.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "ED_gpencil.h"
+#include "ED_screen.h"
+#include "ED_undo.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+
+#include "interface_intern.h"
+#include "interface_eyedropper_intern.h"
+
+typedef struct EyedropperGPencil {
+ struct ColorManagedDisplay *display;
+ /** color under cursor RGB */
+ float color[3];
+} EyedropperGPencil;
+
+/* Helper: Draw status message while the user is running the operator */
+static void eyedropper_gpencil_status_indicators(bContext *C)
+{
+ char msg_str[UI_MAX_DRAW_STR];
+ BLI_strncpy(
+ msg_str, TIP_("LMB: Stroke - Shift: Fill - Shift+Ctrl: Stroke + Fill"), UI_MAX_DRAW_STR);
+
+ ED_workspace_status_text(C, msg_str);
+}
+
+/* Initialize. */
+static bool eyedropper_gpencil_init(bContext *C, wmOperator *op)
+{
+ EyedropperGPencil *eye = MEM_callocN(sizeof(EyedropperGPencil), __func__);
+
+ op->customdata = eye;
+ Scene *scene = CTX_data_scene(C);
+
+ const char *display_device;
+ display_device = scene->display_settings.display_device;
+ eye->display = IMB_colormanagement_display_get_named(display_device);
+
+ return true;
+}
+
+/* Exit and free memory. */
+static void eyedropper_gpencil_exit(bContext *C, wmOperator *op)
+{
+ /* Clear status message area. */
+ ED_workspace_status_text(C, NULL);
+
+ MEM_SAFE_FREE(op->customdata);
+}
+
+/* Set the material. */
+static void eyedropper_gpencil_color_set(bContext *C, const wmEvent *event, EyedropperGPencil *eye)
+{
+ Main *bmain = CTX_data_main(C);
+ Object *ob = CTX_data_active_object(C);
+ Material *ma = NULL;
+
+ const bool only_stroke = ((!event->ctrl) && (!event->shift));
+ const bool only_fill = ((!event->ctrl) && (event->shift));
+ const bool both = ((event->ctrl) && (event->shift));
+
+ float col_conv[4];
+ bool found = false;
+
+ /* Convert from linear rgb space to display space because grease pencil colors are in display
+ * space, and this conversion is needed to undo the conversion to linear performed by
+ * eyedropper_color_sample_fl. */
+ if (eye->display) {
+ copy_v3_v3(col_conv, eye->color);
+ IMB_colormanagement_scene_linear_to_display_v3(col_conv, eye->display);
+ }
+ else {
+ copy_v3_v3(col_conv, eye->color);
+ }
+
+ /* Look for a similar material in grease pencil slots. */
+ short *totcol = give_totcolp(ob);
+ for (short i = 0; i < *totcol; i++) {
+ ma = give_current_material(ob, i + 1);
+ if (ma == NULL) {
+ continue;
+ }
+
+ MaterialGPencilStyle *gp_style = ma->gp_style;
+ if (gp_style != NULL) {
+ /* Check stroke color. */
+ bool found_stroke = compare_v3v3(gp_style->stroke_rgba, col_conv, 0.01f) &&
+ (gp_style->flag & GP_STYLE_STROKE_SHOW);
+ /* Check fill color. */
+ bool found_fill = compare_v3v3(gp_style->fill_rgba, col_conv, 0.01f) &&
+ (gp_style->flag & GP_STYLE_FILL_SHOW);
+
+ if ((only_stroke) && (found_stroke) && ((gp_style->flag & GP_STYLE_FILL_SHOW) == 0)) {
+ found = true;
+ }
+ else if ((only_fill) && (found_fill) && ((gp_style->flag & GP_STYLE_STROKE_SHOW) == 0)) {
+ found = true;
+ }
+ else if ((both) && (found_stroke) && (found_fill)) {
+ found = true;
+ }
+
+ /* Found existing material. */
+ if (found) {
+ ob->actcol = i + 1;
+ WM_main_add_notifier(NC_MATERIAL | ND_SHADING_LINKS, NULL);
+ WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ return;
+ }
+ }
+ }
+
+ /* If material was not found add a new material with stroke and/or fill color
+ * depending of the secondary key (LMB: Stroke, Shift: Fill, Shift+Ctrl: Stroke/Fill)
+ */
+ int idx;
+ Material *ma_new = BKE_gpencil_object_material_new(bmain, ob, "Material", &idx);
+ WM_main_add_notifier(NC_OBJECT | ND_OB_SHADING, &ob->id);
+ WM_main_add_notifier(NC_MATERIAL | ND_SHADING_LINKS, NULL);
+ DEG_relations_tag_update(bmain);
+
+ BLI_assert(ma_new != NULL);
+
+ MaterialGPencilStyle *gp_style_new = ma_new->gp_style;
+ BLI_assert(gp_style_new != NULL);
+
+ /* Only create Stroke (default option). */
+ if (only_stroke) {
+ /* Stroke color. */
+ gp_style_new->flag |= GP_STYLE_STROKE_SHOW;
+ gp_style_new->flag &= ~GP_STYLE_FILL_SHOW;
+ copy_v3_v3(gp_style_new->stroke_rgba, col_conv);
+ zero_v4(gp_style_new->fill_rgba);
+ }
+ /* Fill Only. */
+ else if (only_fill) {
+ /* Fill color. */
+ gp_style_new->flag &= ~GP_STYLE_STROKE_SHOW;
+ gp_style_new->flag |= GP_STYLE_FILL_SHOW;
+ zero_v4(gp_style_new->stroke_rgba);
+ copy_v3_v3(gp_style_new->fill_rgba, col_conv);
+ }
+ /* Stroke and Fill. */
+ else if (both) {
+ gp_style_new->flag |= GP_STYLE_STROKE_SHOW | GP_STYLE_FILL_SHOW;
+ copy_v3_v3(gp_style_new->stroke_rgba, col_conv);
+ copy_v3_v3(gp_style_new->fill_rgba, col_conv);
+ }
+ /* Push undo for new created material. */
+ ED_undo_push(C, "Add Grease Pencil Material");
+}
+
+/* Sample the color below cursor. */
+static void eyedropper_gpencil_color_sample(bContext *C, EyedropperGPencil *eye, int mx, int my)
+{
+ eyedropper_color_sample_fl(C, mx, my, eye->color);
+}
+
+/* Cancel operator. */
+static void eyedropper_gpencil_cancel(bContext *C, wmOperator *op)
+{
+ eyedropper_gpencil_exit(C, op);
+}
+
+/* Main modal status check. */
+static int eyedropper_gpencil_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ EyedropperGPencil *eye = (EyedropperGPencil *)op->customdata;
+ /* Handle modal keymap */
+ switch (event->type) {
+ case EVT_MODAL_MAP: {
+ switch (event->val) {
+ case EYE_MODAL_SAMPLE_BEGIN: {
+ return OPERATOR_RUNNING_MODAL;
+ }
+ case EYE_MODAL_CANCEL: {
+ eyedropper_gpencil_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ case EYE_MODAL_SAMPLE_CONFIRM: {
+ eyedropper_gpencil_color_sample(C, eye, event->x, event->y);
+
+ /* Create material. */
+ eyedropper_gpencil_color_set(C, event, eye);
+ WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ eyedropper_gpencil_exit(C, op);
+ return OPERATOR_FINISHED;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ break;
+ }
+ case MOUSEMOVE:
+ case INBETWEEN_MOUSEMOVE: {
+ eyedropper_gpencil_color_sample(C, eye, event->x, event->y);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* Modal Operator init */
+static int eyedropper_gpencil_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ /* Init. */
+ if (eyedropper_gpencil_init(C, op)) {
+ /* Add modal temp handler. */
+ WM_event_add_modal_handler(C, op);
+ /* Status message. */
+ eyedropper_gpencil_status_indicators(C);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ return OPERATOR_PASS_THROUGH;
+ }
+}
+
+/* Repeat operator */
+static int eyedropper_gpencil_exec(bContext *C, wmOperator *op)
+{
+ /* init */
+ if (eyedropper_gpencil_init(C, op)) {
+
+ /* cleanup */
+ eyedropper_gpencil_exit(C, op);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_PASS_THROUGH;
+ }
+}
+
+static bool eyedropper_gpencil_poll(bContext *C)
+{
+ /* Only valid if the current active object is grease pencil. */
+ Object *obact = CTX_data_active_object(C);
+ if ((obact == NULL) || (obact->type != OB_GPENCIL)) {
+ return false;
+ }
+
+ /* Test we have a window below. */
+ return (CTX_wm_window(C) != NULL);
+}
+
+void UI_OT_eyedropper_gpencil_color(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Grease Pencil Eyedropper";
+ ot->idname = "UI_OT_eyedropper_gpencil_color";
+ ot->description = "Sample a color from the Blender Window and create Grease Pencil material";
+
+ /* api callbacks */
+ ot->invoke = eyedropper_gpencil_invoke;
+ ot->modal = eyedropper_gpencil_modal;
+ ot->cancel = eyedropper_gpencil_cancel;
+ ot->exec = eyedropper_gpencil_exec;
+ ot->poll = eyedropper_gpencil_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
+}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 4351b75eb86..81979b1fc8f 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -971,6 +971,9 @@ void UI_OT_eyedropper_depth(struct wmOperatorType *ot);
/* interface_eyedropper_driver.c */
void UI_OT_eyedropper_driver(struct wmOperatorType *ot);
+/* interface_eyedropper_gpencil_color.c */
+void UI_OT_eyedropper_gpencil_color(struct wmOperatorType *ot);
+
/* interface_util.c */
/**
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index a6f8ba4560d..2a4c2aba4a1 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -3650,8 +3650,13 @@ static void ui_litem_estimate_box(uiLayout *litem)
uiStyle *style = litem->root->style;
ui_litem_estimate_column(litem, true);
- litem->w += 2 * style->boxspace;
- litem->h += 2 * style->boxspace;
+
+ int boxspace = style->boxspace;
+ if (litem->root->type == UI_LAYOUT_HEADER) {
+ boxspace = 0;
+ }
+ litem->w += 2 * boxspace;
+ litem->h += 2 * boxspace;
}
static void ui_litem_layout_box(uiLayout *litem)
@@ -3661,29 +3666,34 @@ static void ui_litem_layout_box(uiLayout *litem)
uiBut *but;
int w, h;
+ int boxspace = style->boxspace;
+ if (litem->root->type == UI_LAYOUT_HEADER) {
+ boxspace = 0;
+ }
+
w = litem->w;
h = litem->h;
- litem->x += style->boxspace;
- litem->y -= style->boxspace;
+ litem->x += boxspace;
+ litem->y -= boxspace;
if (w != 0) {
- litem->w -= 2 * style->boxspace;
+ litem->w -= 2 * boxspace;
}
if (h != 0) {
- litem->h -= 2 * style->boxspace;
+ litem->h -= 2 * boxspace;
}
ui_litem_layout_column(litem, true);
- litem->x -= style->boxspace;
- litem->y -= style->boxspace;
+ litem->x -= boxspace;
+ litem->y -= boxspace;
if (w != 0) {
- litem->w += 2 * style->boxspace;
+ litem->w += 2 * boxspace;
}
if (h != 0) {
- litem->h += 2 * style->boxspace;
+ litem->h += 2 * boxspace;
}
/* roundbox around the sublayout */
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 4e56a02997b..7ce4242c697 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1751,6 +1751,7 @@ void ED_operatortypes_ui(void)
WM_operatortype_append(UI_OT_eyedropper_id);
WM_operatortype_append(UI_OT_eyedropper_depth);
WM_operatortype_append(UI_OT_eyedropper_driver);
+ WM_operatortype_append(UI_OT_eyedropper_gpencil_color);
}
/**
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index fe484676ddd..021d7733fae 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -6657,6 +6657,42 @@ void uiTemplateKeymapItemProperties(uiLayout *layout, PointerRNA *ptr)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Event Icon Template
+ *
+ * \{ */
+
+bool uiTemplateEventFromKeymapItem(struct uiLayout *layout,
+ const char *text,
+ const struct wmKeyMapItem *kmi,
+ bool text_fallback)
+{
+ bool ok = false;
+
+ int icon_mod[4];
+#ifdef WITH_HEADLESS
+ int icon = 0;
+#else
+ int icon = UI_icon_from_keymap_item(kmi, icon_mod);
+#endif
+ if (icon != 0) {
+ for (int j = 0; j < ARRAY_SIZE(icon_mod) && icon_mod[j]; j++) {
+ uiItemL(layout, "", icon_mod[j]);
+ }
+ uiItemL(layout, text, icon);
+ ok = true;
+ }
+ else if (text_fallback) {
+ const char *event_text = WM_key_event_string(kmi->type, true);
+ uiItemL(layout, event_text, ICON_NONE);
+ uiItemL(layout, text, ICON_NONE);
+ ok = true;
+ }
+ return ok;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Color Management Template
* \{ */
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index b3e039292e1..4cef9ace66e 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -184,6 +184,18 @@ static void color_ensure_contrast_v3(uchar cp[3], const uchar cp_other[3], int c
}
}
+static void color_mul_hsl_v3(uchar ch[3], float h_factor, float s_factor, float l_factor)
+{
+ float rgb[3], hsl[3];
+ rgb_uchar_to_float(rgb, ch);
+ rgb_to_hsl_v(rgb, hsl);
+ hsl[0] *= h_factor;
+ hsl[1] *= s_factor;
+ hsl[2] *= l_factor;
+ hsl_to_rgb_v(hsl, rgb);
+ rgb_float_to_uchar(ch, rgb);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -2573,11 +2585,12 @@ static void ui_widget_color_disabled(uiWidgetType *wt)
wt->wcol_theme = &wcol_theme_s;
}
-static void widget_active_color(uchar cp[3])
+static void widget_active_color(uiWidgetColors *wcol)
{
- cp[0] = cp[0] >= 240 ? 255 : cp[0] + 15;
- cp[1] = cp[1] >= 240 ? 255 : cp[1] + 15;
- cp[2] = cp[2] >= 240 ? 255 : cp[2] + 15;
+ bool dark = (rgb_to_grayscale_byte(wcol->text) > rgb_to_grayscale_byte(wcol->inner));
+ color_mul_hsl_v3(wcol->inner, 1.0f, 1.15f, dark ? 1.2f : 1.1f);
+ color_mul_hsl_v3(wcol->outline, 1.0f, 1.15f, 1.15f);
+ color_mul_hsl_v3(wcol->text, 1.0f, 1.15f, dark ? 1.25f : 0.8f);
}
static const uchar *widget_color_blend_from_flags(const uiWidgetStateColors *wcol_state,
@@ -2641,10 +2654,10 @@ static void widget_state(uiWidgetType *wt, int state, int drawflag)
if (color_blend != NULL) {
color_blend_v3_v3(wt->wcol.inner, color_blend, wcol_state->blend);
}
+ }
- if (state & UI_ACTIVE) { /* mouse over? */
- widget_active_color(wt->wcol.inner);
- }
+ if (state & UI_ACTIVE) {
+ widget_active_color(&wt->wcol);
}
if (state & UI_BUT_REDALERT) {
@@ -3403,7 +3416,7 @@ static void widget_numbut_draw(
wcol_zone = *wcol;
copy_v3_v3_uchar(wcol_zone.item, wcol->text);
if (state & UI_STATE_ACTIVE_LEFT) {
- widget_active_color(wcol_zone.inner);
+ widget_active_color(&wcol_zone);
}
rect_zone = *rect;
@@ -3423,7 +3436,7 @@ static void widget_numbut_draw(
wcol_zone = *wcol;
copy_v3_v3_uchar(wcol_zone.item, wcol->text);
if (state & UI_STATE_ACTIVE_RIGHT) {
- widget_active_color(wcol_zone.inner);
+ widget_active_color(&wcol_zone);
}
rect_zone = *rect;
@@ -3442,7 +3455,7 @@ static void widget_numbut_draw(
wcol_zone = *wcol;
copy_v3_v3_uchar(wcol_zone.item, wcol->text);
if (!(state & (UI_STATE_ACTIVE_LEFT | UI_STATE_ACTIVE_RIGHT))) {
- widget_active_color(wcol_zone.inner);
+ widget_active_color(&wcol_zone);
}
rect_zone = *rect;