Merging r46725 through r46963 from trunk into soc-2011-tomato
[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 "MEM_guardedalloc.h"
37
38 #include "BLI_blenlib.h"
39 #include "BLI_utildefines.h"
40
41 #include "BKE_context.h"
42 #include "BKE_screen.h"
43
44 #include "ED_screen.h"
45 #include "ED_util.h"
46
47 #include "WM_types.h"
48 #include "WM_api.h"
49
50 #include "UI_interface.h"
51 #include "UI_resources.h"
52
53 #include "clip_intern.h" /* own include */
54
55 /* ************************ header area region *********************** */
56
57 /************************** properties ******************************/
58
59 ARegion *ED_clip_has_properties_region(ScrArea *sa)
60 {
61         ARegion *ar, *arnew;
62
63         ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
64         if (ar)
65                 return ar;
66
67         /* add subdiv level; after header */
68         ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
69
70         /* is error! */
71         if (ar == NULL)
72                 return NULL;
73
74         arnew = MEM_callocN(sizeof(ARegion), "clip properties region");
75
76         BLI_insertlinkafter(&sa->regionbase, ar, arnew);
77         arnew->regiontype = RGN_TYPE_UI;
78         arnew->alignment = RGN_ALIGN_RIGHT;
79
80         arnew->flag = RGN_FLAG_HIDDEN;
81
82         return arnew;
83 }
84
85 static int properties_poll(bContext *C)
86 {
87         return (CTX_wm_space_clip(C) != NULL);
88 }
89
90 static int properties_exec(bContext *C, wmOperator *UNUSED(op))
91 {
92         ScrArea *sa = CTX_wm_area(C);
93         ARegion *ar = ED_clip_has_properties_region(sa);
94
95         if (ar && ar->alignment != RGN_ALIGN_NONE)
96                 ED_region_toggle_hidden(C, ar);
97
98         return OPERATOR_FINISHED;
99 }
100
101 void CLIP_OT_properties(wmOperatorType *ot)
102 {
103         /* identifiers */
104         ot->name = "Properties";
105         ot->description = "Toggle clip properties panel";
106         ot->idname = "CLIP_OT_properties";
107
108         /* api callbacks */
109         ot->exec = properties_exec;
110         ot->poll = properties_poll;
111 }
112
113 /************************** tools ******************************/
114
115 static ARegion *clip_has_tools_region(ScrArea *sa)
116 {
117         ARegion *ar, *artool = NULL, *arprops = NULL, *arhead;
118
119         for (ar = sa->regionbase.first; ar; ar = ar->next) {
120                 if (ar->regiontype == RGN_TYPE_TOOLS)
121                         artool = ar;
122
123                 if (ar->regiontype == RGN_TYPE_TOOL_PROPS)
124                         arprops = ar;
125         }
126
127         /* tool region hide/unhide also hides props */
128         if (arprops && artool)
129                 return artool;
130
131         if (artool == NULL) {
132                 /* add subdiv level; after header */
133                 arhead = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
134
135                 /* is error! */
136                 if (arhead == NULL)
137                         return NULL;
138
139                 artool = MEM_callocN(sizeof(ARegion), "clip tools region");
140
141                 BLI_insertlinkafter(&sa->regionbase, arhead, artool);
142                 artool->regiontype = RGN_TYPE_TOOLS;
143                 artool->alignment = RGN_ALIGN_LEFT;
144
145                 artool->flag = RGN_FLAG_HIDDEN;
146         }
147
148         if (arprops == NULL) {
149                 /* add extra subdivided region for tool properties */
150                 arprops = MEM_callocN(sizeof(ARegion), "tool props for clip");
151
152                 BLI_insertlinkafter(&sa->regionbase, artool, arprops);
153                 arprops->regiontype = RGN_TYPE_TOOL_PROPS;
154                 arprops->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
155         }
156
157         return artool;
158 }
159
160 static int tools_poll(bContext *C)
161 {
162         return (CTX_wm_space_clip(C) != NULL);
163 }
164
165 static int tools_exec(bContext *C, wmOperator *UNUSED(op))
166 {
167         ScrArea *sa = CTX_wm_area(C);
168         ARegion *ar = clip_has_tools_region(sa);
169
170         if (ar && ar->alignment != RGN_ALIGN_NONE)
171                 ED_region_toggle_hidden(C, ar);
172
173         return OPERATOR_FINISHED;
174 }
175
176 void CLIP_OT_tools(wmOperatorType *ot)
177 {
178         /* identifiers */
179         ot->name = "Tools";
180         ot->description = "Toggle clip tools panel";
181         ot->idname = "CLIP_OT_tools";
182
183         /* api callbacks */
184         ot->exec = tools_exec;
185         ot->poll = tools_poll;
186 }
187
188 /************************** redo panel ******************************/
189
190 static void clip_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOperator *op)
191 {
192         uiLayoutOperatorButs(C, pa->layout, op, NULL, 'V', 0);
193 }
194
195 static void clip_panel_operator_redo_header(const bContext *C, Panel *pa)
196 {
197         wmOperator *op = WM_operator_last_redo(C);
198
199         if (op)
200                 BLI_strncpy(pa->drawname, op->type->name, sizeof(pa->drawname));
201         else
202                 BLI_strncpy(pa->drawname, "Operator", sizeof(pa->drawname));
203 }
204
205 static void clip_panel_operator_redo_operator(const bContext *C, Panel *pa, wmOperator *op)
206 {
207         if (op->type->flag & OPTYPE_MACRO) {
208                 for (op = op->macro.first; op; op = op->next) {
209                         uiItemL(pa->layout, op->type->name, ICON_NONE);
210                         clip_panel_operator_redo_operator(C, pa, op);
211                 }
212         }
213         else {
214                 clip_panel_operator_redo_buts(C, pa, op);
215         }
216 }
217
218 /* TODO de-duplicate redo panel functions - campbell */
219 static void clip_panel_operator_redo(const bContext *C, Panel *pa)
220 {
221         wmOperator *op = WM_operator_last_redo(C);
222         uiBlock *block;
223
224         if (op == NULL)
225                 return;
226
227         if (WM_operator_poll((bContext*)C, op->type) == 0)
228                 return;
229
230         block = uiLayoutGetBlock(pa->layout);
231
232         if (!WM_operator_check_ui_enabled(C, op->type->name))
233                 uiLayoutSetEnabled(pa->layout, 0);
234
235         /* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */
236         uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, op);
237
238         clip_panel_operator_redo_operator(C, pa, op);
239 }
240
241 void ED_clip_tool_props_register(ARegionType *art)
242 {
243         PanelType *pt;
244
245         pt = MEM_callocN(sizeof(PanelType), "spacetype clip panel last operator");
246         strcpy(pt->idname, "CLIP_PT_last_operator");
247         strcpy(pt->label, "Operator");
248         pt->draw_header = clip_panel_operator_redo_header;
249         pt->draw = clip_panel_operator_redo;
250         BLI_addtail(&art->paneltypes, pt);
251 }