svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r22875:22935
[blender.git] / source / blender / editors / gpencil / gpencil_buttons.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2008, Blender Foundation, Joshua Leung
21  * This is a new part of Blender
22  *
23  * Contributor(s): Joshua Leung
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27  
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stddef.h>
32
33 #include "MEM_guardedalloc.h"
34
35 #include "BLI_arithb.h"
36 #include "BLI_blenlib.h"
37
38 #include "DNA_gpencil_types.h"
39 #include "DNA_listBase.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_screen_types.h"
42 #include "DNA_userdef_types.h"
43 #include "DNA_windowmanager_types.h"
44
45 #include "BKE_context.h"
46 #include "BKE_global.h"
47 #include "BKE_gpencil.h"
48 #include "BKE_utildefines.h"
49
50 #include "WM_api.h"
51 #include "WM_types.h"
52
53 #include "RNA_access.h"
54
55 #include "BIF_gl.h"
56 #include "BIF_glutil.h"
57
58 #include "ED_gpencil.h"
59 #include "ED_sequencer.h"
60 #include "ED_util.h"
61
62 #include "UI_interface.h"
63 #include "UI_resources.h"
64 #include "UI_view2d.h"
65
66 #include "gpencil_intern.h"
67
68 /* ************************************************** */
69 /* GREASE PENCIL PANEL-UI DRAWING */
70
71 /* Every space which implements Grease-Pencil functionality should have a panel
72  * for the settings. All of the space-dependent parts should be coded in the panel
73  * code for that space, but the rest is all handled by generic panel here.
74  */
75
76 /* ------- Callbacks ----------- */
77 /* These are just 'dummy wrappers' around gpencil api calls */
78
79 /* make layer active one after being clicked on */
80 void gp_ui_activelayer_cb (bContext *C, void *gpd, void *gpl)
81 {
82         gpencil_layer_setactive(gpd, gpl);
83         
84         WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work!
85 }
86
87 /* delete 'active' layer */
88 void gp_ui_dellayer_cb (bContext *C, void *gpd, void *gpl)
89 {
90         /* make sure the layer we want to remove is the active one */
91         gpencil_layer_setactive(gpd, gpl); 
92         gpencil_layer_delactive(gpd);
93         
94         WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work!
95 }
96
97 /* ------- Drawing Code ------- */
98
99 /* draw the controls for a given layer */
100 static void gp_drawui_layer (uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl)
101 {
102         uiLayout *box=NULL, *split=NULL;
103         uiLayout *col=NULL, *subcol=NULL;
104         uiLayout *row=NULL, *subrow=NULL;
105         uiBlock *block;
106         uiBut *but;
107         PointerRNA ptr;
108         int icon;
109         
110         /* make pointer to layer data */
111         RNA_pointer_create((ID *)gpd, &RNA_GPencilLayer, gpl, &ptr);
112         
113         /* unless button has own callback, it adds this callback to button */
114         block= uiLayoutGetBlock(layout);
115         uiBlockSetFunc(block, gp_ui_activelayer_cb, gpd, gpl);
116         
117         /* draw header ---------------------------------- */
118         /* get layout-row + UI-block for header */
119         box= uiLayoutBox(layout);
120         
121         row= uiLayoutRow(box, 0);
122         block= uiLayoutGetBlock(row); // err...
123         
124         uiBlockSetEmboss(block, UI_EMBOSSN);
125         
126         /* left-align ............................... */
127         subrow= uiLayoutRow(row, 1);
128         uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_LEFT);
129         
130         /* active */
131         icon= (gpl->flag & GP_LAYER_ACTIVE) ? ICON_RADIOBUT_ON : ICON_RADIOBUT_OFF;
132         uiItemR(subrow, "", icon, &ptr, "active", 0);
133         
134         /* locked */
135         icon= (gpl->flag & GP_LAYER_LOCKED) ? ICON_LOCKED : ICON_UNLOCKED;
136         uiItemR(subrow, "", icon, &ptr, "locked", 0);
137         
138         /* when layer is locked or hidden, only draw header */
139         if (gpl->flag & (GP_LAYER_LOCKED|GP_LAYER_HIDE)) {
140                 char name[256]; /* gpl->info is 128, but we need space for 'locked/hidden' as well */
141                 
142                 /* visibility button (only if hidden but not locked!) */
143                 if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED))
144                         uiItemR(subrow, "", ICON_RESTRICT_VIEW_ON, &ptr, "hide", 0); 
145                         
146                 
147                 /* name */
148                 if (gpl->flag & GP_LAYER_HIDE)
149                         sprintf(name, "%s (Hidden)", gpl->info);
150                 else
151                         sprintf(name, "%s (Locked)", gpl->info);
152                 uiItemL(subrow, name, 0);
153                         
154                 /* delete button (only if hidden but not locked!) */
155                 if ((gpl->flag & GP_LAYER_HIDE) & !(gpl->flag & GP_LAYER_LOCKED)) {
156                         /* right-align ............................... */
157                         subrow= uiLayoutRow(row, 1);
158                         uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_RIGHT);
159                         block= uiLayoutGetBlock(subrow); // XXX... err...
160                         
161                         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");
162                         uiButSetFunc(but, gp_ui_dellayer_cb, gpd, gpl);
163                 }       
164                 uiBlockSetEmboss(block, UI_EMBOSS);
165         }
166         else {
167                 /* draw rest of header -------------------------------- */
168                 /* visibility button */
169                 uiItemR(subrow, "", ICON_RESTRICT_VIEW_OFF, &ptr, "hide", 0); 
170                 
171                 uiBlockSetEmboss(block, UI_EMBOSS);
172                 
173                 /* name */
174                 uiItemR(subrow, "", 0, &ptr, "info", 0);
175                 
176                 /* delete 'button' */
177                 uiBlockSetEmboss(block, UI_EMBOSSN);
178                         /* right-align ............................... */
179                         subrow= uiLayoutRow(row, 1);
180                         uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_RIGHT);
181                         block= uiLayoutGetBlock(subrow); // XXX... err...
182                         
183                         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");
184                         uiButSetFunc(but, gp_ui_dellayer_cb, gpd, gpl);
185                 uiBlockSetEmboss(block, UI_EMBOSS);
186                 
187                 
188                 /* new backdrop ----------------------------------- */
189                 box= uiLayoutBox(layout);
190                 split= uiLayoutSplit(box, 0.5f);
191                 
192                 
193                 /* draw settings ---------------------------------- */
194                 /* left column ..................... */
195                 col= uiLayoutColumn(split, 0);
196                 
197                 /* color */
198                 subcol= uiLayoutColumn(col, 1);
199                         uiItemR(subcol, "", 0, &ptr, "color", 0);
200                         uiItemR(subcol, NULL, 0, &ptr, "opacity", UI_ITEM_R_SLIDER);
201                         
202                 /* stroke thickness */
203                 subcol= uiLayoutColumn(col, 1);
204                         uiItemR(subcol, NULL, 0, &ptr, "line_thickness", UI_ITEM_R_SLIDER);
205                 
206                 /* debugging options */
207                 if (G.f & G_DEBUG) {
208                         subcol= uiLayoutColumn(col, 1);
209                                 uiItemR(subcol, NULL, 0, &ptr, "show_points", 0);
210                 }
211                 
212                 /* right column ................... */
213                 col= uiLayoutColumn(split, 0);
214                 
215                 /* onion-skinning */
216                 subcol= uiLayoutColumn(col, 1);
217                         uiItemR(subcol, "Onion Skinning", 0, &ptr, "use_onion_skinning", 0);
218                         uiItemR(subcol, "GStep", 0, &ptr, "max_ghost_range", 0); // XXX shorter name here? (i.e. GStep)
219                 
220                 /* additional options... */
221                 subcol= uiLayoutColumn(col, 1);
222                         uiItemO(subcol, "Delete Frame", 0, "GPENCIL_OT_active_frame_delete");
223                         uiItemO(subcol, "Convert...", 0, "GPENCIL_OT_convert");
224         }
225
226
227 /* Draw the contents for a grease-pencil panel*/
228 static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, PointerRNA *ctx_ptr)
229 {
230         PointerRNA gpd_ptr;
231         bGPDlayer *gpl;
232         uiLayout *col;
233         
234         /* make new PointerRNA for Grease Pencil block */
235         RNA_id_pointer_create((ID *)gpd, &gpd_ptr);
236         
237         /* draw gpd settings first ------------------------------------- */
238         col= uiLayoutColumn(layout, 0);
239                 /* current Grease Pencil block */
240                 // TODO: show some info about who owns this?
241                 //uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_new", "GPENCIL_OT_data_unlink"); // XXX not working
242                 uiItemR(col, NULL, 0, ctx_ptr, "grease_pencil", 0); // XXX this will have to do for now...
243                 
244                 /* add new layer button */
245                 uiItemO(col, NULL, 0, "GPENCIL_OT_layer_add");
246         
247         /* draw each layer --------------------------------------------- */
248         for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
249                 col= uiLayoutColumn(layout, 1);
250                         gp_drawui_layer(col, gpd, gpl);
251         }
252         
253         /* draw gpd drawing settings first ------------------------------------- */
254         col= uiLayoutColumn(layout, 0);
255                 /* label */
256                 uiItemL(col, "Drawing Settings:", 0);
257                 
258                 /* 'stick to view' option */
259                 uiItemR(col, NULL, 0, &gpd_ptr, "view_space_draw", 0);
260 }       
261
262
263 /* Standard panel to be included whereever Grease Pencil is used... */
264 void gpencil_panel_standard(const bContext *C, Panel *pa)
265 {
266         bGPdata **gpd_ptr = NULL;
267         PointerRNA ptr;
268         
269         //if (v3d->flag2 & V3D_DISPGP)... etc.
270         
271         /* get pointer to Grease Pencil Data */
272         gpd_ptr= gpencil_data_get_pointers((bContext *)C, &ptr);
273         
274         if (gpd_ptr && *gpd_ptr)
275                 draw_gpencil_panel((bContext *)C, pa->layout, *gpd_ptr, &ptr);
276 }
277
278 /* ************************************************** */