7543988b5aab5e25cc139602f2ac4cf3a6359dc9
[blender.git] / source / blender / editors / space_clip / clip_toolbar.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2011 Blender Foundation.
19  * All rights reserved.
20  *
21  *
22  * Contributor(s): Blender Foundation,
23  *                 Sergey Sharybin
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/space_clip/clip_toolbar.c
29  *  \ingroup spclip
30  */
31
32 #include <string.h>
33
34 #include "DNA_windowmanager_types.h"
35
36 #include "RNA_access.h"
37
38 #include "MEM_guardedalloc.h"
39
40 #include "BLI_blenlib.h"
41 #include "BLI_utildefines.h"
42
43 #include "BLF_translation.h"
44
45 #include "BKE_context.h"
46 #include "BKE_screen.h"
47
48 #include "ED_screen.h"
49 #include "ED_util.h"
50
51 #include "WM_types.h"
52 #include "WM_api.h"
53
54 #include "UI_interface.h"
55 #include "UI_resources.h"
56
57 #include "clip_intern.h" /* own include */
58
59 /* ************************ header area region *********************** */
60
61 /************************** properties ******************************/
62
63 ARegion *ED_clip_has_properties_region(ScrArea *sa)
64 {
65         ARegion *ar, *arnew;
66
67         ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
68         if (ar)
69                 return ar;
70
71         /* add subdiv level; after header */
72         ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
73
74         /* is error! */
75         if (ar == NULL)
76                 return NULL;
77
78         arnew = MEM_callocN(sizeof(ARegion), "clip properties region");
79
80         BLI_insertlinkafter(&sa->regionbase, ar, arnew);
81         arnew->regiontype = RGN_TYPE_UI;
82         arnew->alignment = RGN_ALIGN_RIGHT;
83
84         arnew->flag = RGN_FLAG_HIDDEN;
85
86         return arnew;
87 }
88
89 static int properties_poll(bContext *C)
90 {
91         return (CTX_wm_space_clip(C) != NULL);
92 }
93
94 static int properties_exec(bContext *C, wmOperator *UNUSED(op))
95 {
96         ScrArea *sa = CTX_wm_area(C);
97         ARegion *ar = ED_clip_has_properties_region(sa);
98
99         if (ar && ar->alignment != RGN_ALIGN_NONE)
100                 ED_region_toggle_hidden(C, ar);
101
102         return OPERATOR_FINISHED;
103 }
104
105 void CLIP_OT_properties(wmOperatorType *ot)
106 {
107         /* identifiers */
108         ot->name = "Properties";
109         ot->description = "Toggle clip properties panel";
110         ot->idname = "CLIP_OT_properties";
111
112         /* api callbacks */
113         ot->exec = properties_exec;
114         ot->poll = properties_poll;
115 }
116
117 /************************** tools ******************************/
118
119 static ARegion *clip_has_tools_region(ScrArea *sa)
120 {
121         ARegion *ar, *artool = NULL, *arprops = NULL, *arhead;
122
123         for (ar = sa->regionbase.first; ar; ar = ar->next) {
124                 if (ar->regiontype == RGN_TYPE_TOOLS)
125                         artool = ar;
126
127                 if (ar->regiontype == RGN_TYPE_TOOL_PROPS)
128                         arprops = ar;
129         }
130
131         /* tool region hide/unhide also hides props */
132         if (arprops && artool)
133                 return artool;
134
135         if (artool == NULL) {
136                 /* add subdiv level; after header */
137                 arhead = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
138
139                 /* is error! */
140                 if (arhead == NULL)
141                         return NULL;
142
143                 artool = MEM_callocN(sizeof(ARegion), "clip tools region");
144
145                 BLI_insertlinkafter(&sa->regionbase, arhead, artool);
146                 artool->regiontype = RGN_TYPE_TOOLS;
147                 artool->alignment = RGN_ALIGN_LEFT;
148
149                 artool->flag = RGN_FLAG_HIDDEN;
150         }
151
152         if (arprops == NULL) {
153                 /* add extra subdivided region for tool properties */
154                 arprops = MEM_callocN(sizeof(ARegion), "tool props for clip");
155
156                 BLI_insertlinkafter(&sa->regionbase, artool, arprops);
157                 arprops->regiontype = RGN_TYPE_TOOL_PROPS;
158                 arprops->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
159         }
160
161         return artool;
162 }
163
164 static int tools_poll(bContext *C)
165 {
166         return (CTX_wm_space_clip(C) != NULL);
167 }
168
169 static int tools_exec(bContext *C, wmOperator *UNUSED(op))
170 {
171         ScrArea *sa = CTX_wm_area(C);
172         ARegion *ar = clip_has_tools_region(sa);
173
174         if (ar && ar->alignment != RGN_ALIGN_NONE)
175                 ED_region_toggle_hidden(C, ar);
176
177         return OPERATOR_FINISHED;
178 }
179
180 void CLIP_OT_tools(wmOperatorType *ot)
181 {
182         /* identifiers */
183         ot->name = "Tools";
184         ot->description = "Toggle clip tools panel";
185         ot->idname = "CLIP_OT_tools";
186
187         /* api callbacks */
188         ot->exec = tools_exec;
189         ot->poll = tools_poll;
190 }
191
192 /************************** redo panel ******************************/
193
194 static void clip_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOperator *op)
195 {
196         uiLayoutOperatorButs(C, pa->layout, op, NULL, 'V', 0);
197 }
198
199 static void clip_panel_operator_redo_header(const bContext *C, Panel *pa)
200 {
201         wmOperator *op = WM_operator_last_redo(C);
202
203         if (op)
204                 BLI_strncpy(pa->drawname, RNA_struct_ui_name(op->type->srna), sizeof(pa->drawname));
205         else
206                 BLI_strncpy(pa->drawname, IFACE_("Operator"), sizeof(pa->drawname));
207 }
208
209 static void clip_panel_operator_redo_operator(const bContext *C, Panel *pa, wmOperator *op)
210 {
211         if (op->type->flag & OPTYPE_MACRO) {
212                 for (op = op->macro.first; op; op = op->next) {
213                         uiItemL(pa->layout, RNA_struct_ui_name(op->type->srna), ICON_NONE);
214                         clip_panel_operator_redo_operator(C, pa, op);
215                 }
216         }
217         else {
218                 clip_panel_operator_redo_buts(C, pa, op);
219         }
220 }
221
222 /* TODO de-duplicate redo panel functions - campbell */
223 static void clip_panel_operator_redo(const bContext *C, Panel *pa)
224 {
225         wmOperator *op = WM_operator_last_redo(C);
226         ARegion *ar;
227         ARegion *ar1;
228
229         if (op == NULL)
230                 return;
231
232         /* keep in sync with logic in ED_undo_operator_repeat() */
233         ar = CTX_wm_region(C);
234         ar1 = BKE_area_find_region_type(CTX_wm_area(C), RGN_TYPE_WINDOW);
235         if (ar1)
236                 CTX_wm_region_set((bContext *)C, ar1);
237
238         if (WM_operator_poll((bContext *)C, op->type)) {
239                 uiBlock *block = uiLayoutGetBlock(pa->layout);
240
241                 if (!WM_operator_check_ui_enabled(C, op->type->name))
242                         uiLayoutSetEnabled(pa->layout, FALSE);
243
244                 /* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */
245                 uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, op);
246
247                 clip_panel_operator_redo_operator(C, pa, op);
248         }
249
250         /* set region back */
251         CTX_wm_region_set((bContext *)C, ar);
252 }
253
254 void ED_clip_tool_props_register(ARegionType *art)
255 {
256         PanelType *pt;
257
258         pt = MEM_callocN(sizeof(PanelType), "spacetype clip panel last operator");
259         strcpy(pt->idname, "CLIP_PT_last_operator");
260         strcpy(pt->label, "Operator");
261         pt->draw_header = clip_panel_operator_redo_header;
262         pt->draw = clip_panel_operator_redo;
263         BLI_addtail(&art->paneltypes, pt);
264 }