Blender  V2.59
gpencil_buttons.c
Go to the documentation of this file.
00001 /*
00002  * $Id: gpencil_buttons.c 36223 2011-04-19 13:02:49Z aligorith $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2008, Blender Foundation, Joshua Leung
00021  * This is a new part of Blender
00022  *
00023  * Contributor(s): Joshua Leung
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include <stdio.h>
00034 #include <string.h>
00035 #include <stdlib.h>
00036 #include <stddef.h>
00037 
00038 
00039 #include "BLI_math.h"
00040 #include "BLI_blenlib.h"
00041 
00042 #include "DNA_gpencil_types.h"
00043 #include "DNA_screen_types.h"
00044 
00045 #include "BKE_context.h"
00046 #include "BKE_global.h"
00047 #include "BKE_gpencil.h"
00048 
00049 #include "WM_api.h"
00050 #include "WM_types.h"
00051 
00052 #include "RNA_access.h"
00053 
00054 
00055 #include "ED_gpencil.h"
00056 
00057 #include "UI_interface.h"
00058 #include "UI_resources.h"
00059 
00060 #include "gpencil_intern.h"
00061 
00062 /* ************************************************** */
00063 /* GREASE PENCIL PANEL-UI DRAWING */
00064 
00065 /* Every space which implements Grease-Pencil functionality should have a panel
00066  * for the settings. All of the space-dependent parts should be coded in the panel
00067  * code for that space, but the rest is all handled by generic panel here.
00068  */
00069 
00070 /* ------- Callbacks ----------- */
00071 /* These are just 'dummy wrappers' around gpencil api calls */
00072 
00073 /* make layer active one after being clicked on */
00074 static void gp_ui_activelayer_cb (bContext *C, void *gpd, void *gpl)
00075 {
00076         /* make sure the layer we want to remove is the active one */
00077         gpencil_layer_setactive(gpd, gpl);
00078 
00079         WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work!
00080 }
00081 
00082 /* delete 'active' layer */
00083 static void gp_ui_dellayer_cb (bContext *C, void *gpd, void *gpl)
00084 {
00085         /* make sure the layer we want to remove is the active one */
00086         gpencil_layer_setactive(gpd, gpl); 
00087         gpencil_layer_delactive(gpd);
00088         
00089         WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work!
00090 }
00091 
00092 
00093 
00094 /* ------- Drawing Code ------- */
00095 
00096 /* draw the controls for a given layer */
00097 static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl, const short is_v3d)
00098 {
00099         uiLayout *box=NULL, *split=NULL;
00100         uiLayout *col=NULL, *subcol=NULL;
00101         uiLayout *row=NULL, *subrow=NULL;
00102         uiBlock *block;
00103         uiBut *but;
00104         PointerRNA ptr;
00105         int icon;
00106         
00107         /* make pointer to layer data */
00108         RNA_pointer_create((ID *)gpd, &RNA_GPencilLayer, gpl, &ptr);
00109         
00110         /* unless button has own callback, it adds this callback to button */
00111         block= uiLayoutGetBlock(layout);
00112         uiBlockSetFunc(block, gp_ui_activelayer_cb, gpd, gpl);
00113         
00114         /* draw header ---------------------------------- */
00115         /* get layout-row + UI-block for header */
00116         box= uiLayoutBox(layout);
00117         
00118         row= uiLayoutRow(box, 0);
00119         uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_EXPAND);
00120         block= uiLayoutGetBlock(row); // err...
00121         
00122         uiBlockSetEmboss(block, UI_EMBOSSN);
00123         
00124         /* left-align ............................... */
00125         subrow= uiLayoutRow(row, 0);
00126         
00127         /* active */
00128         block= uiLayoutGetBlock(subrow);
00129         icon= (gpl->flag & GP_LAYER_ACTIVE) ? ICON_RADIOBUT_ON : ICON_RADIOBUT_OFF;
00130         but= uiDefIconBut(block, BUT, 0, icon, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Set active layer");
00131         uiButSetFunc(but, gp_ui_activelayer_cb, gpd, gpl);
00132 
00133         /* locked */
00134         icon= (gpl->flag & GP_LAYER_LOCKED) ? ICON_LOCKED : ICON_UNLOCKED;
00135         uiItemR(subrow, &ptr, "lock", 0, "", icon);
00136         
00137         /* when layer is locked or hidden, only draw header */
00138         if (gpl->flag & (GP_LAYER_LOCKED|GP_LAYER_HIDE)) {
00139                 char name[256]; /* gpl->info is 128, but we need space for 'locked/hidden' as well */
00140                 
00141                 /* visibility button (only if hidden but not locked!) */
00142                 if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED))
00143                         uiItemR(subrow, &ptr, "hide", 0, "", ICON_RESTRICT_VIEW_ON); 
00144                         
00145                 
00146                 /* name */
00147                 if (gpl->flag & GP_LAYER_HIDE)
00148                         sprintf(name, "%s (Hidden)", gpl->info);
00149                 else
00150                         sprintf(name, "%s (Locked)", gpl->info);
00151                 uiItemL(subrow, name, ICON_NONE);
00152                         
00153                 /* delete button (only if hidden but not locked!) */
00154                 if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED)) {
00155                         /* right-align ............................... */
00156                         subrow= uiLayoutRow(row, 1);
00157                         uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_RIGHT);
00158                         block= uiLayoutGetBlock(subrow); // XXX... err...
00159                         
00160                         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");
00161                         uiButSetFunc(but, gp_ui_dellayer_cb, gpd, gpl);
00162                 }       
00163                 uiBlockSetEmboss(block, UI_EMBOSS);
00164         }
00165         else {
00166                 /* draw rest of header -------------------------------- */
00167                 /* visibility button */
00168                 uiItemR(subrow, &ptr, "hide", 0, "", ICON_RESTRICT_VIEW_OFF); 
00169                 
00170                 /* frame locking */
00171                 // TODO: this needs its own icons...
00172                 icon= (gpl->flag & GP_LAYER_FRAMELOCK) ? ICON_RENDER_STILL : ICON_RENDER_ANIMATION;
00173                 uiItemR(subrow, &ptr, "lock_frame", 0, "", icon); 
00174                 
00175                 uiBlockSetEmboss(block, UI_EMBOSS);
00176                 
00177                 /* name */
00178                 uiItemR(subrow, &ptr, "info", 0, "", ICON_NONE);
00179                 
00180                 /* delete 'button' */
00181                 uiBlockSetEmboss(block, UI_EMBOSSN);
00182                         /* right-align ............................... */
00183                         subrow= uiLayoutRow(row, 1);
00184                         uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_RIGHT);
00185                         block= uiLayoutGetBlock(subrow); // XXX... err...
00186                         
00187                         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");
00188                         uiButSetFunc(but, gp_ui_dellayer_cb, gpd, gpl);
00189                 uiBlockSetEmboss(block, UI_EMBOSS);
00190                 
00191                 
00192                 /* new backdrop ----------------------------------- */
00193                 box= uiLayoutBox(layout);
00194                 split= uiLayoutSplit(box, 0.5f, 0);
00195                 
00196                 /* draw settings ---------------------------------- */
00197                 /* left column ..................... */
00198                 col= uiLayoutColumn(split, 0);
00199                 
00200                 /* color */
00201                 subcol= uiLayoutColumn(col, 1);
00202                         uiItemR(subcol, &ptr, "color", 0, "", ICON_NONE);
00203                         uiItemR(subcol, &ptr, "alpha", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
00204                         
00205                 /* stroke thickness */
00206                 subcol= uiLayoutColumn(col, 1);
00207                         uiItemR(subcol, &ptr, "line_width", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
00208                 
00209                 /* debugging options */
00210                 if (G.f & G_DEBUG) {
00211                         subcol= uiLayoutColumn(col, 1);
00212                                 uiItemR(subcol, &ptr, "show_points", 0, NULL, ICON_NONE);
00213                 }
00214                 
00215                 /* right column ................... */
00216                 col= uiLayoutColumn(split, 0);
00217                 
00218                 /* onion-skinning */
00219                 subcol= uiLayoutColumn(col, 1);
00220                         uiItemR(subcol, &ptr, "use_onion_skinning", 0, "Onion Skinning", ICON_NONE);
00221                         uiItemR(subcol, &ptr, "ghost_range_max", 0, "Frames", ICON_NONE); // XXX shorter name here? i.e. GStep
00222                 
00223                 /* 3d-view specific drawing options */
00224                 if (is_v3d) {
00225                         subcol= uiLayoutColumn(col, 0);
00226                                 uiItemR(subcol, &ptr, "show_x_ray", 0, "X-Ray", ICON_NONE);
00227                 }
00228                 
00229         }
00230 } 
00231 
00232 /* stroke drawing options available */
00233 typedef enum eGP_Stroke_Ops {
00234         STROKE_OPTS_NORMAL = 0, 
00235         STROKE_OPTS_V3D_OFF, 
00236         STROKE_OPTS_V3D_ON,
00237 } eGP_Stroke_Ops;
00238 
00239 /* Draw the contents for a grease-pencil panel*/
00240 static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, PointerRNA *ctx_ptr)
00241 {
00242         PointerRNA gpd_ptr;
00243         bGPDlayer *gpl;
00244         uiLayout *col, *row;
00245         short v3d_stroke_opts = STROKE_OPTS_NORMAL;
00246         const short is_v3d= CTX_wm_view3d(C) != NULL;
00247         
00248         /* make new PointerRNA for Grease Pencil block */
00249         RNA_id_pointer_create((ID *)gpd, &gpd_ptr);
00250         
00251         /* draw gpd settings first ------------------------------------- */
00252         col= uiLayoutColumn(layout, 0);
00253                 /* current Grease Pencil block */
00254                 // TODO: show some info about who owns this?
00255                 uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", NULL, "GPENCIL_OT_data_unlink"); 
00256                 
00257                 /* add new layer button - can be used even when no data, since it can add a new block too */
00258                 uiItemO(col, "New Layer", ICON_NONE, "GPENCIL_OT_layer_add");
00259                 row= uiLayoutRow(col, 1);
00260                 uiItemO(row, "Delete Frame", ICON_NONE, "GPENCIL_OT_active_frame_delete");
00261                 uiItemO(row, "Convert", ICON_NONE, "GPENCIL_OT_convert");
00262                 
00263         /* sanity checks... */
00264         if (gpd == NULL)
00265                 return;
00266         
00267         /* draw each layer --------------------------------------------- */
00268         for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
00269                 col= uiLayoutColumn(layout, 1);
00270                         gp_drawui_layer(col, gpd, gpl, is_v3d);
00271         }
00272         
00273         /* draw gpd drawing settings first ------------------------------------- */
00274         col= uiLayoutColumn(layout, 1);
00275                 /* label */
00276                 uiItemL(col, "Drawing Settings:", ICON_NONE);
00277                 
00278                 /* check whether advanced 3D-View drawing space options can be used */
00279                 if (is_v3d) {
00280                         if (gpd->flag & (GP_DATA_DEPTH_STROKE|GP_DATA_DEPTH_VIEW))
00281                                 v3d_stroke_opts = STROKE_OPTS_V3D_ON;
00282                         else
00283                                 v3d_stroke_opts = STROKE_OPTS_V3D_OFF;
00284                 }
00285                 
00286                 /* drawing space options */
00287                 row= uiLayoutRow(col, 1);
00288                         uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "VIEW", NULL, ICON_NONE);
00289                         uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "CURSOR", NULL, ICON_NONE);
00290                 row= uiLayoutRow(col, 1);
00291                         uiLayoutSetActive(row, v3d_stroke_opts);
00292                         uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "SURFACE", NULL, ICON_NONE);
00293                         uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "STROKE", NULL, ICON_NONE);
00294                 
00295                 row= uiLayoutRow(col, 0);
00296                         uiLayoutSetActive(row, v3d_stroke_opts==STROKE_OPTS_V3D_ON);
00297                         uiItemR(row, &gpd_ptr, "use_stroke_endpoints", 0, NULL, ICON_NONE);
00298 }       
00299 
00300 
00301 /* Standard panel to be included whereever Grease Pencil is used... */
00302 void gpencil_panel_standard(const bContext *C, Panel *pa)
00303 {
00304         bGPdata **gpd_ptr = NULL;
00305         PointerRNA ptr;
00306         
00307         //if (v3d->flag2 & V3D_DISPGP)... etc.
00308         
00309         /* get pointer to Grease Pencil Data */
00310         gpd_ptr= gpencil_data_get_pointers((bContext *)C, &ptr);
00311         
00312         if (gpd_ptr)
00313                 draw_gpencil_panel((bContext *)C, pa->layout, *gpd_ptr, &ptr);
00314 }
00315 
00316 /* ************************************************** */