Grease Pencil: UI (i.e. Panel) for Settings
authorJoshua Leung <aligorith@gmail.com>
Sat, 29 Aug 2009 06:50:32 +0000 (06:50 +0000)
committerJoshua Leung <aligorith@gmail.com>
Sat, 29 Aug 2009 06:50:32 +0000 (06:50 +0000)
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...

source/blender/editors/gpencil/gpencil_buttons.c
source/blender/editors/gpencil/gpencil_edit.c
source/blender/editors/gpencil/gpencil_intern.h
source/blender/editors/gpencil/gpencil_ops.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/include/ED_gpencil.h
source/blender/editors/space_view3d/view3d_buttons.c

index 12e987af47bb70a1ed3a57317bfd5b2ed000cbb4..b572cd6916a693941f55e38043b78424a371d839 100644 (file)
 #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"
 
 /* ------- 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);
+}
+
 /* ************************************************** */
index 3130e190ce287cd0db252392f65eff8ecedfe9fe..2faf3ccbbdadd5184bc62c69d3e7de108b64de9e 100644 (file)
@@ -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;
+}
 
 /* ************************************************ */
index b134328c8a0ca9b71085826f2e620497a0dceb97..cc98d491f7ae60837887a5f9f87e7ad9343a160e 100644 (file)
@@ -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! */
index 347a611ee301b1e579f2555d2e2b274b9f4737c8..364b27b61b0c65d395490a53a84cf417e27e8674 100644 (file)
@@ -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) --------------- */
 }
 
index 445d9ae346dc2753f4665fb3c477092ea7d6078d..82dc76a2152628cb7c4bb79773f6405b1c37270b 100644 (file)
@@ -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;
 }
index 25e622d8551133664724e43f96e2c3fab6fa7313..ba60211ef3f7fdaabfce67b4a6493fec134828fc 100644 (file)
@@ -39,8 +39,7 @@ struct bGPdata;
 struct bGPDlayer;
 struct bGPDframe;
 struct PointerRNA;
-struct uiLayout;
-struct uiBlock;
+struct Panel;
 struct ImBuf;
 struct wmWindowManager;
 
@@ -75,5 +74,7 @@ void draw_gpencil_2dview(struct bContext *C, short onlyv2d);
 void draw_gpencil_3dview(struct bContext *C, short only3d);
 void draw_gpencil_oglrender(struct bContext *C);
 
+void gpencil_panel_standard(const struct bContext *C, struct Panel *pa);
+
 
 #endif /*  ED_GPENCIL_H */
index 9b05f5b25b25bfb0766df402c82bde046445f874..2fbe7e5db79556311cd61a67626e1d5790789dda 100644 (file)
@@ -36,6 +36,7 @@
 #include "DNA_armature_types.h"
 #include "DNA_curve_types.h"
 #include "DNA_camera_types.h"
+#include "DNA_gpencil_types.h"
 #include "DNA_lamp_types.h"
 #include "DNA_lattice_types.h"
 #include "DNA_meta_types.h"
@@ -81,6 +82,7 @@
 #include "ED_armature.h"
 #include "ED_curve.h"
 #include "ED_image.h"
+#include "ED_gpencil.h"
 #include "ED_keyframing.h"
 #include "ED_mesh.h"
 #include "ED_object.h"
@@ -1199,33 +1201,6 @@ static void view3d_panel_preview(bContext *C, ARegion *ar, short cntrl)  // VIEW3
 }
 #endif
 
-#if 0
-static void view3d_panel_gpencil(const bContext *C, Panel *pa)
-{
-       View3D *v3d= CTX_wm_view3d(C);
-       uiBlock *block;
-
-       block= uiLayoutFreeBlock(pa->layout);
-
-       /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */
-       if (v3d->flag2 & V3D_DISPGP) {
-//             if (v3d->gpd == NULL)
-// XXX                 gpencil_data_setactive(ar, gpencil_data_addnew());
-       }
-       
-       if (v3d->flag2 & V3D_DISPGP) {
-// XXX         bGPdata *gpd= v3d->gpd;
-               
-               /* draw button for showing gpencil settings and drawings */
-               uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &v3d->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View (draw using Shift-LMB)");
-       }
-       else {
-               uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &v3d->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View");
-               uiDefBut(block, LABEL, 1, " ",  160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
-       }
-}
-#endif
-
 static void delete_sketch_armature(bContext *C, void *arg1, void *arg2)
 {
        BIF_deleteSketch(C);
@@ -1416,6 +1391,12 @@ void view3d_buttons_register(ARegionType *art)
        strcpy(pt->label, "Transform");
        pt->draw= view3d_panel_object;
        BLI_addtail(&art->paneltypes, pt);
+       
+       pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
+       strcpy(pt->idname, "VIEW3D_PT_gpencil");
+       strcpy(pt->label, "Grease Pencil");
+       pt->draw= gpencil_panel_standard;
+       BLI_addtail(&art->paneltypes, pt);
 /*
        pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel properties");
        strcpy(pt->idname, "VIEW3D_PT_properties");