Blender V2.61 - r43446

gpencil_buttons.c

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