Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/paint_ops.c
| Context not available. | |||||
| #include "BLI_string.h" | #include "BLI_string.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BLI_math_vector.h" | #include "BLI_math_vector.h" | ||||
| #include "BLI_math_color.h" | |||||
| #include "DNA_customdata_types.h" | #include "DNA_customdata_types.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_brush_types.h" | #include "DNA_brush_types.h" | ||||
| #include "DNA_gpencil_types.h" | |||||
| #include "BKE_brush.h" | #include "BKE_brush.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_paint.h" | #include "BKE_paint.h" | ||||
| #include "BKE_gpencil.h" | |||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_report.h" | |||||
| #include "DEG_depsgraph.h" | |||||
| #include "ED_paint.h" | #include "ED_paint.h" | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "ED_image.h" | #include "ED_image.h" | ||||
| #include "ED_gpencil.h" | |||||
| #include "UI_resources.h" | #include "UI_resources.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| Context not available. | |||||
| //#include <stdio.h> | //#include <stdio.h> | ||||
| #include <stddef.h> | #include <stddef.h> | ||||
| /* poll functions */ | |||||
| /* poll callback for checking if there is an active layer */ | |||||
| static int gp_active_layer_poll(bContext *C) | |||||
| { | |||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); | |||||
| return (gpl != NULL); | |||||
| } | |||||
| /* poll callback for checking if there is an active palette */ | |||||
| static int palette_active_poll(bContext *C) | |||||
| { | |||||
| Palette *palette = BKE_palette_get_active_from_context(C); | |||||
| return (palette != NULL); | |||||
| } | |||||
| /* poll callback for checking if there is an active palette color */ | |||||
| static int palettecolor_active_poll(bContext *C) | |||||
| { | |||||
| Palette *palette = BKE_palette_get_active_from_context(C); | |||||
| PaletteColor *palcolor = BKE_palette_color_get_active(palette); | |||||
| return (palcolor != NULL); | |||||
| } | |||||
| /* Brush operators */ | /* Brush operators */ | ||||
| static int brush_add_exec(bContext *C, wmOperator *UNUSED(op)) | static int brush_add_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Context not available. | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| } | } | ||||
| static int brush_add_gpencil_exec(bContext *C, wmOperator *UNUSED(op)) | |||||
| { | |||||
| /*int type = RNA_enum_get(op->ptr, "type");*/ | |||||
| ToolSettings *ts = CTX_data_tool_settings(C); | |||||
| Paint *paint = &ts->gp_paint->paint; | |||||
| Brush *br = BKE_paint_brush(paint); | |||||
| Main *bmain = CTX_data_main(C); | |||||
| // ePaintMode mode = ePaintGpencil; | |||||
| if (br) { | |||||
| br = BKE_brush_copy(bmain, br); | |||||
| } | |||||
| else { | |||||
| br = BKE_brush_add(bmain, "Brush", OB_MODE_GPENCIL_PAINT); | |||||
| id_us_min(&br->id); /* fake user only */ | |||||
| } | |||||
| BKE_paint_brush_set(paint, br); | |||||
| /* TODO init grease pencil specific data */ | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static void BRUSH_OT_add_gpencil(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Add Drawing Brush"; | |||||
| ot->description = "Add brush for grease pencil"; | |||||
| ot->idname = "BRUSH_OT_add_gpencil"; | |||||
| /* api callbacks */ | |||||
| ot->exec = brush_add_gpencil_exec; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| } | |||||
| static int brush_scale_size_exec(bContext *C, wmOperator *op) | static int brush_scale_size_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Context not available. | |||||
| static int palette_poll(bContext *C) | static int palette_poll(bContext *C) | ||||
| { | { | ||||
| Paint *paint = BKE_paint_get_active_from_context(C); | Palette *palette = BKE_palette_get_active_from_context(C); | ||||
| return (palette != NULL); | |||||
| } | |||||
| static int palette_new_gpencil_exec(bContext *C, wmOperator *UNUSED(op)) | |||||
| { | |||||
| bGPdata *gpd = CTX_data_gpencil_data(C); | |||||
| Main *bmain = CTX_data_main(C); | |||||
| /* add new palette for use with active paletteslot */ | |||||
| bGPDpaletteref *palslot = BKE_gpencil_paletteslot_get_active(gpd); | |||||
| if (palslot && palslot->palette) { | |||||
| /* Replace the existing palette with a copy of the original datablock | |||||
| * (as done in the rest of Blender) | |||||
| */ | |||||
| Palette *palette = BKE_palette_copy(bmain, palslot->palette); | |||||
| BKE_gpencil_paletteslot_set_palette(gpd, palslot, palette); | |||||
| } | |||||
| else { | |||||
| /* Just create everything that doesn't exist already */ | |||||
| palslot = BKE_gpencil_paletteslot_validate(bmain, gpd); | |||||
| } | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static void PALETTE_OT_new_gpencil(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Add New GPencil Palette"; | |||||
| ot->description = "Add new palette for use with Grease Pencil"; | |||||
| ot->idname = "PALETTE_OT_new_gpencil"; | |||||
| /* api callbacks */ | |||||
| ot->exec = palette_new_gpencil_exec; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| } | |||||
| /* ******************* Lock and hide any color non used in current layer ************************** */ | |||||
| static int palette_lock_layer_exec(bContext *C, wmOperator *UNUSED(op)) | |||||
| { | |||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| Palette *palette; | |||||
| /* sanity checks */ | |||||
| if (ELEM(NULL, gpd)) | |||||
| return OPERATOR_CANCELLED; | |||||
| palette = BKE_palette_get_active_from_context(C); | |||||
| if (ELEM(NULL, palette)) | |||||
| return OPERATOR_CANCELLED; | |||||
| /* first lock and hide all colors */ | |||||
| for (PaletteColor *palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { | |||||
| palcolor->flag |= PC_COLOR_LOCKED; | |||||
| palcolor->flag |= PC_COLOR_HIDE; | |||||
| } | |||||
| /* loop all selected strokes and unlock any color used in active layer */ | |||||
| for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { | |||||
| /* only editable and visible layers are considered */ | |||||
| if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL) && (gpl->flag & GP_LAYER_ACTIVE)) { | |||||
| for (bGPDstroke *gps = gpl->actframe->strokes.last; gps; gps = gps->prev) { | |||||
| /* skip strokes that are invalid for current view */ | |||||
| if (ED_gpencil_stroke_can_use(C, gps) == false) | |||||
| continue; | |||||
| /* unlock/unhide color if not unlocked before */ | |||||
| if (gps->palcolor != NULL) { | |||||
| gps->palcolor->flag &= ~PC_COLOR_LOCKED; | |||||
| gps->palcolor->flag &= ~PC_COLOR_HIDE; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /* notifiers */ | |||||
| BKE_gpencil_batch_cache_dirty(gpd); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| if (paint && paint->palette != NULL) | static void PALETTE_OT_lock_layer(wmOperatorType *ot) | ||||
| return true; | { | ||||
| /* identifiers */ | |||||
| ot->name = "Disable Unused Layer Colors"; | |||||
| ot->idname = "PALETTE_OT_lock_layer"; | |||||
| ot->description = "Lock and hide any color not used in any layer"; | |||||
| return false; | /* api callbacks */ | ||||
| ot->exec = palette_lock_layer_exec; | |||||
| ot->poll = gp_active_layer_poll; | |||||
| } | } | ||||
| static int palette_color_add_exec(bContext *C, wmOperator *UNUSED(op)) | static int palette_color_add_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| Palette *palette = BKE_palette_get_active_from_context(C); | |||||
| Paint *paint = BKE_paint_get_active_from_context(C); | Paint *paint = BKE_paint_get_active_from_context(C); | ||||
| Brush *brush = paint->brush; | |||||
| ePaintMode mode = BKE_paintmode_get_active_from_context(C); | |||||
| Palette *palette = paint->palette; | |||||
| PaletteColor *color; | PaletteColor *color; | ||||
| /* Add a new color and make it active */ | |||||
| color = BKE_palette_color_add(palette); | color = BKE_palette_color_add(palette); | ||||
| palette->active_color = BLI_listbase_count(&palette->colors) - 1; | palette->active_color = BLI_listbase_count(&palette->colors) - 1; | ||||
| if (ELEM(mode, ePaintTextureProjective, ePaintTexture2D, ePaintVertex)) { | /* For Grease Pencil, the active palette won't be the one the current | ||||
| copy_v3_v3(color->rgb, BKE_brush_color_get(scene, brush)); | * Paint context stores (as it comes from the active Palette Slot on the | ||||
| color->value = 0.0; | * current GP Object instead) | ||||
| } | */ | ||||
| else if (mode == ePaintWeight) { | if (palette != paint->palette) { | ||||
| zero_v3(color->rgb); | ePaintMode mode = BKE_paintmode_get_active_from_context(C); | ||||
| color->value = brush->weight; | Brush *brush = paint->brush; | ||||
| if (ELEM(mode, ePaintTextureProjective, ePaintTexture2D, ePaintVertex)) { | |||||
| copy_v3_v3(color->rgb, BKE_brush_color_get(scene, brush)); | |||||
| color->value = 0.0; | |||||
| } | |||||
| else if (mode == ePaintWeight) { | |||||
| zero_v3(color->rgb); | |||||
| color->value = brush->weight; | |||||
| } | |||||
| } | } | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| Context not available. | |||||
| /* api callbacks */ | /* api callbacks */ | ||||
| ot->exec = palette_color_add_exec; | ot->exec = palette_color_add_exec; | ||||
| ot->poll = palette_poll; | ot->poll = palette_poll; | ||||
| /* flags */ | /* flags */ | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| } | } | ||||
| Context not available. | |||||
| static int palette_color_delete_exec(bContext *C, wmOperator *UNUSED(op)) | static int palette_color_delete_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Paint *paint = BKE_paint_get_active_from_context(C); | Main *bmain = CTX_data_main(C); | ||||
| Palette *palette = paint->palette; | Palette *palette = BKE_palette_get_active_from_context(C); | ||||
| PaletteColor *color = BLI_findlink(&palette->colors, palette->active_color); | PaletteColor *color = BLI_findlink(&palette->colors, palette->active_color); | ||||
| if (color) { | if (color) { | ||||
| /* delete any gp strokes using this color */ | |||||
| BKE_gpencil_palettecolor_delete_allstrokes(bmain, color); | |||||
| /* delete the active color */ | |||||
| BKE_palette_color_remove(palette, color); | BKE_palette_color_remove(palette, color); | ||||
| } | } | ||||
| /* notifiers */ | |||||
| WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); | |||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| Context not available. | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| } | } | ||||
| /* ********************** Isolate palette color **************************** */ | |||||
| static int palettecolor_isolate_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| Palette *palette = BKE_palette_get_active_from_context(C); | |||||
| PaletteColor *active_color = BKE_palette_color_get_active(palette); | |||||
| PaletteColor *palcolor; | |||||
| int flags = PC_COLOR_LOCKED; | |||||
| bool isolate = false; | |||||
| if (RNA_boolean_get(op->ptr, "affect_visibility")) | |||||
| flags |= PC_COLOR_HIDE; | |||||
| if (ELEM(NULL, gpd, active_color)) { | |||||
| BKE_report(op->reports, RPT_ERROR, "No active color to isolate"); | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| /* Test whether to isolate or clear all flags */ | |||||
| for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { | |||||
| /* Skip if this is the active one */ | |||||
| if (palcolor == active_color) | |||||
| continue; | |||||
| /* If the flags aren't set, that means that the color is | |||||
| * not alone, so we have some colors to isolate still | |||||
| */ | |||||
| if ((palcolor->flag & flags) == 0) { | |||||
| isolate = true; | |||||
| break; | |||||
| } | |||||
| } | |||||
| /* Set/Clear flags as appropriate */ | |||||
| if (isolate) { | |||||
| /* Set flags on all "other" colors */ | |||||
| for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { | |||||
| if (palcolor == active_color) | |||||
| continue; | |||||
| else | |||||
| palcolor->flag |= flags; | |||||
| } | |||||
| } | |||||
| else { | |||||
| /* Clear flags - Restore everything else */ | |||||
| for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { | |||||
| palcolor->flag &= ~flags; | |||||
| } | |||||
| } | |||||
| /* notifiers */ | |||||
| DEG_id_tag_update(&palette->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static void PALETTE_OT_palettecolor_isolate(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Isolate Palette Color"; | |||||
| ot->idname = "PALETTE_OT_palettecolor_isolate"; | |||||
| ot->description = "Toggle whether the active color is the only one that is editable and/or visible"; | |||||
| /* callbacks */ | |||||
| ot->exec = palettecolor_isolate_exec; | |||||
| ot->poll = palettecolor_active_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| /* properties */ | |||||
| RNA_def_boolean(ot->srna, "affect_visibility", false, "Affect Visibility", "In addition to toggling " | |||||
| "the editability, also affect the visibility"); | |||||
| } | |||||
| /* *********************** Hide Palette colors ******************************** */ | |||||
| static int palettecolor_hide_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Palette *palette = BKE_palette_get_active_from_context(C); | |||||
| PaletteColor *palcolor = BKE_palette_color_get_active(palette); | |||||
| bool unselected = RNA_boolean_get(op->ptr, "unselected"); | |||||
| /* sanity checks */ | |||||
| if (ELEM(NULL, palette, palcolor)) | |||||
| return OPERATOR_CANCELLED; | |||||
| if (unselected) { | |||||
| PaletteColor *color; | |||||
| /* hide unselected */ | |||||
| for (color = palette->colors.first; color; color = color->next) { | |||||
| if (color != palcolor) { | |||||
| color->flag |= PC_COLOR_HIDE; | |||||
| } | |||||
| } | |||||
| } | |||||
| else { | |||||
| /* hide selected/active */ | |||||
| palcolor->flag |= PC_COLOR_HIDE; | |||||
| } | |||||
| /* notifiers */ | |||||
| WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static void PALETTE_OT_palettecolor_hide(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Hide Color(s)"; | |||||
| ot->idname = "PALETTE_OT_palettecolor_hide"; | |||||
| ot->description = "Hide selected/unselected Grease Pencil colors"; | |||||
| /* callbacks */ | |||||
| ot->exec = palettecolor_hide_exec; | |||||
| ot->poll = palettecolor_active_poll; /* NOTE: we need an active color to play with */ | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| /* props */ | |||||
| RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected colors"); | |||||
| } | |||||
| /* ********************** Show All Colors ***************************** */ | |||||
| static int palettecolor_reveal_exec(bContext *C, wmOperator *UNUSED(op)) | |||||
| { | |||||
| Palette *palette = BKE_palette_get_active_from_context(C); | |||||
| PaletteColor *palcolor; | |||||
| /* sanity checks */ | |||||
| if (ELEM(NULL, palette)) | |||||
| return OPERATOR_CANCELLED; | |||||
| /* make all colors visible */ | |||||
| for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { | |||||
| palcolor->flag &= ~PC_COLOR_HIDE; | |||||
| } | |||||
| /* notifiers */ | |||||
| WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static void PALETTE_OT_palettecolor_reveal(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Show All Colors"; | |||||
| ot->idname = "PALETTE_OT_palettecolor_reveal"; | |||||
| ot->description = "Unhide all hidden Grease Pencil palette colors"; | |||||
| /* callbacks */ | |||||
| ot->exec = palettecolor_reveal_exec; | |||||
| ot->poll = palette_active_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| } | |||||
| /* ***************** Lock/Unlock All Palette colors ************************ */ | |||||
| static int palettecolor_lock_all_exec(bContext *C, wmOperator *UNUSED(op)) | |||||
| { | |||||
| Palette *palette = BKE_palette_get_active_from_context(C); | |||||
| PaletteColor *palcolor; | |||||
| /* sanity checks */ | |||||
| if (ELEM(NULL, palette)) | |||||
| return OPERATOR_CANCELLED; | |||||
| /* make all layers non-editable */ | |||||
| for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { | |||||
| palcolor->flag |= PC_COLOR_LOCKED; | |||||
| } | |||||
| /* notifiers */ | |||||
| WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static void PALETTE_OT_palettecolor_lock_all(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Lock All Colors"; | |||||
| ot->idname = "PALETTE_OT_palettecolor_lock_all"; | |||||
| ot->description = "Lock all Grease Pencil colors to prevent them from being accidentally modified"; | |||||
| /* callbacks */ | |||||
| ot->exec = palettecolor_lock_all_exec; | |||||
| ot->poll = palette_active_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| } | |||||
| /* -------------------------- */ | |||||
| static int palettecolor_unlock_all_exec(bContext *C, wmOperator *UNUSED(op)) | |||||
| { | |||||
| Palette *palette = BKE_palette_get_active_from_context(C); | |||||
| PaletteColor *palcolor; | |||||
| /* sanity checks */ | |||||
| if (ELEM(NULL, palette)) | |||||
| return OPERATOR_CANCELLED; | |||||
| /* make all layers editable again*/ | |||||
| for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { | |||||
| palcolor->flag &= ~PC_COLOR_LOCKED; | |||||
| } | |||||
| /* notifiers */ | |||||
| WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static void PALETTE_OT_palettecolor_unlock_all(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Unlock All Colors"; | |||||
| ot->idname = "PALETTE_OT_palettecolor_unlock_all"; | |||||
| ot->description = "Unlock all Grease Pencil colors so that they can be edited"; | |||||
| /* callbacks */ | |||||
| ot->exec = palettecolor_unlock_all_exec; | |||||
| ot->poll = palette_active_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| } | |||||
| /* ******************* Move Color Up/Down ************************** */ | |||||
| enum { | |||||
| PALETTE_COLOR_MOVE_UP = -1, | |||||
| PALETTE_COLOR_MOVE_DOWN = 1 | |||||
| }; | |||||
| static int palettecolor_move_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Palette *palette = BKE_palette_get_active_from_context(C); | |||||
| PaletteColor *palcolor = BKE_palette_color_get_active(palette); | |||||
| int direction = RNA_enum_get(op->ptr, "direction"); | |||||
| /* sanity checks */ | |||||
| if (ELEM(NULL, palette, palcolor)) | |||||
| return OPERATOR_CANCELLED; | |||||
| BLI_assert(ELEM(direction, -1, 0, 1)); /* we use value below */ | |||||
| if (BLI_listbase_link_move(&palette->colors, palcolor, direction)) { | |||||
| palette->active_color = BLI_findindex(&palette->colors, palcolor); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); | |||||
| } | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static void PALETTE_OT_palettecolor_move(wmOperatorType *ot) | |||||
| { | |||||
| static EnumPropertyItem slot_move[] = { | |||||
| { PALETTE_COLOR_MOVE_UP, "UP", 0, "Up", "" }, | |||||
| { PALETTE_COLOR_MOVE_DOWN, "DOWN", 0, "Down", "" }, | |||||
| { 0, NULL, 0, NULL, NULL } | |||||
| }; | |||||
| /* identifiers */ | |||||
| ot->name = "Move Palette color"; | |||||
| ot->idname = "PALETTE_OT_palettecolor_move"; | |||||
| ot->description = "Move the active palette color up/down in the list"; | |||||
| /* api callbacks */ | |||||
| ot->exec = palettecolor_move_exec; | |||||
| ot->poll = palette_active_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| ot->prop = RNA_def_enum(ot->srna, "direction", slot_move, PALETTE_COLOR_MOVE_UP, "Direction", ""); | |||||
| } | |||||
| /* ***************** Select all strokes using Palette color ************************ */ | |||||
| static int palettecolor_select_exec(bContext *C, wmOperator *UNUSED(op)) | |||||
| { | |||||
| bGPdata *gpd = ED_gpencil_data_get_active(C); | |||||
| Palette *palette = BKE_palette_get_active_from_context(C); | |||||
| PaletteColor *palcolor = BKE_palette_color_get_active(palette); | |||||
| /* sanity checks */ | |||||
| if (ELEM(NULL, gpd, palette, palcolor)) | |||||
| return OPERATOR_CANCELLED; | |||||
| /* read all strokes and select*/ | |||||
| for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { | |||||
| /* only editable and visible layers are considered */ | |||||
| if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) { | |||||
| /* verify something to do */ | |||||
| for (bGPDstroke *gps = gpl->actframe->strokes.first; gps; gps = gps->next) { | |||||
| /* skip strokes that are invalid for current view */ | |||||
| if (ED_gpencil_stroke_can_use(C, gps) == false) | |||||
| continue; | |||||
| /* check if the color is editable */ | |||||
| if (ED_gpencil_stroke_color_use(gpl, gps) == false) | |||||
| continue; | |||||
| /* select */ | |||||
| if (strcmp(palcolor->info, gps->colorname) == 0) { | |||||
| bGPDspoint *pt; | |||||
| int i; | |||||
| gps->flag |= GP_STROKE_SELECT; | |||||
| for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { | |||||
| pt->flag |= GP_SPOINT_SELECT; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /* notifiers */ | |||||
| WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static void PALETTE_OT_palettecolor_select(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Select Color"; | |||||
| ot->idname = "PALETTE_OT_palettecolor_select"; | |||||
| ot->description = "Select all Grease Pencil strokes using current color"; | |||||
| /* callbacks */ | |||||
| ot->exec = palettecolor_select_exec; | |||||
| ot->poll = palette_active_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| } | |||||
| /* ***************** Choose Palette color by index ************************ */ | |||||
| static int palettecolor_choose_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| const int index = RNA_int_get(op->ptr, "index"); | |||||
| Palette *palette = BKE_palette_get_active_from_context(C); | |||||
| /* sanity checks */ | |||||
| if (ELEM(NULL, palette)) | |||||
| return OPERATOR_CANCELLED; | |||||
| int totcolors = BLI_listbase_count(&palette->colors); | |||||
| if ((index >= 0) && (index < totcolors)) { | |||||
| palette->active_color = index; | |||||
| } | |||||
| /* notifiers */ | |||||
| WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static void PALETTE_OT_palettecolor_choose(wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Choose Color"; | |||||
| ot->idname = "PALETTE_OT_palettecolor_choose"; | |||||
| ot->description = "Active a palette color"; | |||||
| /* callbacks */ | |||||
| ot->exec = palettecolor_choose_exec; | |||||
| ot->poll = palette_active_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| /* properties */ | |||||
| RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of Color", 0, INT_MAX); | |||||
| } | |||||
| /* ***************** Duplicate Palette color ************************ */ | |||||
| static int palettecolor_duplicate_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Palette *palette = BKE_palette_get_active_from_context(C); | |||||
| PaletteColor *palcolor = BKE_palette_color_get_active(palette); | |||||
| PaletteColor *newcolor; | |||||
| float hsv_s[3], hsv_f[3]; | |||||
| /* attenuation factors 10%, 25%, 50%, 75% */ | |||||
| float factors[4] = { 0.9f, 0.75f, 0.5f, 0.25f }; | |||||
| int mode = RNA_enum_get(op->ptr, "type"); | |||||
| /* sanity checks */ | |||||
| if (ELEM(NULL, palette, palcolor)) | |||||
| return OPERATOR_CANCELLED; | |||||
| /* create a new color and duplicate data */ | |||||
| newcolor = BKE_palette_color_copy(palette, palcolor); | |||||
| /* attenuate color */ | |||||
| if (mode > 0) { | |||||
| rgb_to_hsv_v(newcolor->rgb, hsv_s); | |||||
| rgb_to_hsv_v(newcolor->fill, hsv_f); | |||||
| hsv_s[2] *= factors[mode - 1]; | |||||
| hsv_f[2] *= factors[mode - 1]; | |||||
| hsv_to_rgb_v(hsv_s, newcolor->rgb); | |||||
| hsv_to_rgb_v(hsv_f, newcolor->fill); | |||||
| } | |||||
| /* notifiers */ | |||||
| WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static void PALETTE_OT_palettecolor_duplicate(wmOperatorType *ot) | |||||
| { | |||||
| static EnumPropertyItem prop_palettecolor_dup_types[] = { | |||||
| { 0, "DUP", ICON_PASTEDOWN, "Duplicate Color", "Duplicate current palette color" }, | |||||
| { 1, "DUP10", ICON_PASTEDOWN, "Duplicate Attenuate 10%", "Duplicate an attenuate version of the selected color" }, | |||||
| { 2, "DUP25", ICON_PASTEDOWN, "Duplicate Attenuate 25%", "Duplicate an attenuate version of the selected color" }, | |||||
| { 3, "DUP50", ICON_PASTEDOWN, "Duplicate Attenuate 50%", "Duplicate an attenuate version of the selected color" }, | |||||
| { 4, "DUP75", ICON_PASTEDOWN, "Duplicate Attenuate 75%", "Duplicate an attenuate version of the selected color" }, | |||||
| { 0, NULL, 0, NULL, NULL } | |||||
| }; | |||||
| /* identifiers */ | |||||
| ot->name = "Duplicate Color"; | |||||
| ot->idname = "PALETTE_OT_palettecolor_duplicate"; | |||||
| ot->description = "Duplicate current palette color"; | |||||
| /* callbacks */ | |||||
| ot->exec = palettecolor_duplicate_exec; | |||||
| ot->poll = palettecolor_active_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| /* props */ | |||||
| ot->prop = RNA_def_enum(ot->srna, "type", prop_palettecolor_dup_types, 0, "Type", "Method used for duplicating colors"); | |||||
| } | |||||
| static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op)) | static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Paint *paint = BKE_paint_get_active_from_context(C); | Paint *paint = BKE_paint_get_active_from_context(C); | ||||
| Context not available. | |||||
| { | { | ||||
| /* palette */ | /* palette */ | ||||
| WM_operatortype_append(PALETTE_OT_new); | WM_operatortype_append(PALETTE_OT_new); | ||||
| WM_operatortype_append(PALETTE_OT_new_gpencil); | |||||
| WM_operatortype_append(PALETTE_OT_color_add); | WM_operatortype_append(PALETTE_OT_color_add); | ||||
| WM_operatortype_append(PALETTE_OT_color_delete); | WM_operatortype_append(PALETTE_OT_color_delete); | ||||
| WM_operatortype_append(PALETTE_OT_lock_layer); | |||||
| WM_operatortype_append(PALETTE_OT_palettecolor_isolate); | |||||
| WM_operatortype_append(PALETTE_OT_palettecolor_hide); | |||||
| WM_operatortype_append(PALETTE_OT_palettecolor_reveal); | |||||
| WM_operatortype_append(PALETTE_OT_palettecolor_lock_all); | |||||
| WM_operatortype_append(PALETTE_OT_palettecolor_unlock_all); | |||||
| WM_operatortype_append(PALETTE_OT_palettecolor_move); | |||||
| WM_operatortype_append(PALETTE_OT_palettecolor_select); | |||||
| WM_operatortype_append(PALETTE_OT_palettecolor_duplicate); | |||||
| WM_operatortype_append(PALETTE_OT_palettecolor_choose); | |||||
| /* paint curve */ | /* paint curve */ | ||||
| WM_operatortype_append(PAINTCURVE_OT_new); | WM_operatortype_append(PAINTCURVE_OT_new); | ||||
| Context not available. | |||||
| /* brush */ | /* brush */ | ||||
| WM_operatortype_append(BRUSH_OT_add); | WM_operatortype_append(BRUSH_OT_add); | ||||
| WM_operatortype_append(BRUSH_OT_add_gpencil); | |||||
| WM_operatortype_append(BRUSH_OT_scale_size); | WM_operatortype_append(BRUSH_OT_scale_size); | ||||
| WM_operatortype_append(BRUSH_OT_curve_preset); | WM_operatortype_append(BRUSH_OT_curve_preset); | ||||
| WM_operatortype_append(BRUSH_OT_reset); | WM_operatortype_append(BRUSH_OT_reset); | ||||
| Context not available. | |||||