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:
authorJoshua Leung <aligorith@gmail.com>2009-08-29 10:50:32 +0400
committerJoshua Leung <aligorith@gmail.com>2009-08-29 10:50:32 +0400
commit8930a4fd332e69442b4de2efe42019bf5a41c946 (patch)
tree6a276c12cb665324543e67f484a84e6657a32411 /source/blender/editors/gpencil
parentf46f6dc7ba32411a8031a243bba635c8cc3ade29 (diff)
Grease Pencil: UI (i.e. Panel) for Settings
Restored the UI for access to the GP layers. There are still a few minor bugs here: * Wrong icons on the toggles - even when they're enabled, they only show a single state * The ID-template doesn't seem to be showing up. Dunno what's going wrong there...
Diffstat (limited to 'source/blender/editors/gpencil')
-rw-r--r--source/blender/editors/gpencil/gpencil_buttons.c336
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c126
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h7
-rw-r--r--source/blender/editors/gpencil/gpencil_ops.c6
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c5
5 files changed, 279 insertions, 201 deletions
diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c
index 12e987af47b..b572cd6916a 100644
--- a/source/blender/editors/gpencil/gpencil_buttons.c
+++ b/source/blender/editors/gpencil/gpencil_buttons.c
@@ -47,11 +47,11 @@
#include "BKE_gpencil.h"
#include "BKE_utildefines.h"
-#include "PIL_time.h"
-
#include "WM_api.h"
#include "WM_types.h"
+#include "RNA_access.h"
+
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -76,259 +76,195 @@
/* ------- Callbacks ----------- */
/* These are just 'dummy wrappers' around gpencil api calls */
-#if 0
-// XXX
-/* make layer active one after being clicked on */
-void gp_ui_activelayer_cb (void *gpd, void *gpl)
-{
- gpencil_layer_setactive(gpd, gpl);
-
- scrarea_queue_winredraw(curarea);
- allqueue(REDRAWACTION, 0);
-}
-/* rename layer and set active */
-void gp_ui_renamelayer_cb (void *gpd_arg, void *gpl_arg)
+/* make layer active one after being clicked on */
+void gp_ui_activelayer_cb (bContext *C, void *gpd, void *gpl)
{
- bGPdata *gpd= (bGPdata *)gpd_arg;
- bGPDlayer *gpl= (bGPDlayer *)gpl_arg;
-
- BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info[0]), 128);
gpencil_layer_setactive(gpd, gpl);
- scrarea_queue_winredraw(curarea);
- allqueue(REDRAWACTION, 0);
-}
-
-/* add a new layer */
-void gp_ui_addlayer_cb (void *gpd, void *dummy)
-{
- gpencil_layer_addnew(gpd);
-
- scrarea_queue_winredraw(curarea);
- allqueue(REDRAWACTION, 0);
+ WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work!
}
-/* delete active layer */
-void gp_ui_dellayer_cb (void *gpd, void *dummy)
+/* delete 'active' layer */
+void gp_ui_dellayer_cb (bContext *C, void *gpd, void *gpl)
{
+ /* make sure the layer we want to remove is the active one */
+ gpencil_layer_setactive(gpd, gpl);
gpencil_layer_delactive(gpd);
- scrarea_queue_winredraw(curarea);
- allqueue(REDRAWACTION, 0);
+ WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work!
}
-/* delete last stroke of active layer */
-void gp_ui_delstroke_cb (void *gpd, void *gpl)
-{
- bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0);
-
- if (gpf) {
- if (gpf->framenum != CFRA) return;
-
- gpencil_layer_setactive(gpd, gpl);
- gpencil_frame_delete_laststroke(gpl, gpf);
-
- scrarea_queue_winredraw(curarea);
- }
-}
-
-/* delete active frame of active layer */
-void gp_ui_delframe_cb (void *gpd, void *gpl)
-{
- bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0);
-
- gpencil_layer_setactive(gpd, gpl);
- gpencil_layer_delframe(gpl, gpf);
-
- scrarea_queue_winredraw(curarea);
- allqueue(REDRAWACTION, 0);
-}
-
-/* convert the active layer to geometry */
-void gp_ui_convertlayer_cb (void *gpd, void *gpl)
-{
- gpencil_layer_setactive(gpd, gpl);
- gpencil_convert_menu();
-
- scrarea_queue_winredraw(curarea);
-}
-#endif
-
/* ------- Drawing Code ------- */
-#if 0
-/* XXX */
/* draw the controls for a given layer */
-static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short *xco, short *yco)
+static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl)
{
+ uiLayout *box=NULL, *split=NULL;
+ uiLayout *col=NULL, *subcol=NULL;
+ uiLayout *row=NULL, *subrow=NULL;
+ uiBlock *block;
uiBut *but;
- short active= (gpl->flag & GP_LAYER_ACTIVE);
- short width= 314;
- short height;
- int rb_col;
+ PointerRNA ptr;
+
+ /* make pointer to layer data */
+ RNA_pointer_create((ID *)gpd, &RNA_GPencilLayer, gpl, &ptr);
/* unless button has own callback, it adds this callback to button */
+ block= uiLayoutGetBlock(layout);
uiBlockSetFunc(block, gp_ui_activelayer_cb, gpd, gpl);
- /* draw header */
- {
- uiBlockSetEmboss(block, UI_EMBOSSN);
-
- /* rounded header */
- if (active) uiBlockSetCol(block, TH_BUT_ACTION);
- rb_col= (active)?-20:20;
- uiDefBut(block, ROUNDBOX, B_REDR, "", *xco-8, *yco-2, width, 24, NULL, 5.0, 0.0, 15.0, (float)(rb_col-20), "");
- if (active) uiBlockSetCol(block, TH_AUTO);
-
- /* lock toggle */
- uiDefIconButBitI(block, ICONTOG, GP_LAYER_LOCKED, B_REDR, ICON_UNLOCKED, *xco-7, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Layer cannot be modified");
- }
+ /* draw header ---------------------------------- */
+ /* get layout-row + UI-block for header */
+ box= uiLayoutBox(layout);
+
+ row= uiLayoutRow(box, 0);
+ block= uiLayoutGetBlock(row); // err...
+
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+
+ /* left-align ............................... */
+ subrow= uiLayoutRow(row, 1);
+ uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_LEFT);
+
+ /* active */
+ uiItemR(subrow, "", ICON_RADIOBUT_OFF, &ptr, "active", UI_ITEM_R_TOGGLE); // XXX we need to set it to toggle to get icon
+
+ /* locked */
+ uiItemR(subrow, "", ICON_UNLOCKED, &ptr, "locked", UI_ITEM_R_TOGGLE); // XXX we need to set it to toggle to get icon
/* when layer is locked or hidden, only draw header */
if (gpl->flag & (GP_LAYER_LOCKED|GP_LAYER_HIDE)) {
char name[256]; /* gpl->info is 128, but we need space for 'locked/hidden' as well */
- height= 0;
-
/* visibility button (only if hidden but not locked!) */
if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED))
- uiDefIconButBitI(block, ICONTOG, GP_LAYER_HIDE, B_REDR, ICON_RESTRICT_VIEW_OFF, *xco+12, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Visibility of layer");
+ uiItemR(subrow, "", ICON_RESTRICT_VIEW_OFF, &ptr, "hide", UI_ITEM_R_TOGGLE); // XXX we need to set it to toggle to get icon
/* name */
if (gpl->flag & GP_LAYER_HIDE)
sprintf(name, "%s (Hidden)", gpl->info);
else
sprintf(name, "%s (Locked)", gpl->info);
- uiDefBut(block, LABEL, 1, name, *xco+35, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "Short description of what this layer is for (optional)");
+ uiItemL(subrow, name, 0);
/* delete button (only if hidden but not locked!) */
if ((gpl->flag & GP_LAYER_HIDE) & !(gpl->flag & GP_LAYER_LOCKED)) {
- but= uiDefIconBut(block, BUT, B_REDR, ICON_X, *xco+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer");
- uiButSetFunc(but, gp_ui_dellayer_cb, gpd, NULL);
+ /* right-align ............................... */
+ subrow= uiLayoutRow(row, 1);
+ uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_RIGHT);
+ block= uiLayoutGetBlock(subrow); // XXX... err...
+
+ but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer");
+ uiButSetFunc(but, gp_ui_dellayer_cb, gpd, gpl);
}
uiBlockSetEmboss(block, UI_EMBOSS);
}
else {
- height= 97;
+ /* draw rest of header -------------------------------- */
+ /* visibility button */
+ uiItemR(subrow, "", ICON_RESTRICT_VIEW_OFF, &ptr, "hide", UI_ITEM_R_TOGGLE); // XXX we need to set it to toggle to get icon
- /* draw rest of header */
- {
- /* visibility button */
- uiDefIconButBitI(block, ICONTOG, GP_LAYER_HIDE, B_REDR, ICON_RESTRICT_VIEW_OFF, *xco+12, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Visibility of layer");
-
- uiBlockSetEmboss(block, UI_EMBOSS);
-
- /* name */
- but= uiDefButC(block, TEX, B_REDR, "Info:", *xco+36, *yco, 240, 19, gpl->info, 0, 127, 0, 0, "Short description of what this layer is for (optional)");
- uiButSetFunc(but, gp_ui_renamelayer_cb, gpd, gpl);
-
- /* delete 'button' */
- uiBlockSetEmboss(block, UI_EMBOSSN);
-
- but= uiDefIconBut(block, BUT, B_REDR, ICON_X, *xco+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer");
- uiButSetFunc(but, gp_ui_dellayer_cb, gpd, NULL);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
+ uiBlockSetEmboss(block, UI_EMBOSS);
- /* draw backdrop */
- if (active) uiBlockSetCol(block, TH_BUT_ACTION);
- uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12.0, (float)rb_col, "");
- if (active) uiBlockSetCol(block, TH_AUTO);
+ /* name */
+ uiItemR(subrow, "", 0, &ptr, "info", 0);
- /* draw settings */
- {
- /* color */
- uiBlockBeginAlign(block);
- uiDefButF(block, COL, B_REDR, "", *xco, *yco-26, 150, 19, gpl->color, 0, 0, 0, 0, "Color to use for all strokes on this Grease Pencil Layer");
- uiDefButF(block, NUMSLI, B_REDR, "Opacity: ", *xco,*yco-45,150,19, &gpl->color[3], 0.3f, 1.0f, 0, 0, "Visibility of stroke (0.3 to 1.0)");
- uiBlockEndAlign(block);
-
- /* stroke thickness */
- uiDefButS(block, NUMSLI, B_REDR, "Thickness:", *xco, *yco-75, 150, 20, &gpl->thickness, 1, 10, 0, 0, "Thickness of strokes (in pixels)");
-
- /* debugging options */
- if (G.f & G_DEBUG) {
- uiDefButBitI(block, TOG, GP_LAYER_DRAWDEBUG, B_REDR, "Show Points", *xco, *yco-95, 150, 20, &gpl->flag, 0, 0, 0, 0, "Show points which form the strokes");
- }
+ /* delete 'button' */
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ /* right-align ............................... */
+ subrow= uiLayoutRow(row, 1);
+ uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_RIGHT);
+ block= uiLayoutGetBlock(subrow); // XXX... err...
- /* onion-skinning */
- uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, GP_LAYER_ONIONSKIN, B_REDR, "Onion-Skin", *xco+160, *yco-26, 140, 20, &gpl->flag, 0, 0, 0, 0, "Ghost frames on either side of frame");
- uiDefButS(block, NUMSLI, B_REDR, "GStep:", *xco+160, *yco-46, 140, 20, &gpl->gstep, 0, 120, 0, 0, "Max number of frames on either side of active frame to show (0 = just 'first' available sketch on either side)");
- uiBlockEndAlign(block);
+ but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer");
+ uiButSetFunc(but, gp_ui_dellayer_cb, gpd, gpl);
+ uiBlockSetEmboss(block, UI_EMBOSS);
+
+
+ /* new backdrop ----------------------------------- */
+ box= uiLayoutBox(layout);
+ split= uiLayoutSplit(box, 0.5f);
+
+
+ /* draw settings ---------------------------------- */
+ /* left column ..................... */
+ col= uiLayoutColumn(split, 0);
+
+ /* color */
+ subcol= uiLayoutColumn(col, 1);
+ uiItemR(subcol, "", 0, &ptr, "color", 0);
+ uiItemR(subcol, NULL, 0, &ptr, "opacity", UI_ITEM_R_SLIDER);
- /* options */
- uiBlockBeginAlign(block);
- if (curarea->spacetype == SPACE_VIEW3D) {
- but= uiDefBut(block, BUT, B_REDR, "Convert to...", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Converts this layer's strokes to geometry (Hotkey = Alt-Shift-C)");
- uiButSetFunc(but, gp_ui_convertlayer_cb, gpd, gpl);
- }
- else {
- but= uiDefBut(block, BUT, B_REDR, "Del Active Frame", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Erases the the active frame for this layer (Hotkey = Alt-XKEY/DEL)");
- uiButSetFunc(but, gp_ui_delframe_cb, gpd, gpl);
- }
-
- but= uiDefBut(block, BUT, B_REDR, "Del Last Stroke", *xco+160, *yco-95, 140, 20, NULL, 0, 0, 0, 0, "Erases the last stroke from the active frame (Hotkey = Alt-XKEY/DEL)");
- uiButSetFunc(but, gp_ui_delstroke_cb, gpd, gpl);
- uiBlockEndAlign(block);
+ /* stroke thickness */
+ subcol= uiLayoutColumn(col, 1);
+ uiItemR(subcol, NULL, 0, &ptr, "line_thickness", UI_ITEM_R_SLIDER);
+
+ /* debugging options */
+ if (G.f & G_DEBUG) {
+ // XXX this option hasn't been wrapped yet... since it's just debug
+ //subcol= uiLayoutColumn(col, 1);
+ // uiItemR(subrow, NULL, 0, &ptr, "show_points", 0);
}
+
+ /* right column ................... */
+ col= uiLayoutColumn(split, 0);
+
+ /* onion-skinning */
+ subcol= uiLayoutColumn(col, 1);
+ uiItemR(subcol, "Onion Skinning", 0, &ptr, "use_onion_skinning", 0);
+ uiItemR(subcol, "GStep", 0, &ptr, "max_ghost_range", 0); // XXX shorter name here? (i.e. GStep)
+
+ /* additional options... */
+ // None at the moment...
}
-
- /* adjust height for new to start */
- (*yco) -= (height + 27);
}
-#endif
-/* Draw the contents for a grease-pencil panel. This assumes several things:
- * - that panel has been created, is 318 x 204. max yco is 225
- * - that a toggle for turning on/off gpencil drawing is 150 x 20, starting from (10,225)
- * which is basically the top left-hand corner
- * It will return the amount of extra space to extend the panel by
- */
-short draw_gpencil_panel (uiBlock *block, bGPdata *gpd, ScrArea *sa)
+
+/* Draw the contents for a grease-pencil panel*/
+static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, PointerRNA *ctx_ptr)
{
-#if 0
- uiBut *but;
bGPDlayer *gpl;
- short xco= 10, yco= 170;
+ uiLayout *col;
- /* draw gpd settings first */
- {
- /* add new layer buttons */
- but= uiDefBut(block, BUT, B_REDR, "Add New Layer", 10,205,150,20, 0, 0, 0, 0, 0, "Adds a new Grease Pencil Layer");
- uiButSetFunc(but, gp_ui_addlayer_cb, gpd, NULL);
+ /* draw gpd settings first ------------------------------------- */
+ col= uiLayoutColumn(layout, 1);
+ /* current Grease Pencil block */
+ // TODO: show some info about who owns this?
+ // XXX: this template doesn't show up!
+ uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_new", "GPENCIL_OT_data_unlink");
-
- /* show override lmb-clicks button + painting lock */
- uiBlockBeginAlign(block);
- if ((gpd->flag & GP_DATA_EDITPAINT)==0) {
- uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 130, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes");
-
- uiBlockSetCol(block, TH_BUT_SETTING);
- uiDefIconButBitI(block, ICONTOG, GP_DATA_LMBPLOCK, B_REDR, ICON_UNLOCKED, 300, 225, 20, 20, &gpd->flag, 0.0, 0.0, 0, 0, "Painting cannot occur with Shift-LMB (when making selections)");
- uiBlockSetCol(block, TH_AUTO);
- }
- else
- uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 150, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes");
- uiBlockEndAlign(block);
-
- /* 'view align' button (naming depends on context) */
- if (sa->spacetype == SPACE_VIEW3D)
- uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Sketch in 3D", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added in 3D-space");
- else
- uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Stick to View", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added on 2d-canvas");
- }
+ /* add new layer button */
+ uiItemO(col, NULL, 0, "GPENCIL_OT_layer_add");
- /* draw for each layer */
+ /* 'view align' button (naming depends on context) */
+#if 0 // XXX for now, this is enabled by default anyways
+ if (sa->spacetype == SPACE_VIEW3D)
+ uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Sketch in 3D", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added in 3D-space");
+ else
+ uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Stick to View", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added on 2d-canvas");
+#endif
+
+ /* draw each layer --------------------------------------------- */
for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
- gp_drawui_layer(block, gpd, gpl, &xco, &yco);
+ col= uiLayoutColumn(layout, 1);
+ gp_drawui_layer(col, gpd, gpl);
}
-
- /* return new height if necessary */
- return (yco < 0) ? (204 - yco) : 204;
-#endif
- return 0;
}
+
+/* Standard panel to be included whereever Grease Pencil is used... */
+void gpencil_panel_standard(const bContext *C, Panel *pa)
+{
+ bGPdata **gpd_ptr = NULL;
+ PointerRNA ptr;
+
+ //if (v3d->flag2 & V3D_DISPGP)... etc.
+
+ /* get pointer to Grease Pencil Data */
+ gpd_ptr= gpencil_data_get_pointers((bContext *)C, &ptr);
+
+ if (gpd_ptr && *gpd_ptr)
+ draw_gpencil_panel((bContext *)C, pa->layout, *gpd_ptr, &ptr);
+}
+
/* ************************************************** */
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 3130e190ce2..2faf3ccbbda 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -60,6 +60,7 @@
#include "BKE_gpencil.h"
#include "BKE_image.h"
#include "BKE_library.h"
+#include "BKE_report.h"
#include "BKE_utildefines.h"
#include "BIF_gl.h"
@@ -123,6 +124,9 @@ bGPdata **gpencil_data_get_pointers (bContext *C, PointerRNA *ptr)
/* return the GP data for the active strips/image/etc. */
}
break;
+
+ default: /* unsupported space */
+ return NULL;
}
}
@@ -141,6 +145,128 @@ bGPdata *gpencil_data_get_active (bContext *C)
/* ************************************************ */
/* Panel Operators */
+/* poll callback for adding data/layers - special */
+static int gp_add_poll (bContext *C)
+{
+ /* the base line we have is that we have somewhere to add Grease Pencil data */
+ return gpencil_data_get_pointers(C, NULL) != NULL;
+}
+
+/* ******************* Add New Data ************************ */
+
+/* add new datablock - wrapper around API */
+static int gp_data_add_exec (bContext *C, wmOperator *op)
+{
+ bGPdata **gpd_ptr= gpencil_data_get_pointers(C, NULL);
+
+ if (gpd_ptr == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Nowhere for Grease Pencil data to go");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* just add new datablock now */
+ *gpd_ptr= gpencil_data_addnew("GPencil");
+ }
+
+ /* notifiers */
+ WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work!
+
+ return OPERATOR_FINISHED;
+}
+void GPENCIL_OT_data_add (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Grease Pencil Add New";
+ ot->idname= "GPENCIL_OT_data_add";
+ ot->description= "Add new Grease Pencil datablock.";
+
+ /* callbacks */
+ ot->exec= gp_data_add_exec;
+ ot->poll= gp_add_poll;
+}
+
+/* ******************* Unlink Data ************************ */
+
+/* poll callback for adding data/layers - special */
+static int gp_data_unlink_poll (bContext *C)
+{
+ bGPdata **gpd_ptr= gpencil_data_get_pointers(C, NULL);
+
+ /* if we have access to some active data, make sure there's a datablock before enabling this */
+ return (gpd_ptr && *gpd_ptr);
+}
+
+
+/* unlink datablock - wrapper around API */
+static int gp_data_unlink_exec (bContext *C, wmOperator *op)
+{
+ bGPdata **gpd_ptr= gpencil_data_get_pointers(C, NULL);
+
+ if (gpd_ptr == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Nowhere for Grease Pencil data to go");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* just unlink datablock now, decreasing its user count */
+ bGPdata *gpd= (*gpd_ptr);
+
+ gpd->id.us--;
+ *gpd_ptr= NULL;
+ }
+
+ /* notifiers */
+ WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work!
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_data_unlink (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Grease Pencil Unlink";
+ ot->idname= "GPENCIL_OT_data_unlink";
+ ot->description= "Unlink active Grease Pencil datablock.";
+
+ /* callbacks */
+ ot->exec= gp_data_unlink_exec;
+ ot->poll= gp_data_unlink_poll;
+}
+
+/* ******************* Add New Layer ************************ */
+
+/* add new layer - wrapper around API */
+static int gp_layer_add_exec (bContext *C, wmOperator *op)
+{
+ bGPdata **gpd_ptr= gpencil_data_get_pointers(C, NULL);
+
+ /* if there's no existing Grease-Pencil data there, add some */
+ if (gpd_ptr == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Nowhere for Grease Pencil data to go");
+ return OPERATOR_CANCELLED;
+ }
+ if (*gpd_ptr == NULL)
+ *gpd_ptr= gpencil_data_addnew("GPencil");
+
+ /* add new layer now */
+ gpencil_layer_addnew(*gpd_ptr);
+
+ /* notifiers */
+ WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work!
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_layer_add (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add New Layer";
+ ot->idname= "GPENCIL_OT_layer_add";
+ ot->description= "Add new Grease Pencil layer for the active Grease Pencil datablock.";
+
+ /* callbacks */
+ ot->exec= gp_layer_add_exec;
+ ot->poll= gp_add_poll;
+}
/* ************************************************ */
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index b134328c8a0..cc98d491f7a 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -40,6 +40,13 @@ struct wmOperatorType;
void GPENCIL_OT_draw(struct wmOperatorType *ot);
+/* buttons editing --- */
+
+void GPENCIL_OT_data_add(struct wmOperatorType *ot);
+void GPENCIL_OT_data_unlink(struct wmOperatorType *ot);
+
+void GPENCIL_OT_layer_add(struct wmOperatorType *ot);
+
/******************************************************* */
/* FILTERED ACTION DATA - TYPES ---> XXX DEPRECEATED OLD ANIM SYSTEM CODE! */
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 347a611ee30..364b27b61b0 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -66,10 +66,16 @@ void gpencil_common_keymap(wmWindowManager *wm, ListBase *keymap)
void ED_operatortypes_gpencil (void)
{
/* Drawing ----------------------- */
+
WM_operatortype_append(GPENCIL_OT_draw);
/* Editing (Buttons) ------------ */
+ WM_operatortype_append(GPENCIL_OT_data_add);
+ WM_operatortype_append(GPENCIL_OT_data_unlink);
+
+ WM_operatortype_append(GPENCIL_OT_layer_add);
+
/* Editing (Time) --------------- */
}
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 445d9ae346d..82dc76a2152 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -919,7 +919,7 @@ static void gp_paint_initstroke (tGPsdata *p, short paintmode)
View3D *v3d= (View3D *)p->sa->spacedata.first;
RegionView3D *rv3d= p->ar->regiondata;
- // TODO: this should only happen for scene... otherwise use object center!
+ // TODO: this should only happen for scene... otherwise apply correction for object center!
float *fp= give_cursor(p->scene, v3d);
initgrabz(rv3d, fp[0], fp[1], fp[2]);
@@ -1231,6 +1231,9 @@ static int gpencil_draw_exec (bContext *C, wmOperator *op)
/* cleanup */
gpencil_draw_exit(C, op);
+ /* refreshes */
+ WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work!
+
/* done */
return OPERATOR_FINISHED;
}