7ed7d399df484adeb7b79be0b30fa4d8639c5c42
[blender.git] / source / blender / editors / space_view3d / view3d_header.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) 2004-2008 Blender Foundation.
19  * All rights reserved.
20  *
21  *
22  * Contributor(s): Blender Foundation
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/space_view3d/view3d_header.c
28  *  \ingroup spview3d
29  */
30
31 #include <string.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34
35 #include "DNA_scene_types.h"
36 #include "DNA_object_types.h"
37 #include "DNA_gpencil_types.h"
38
39 #include "BLI_math_base.h"
40 #include "BLI_utildefines.h"
41
42 #include "BLT_translation.h"
43
44 #include "BKE_context.h"
45 #include "BKE_main.h"
46 #include "BKE_screen.h"
47 #include "BKE_editmesh.h"
48
49 #include "DEG_depsgraph.h"
50
51 #include "RNA_access.h"
52 #include "RNA_define.h"
53 #include "RNA_enum_types.h"
54
55 #include "WM_api.h"
56 #include "WM_types.h"
57
58 #include "ED_mesh.h"
59 #include "ED_undo.h"
60 #include "ED_screen.h"
61
62 #include "UI_interface.h"
63 #include "UI_resources.h"
64
65 #include "view3d_intern.h"
66
67 static void do_view3d_header_buttons(bContext *C, void *arg, int event);
68
69 #define B_SEL_VERT  110
70 #define B_SEL_EDGE  111
71 #define B_SEL_FACE  112
72
73 /* -------------------------------------------------------------------- */
74 /** \name Toggle Matcap Flip Operator
75  * \{ */
76
77 static int toggle_matcap_flip(bContext *C, wmOperator *UNUSED(op))
78 {
79         View3D *v3d = CTX_wm_view3d(C);
80         v3d->shading.flag ^= V3D_SHADING_MATCAP_FLIP_X;
81         ED_view3d_shade_update(CTX_data_main(C), v3d, CTX_wm_area(C));
82         WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
83         return OPERATOR_FINISHED;
84 }
85
86 void VIEW3D_OT_toggle_matcap_flip(wmOperatorType *ot)
87 {
88         /* identifiers */
89         ot->name = "Flip MatCap";
90         ot->description = "Flip MatCap";
91         ot->idname = "VIEW3D_OT_toggle_matcap_flip";
92
93         /* api callbacks */
94         ot->exec = toggle_matcap_flip;
95         ot->poll = ED_operator_view3d_active;
96 }
97
98 /** \} */
99
100
101 static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
102 {
103         wmWindow *win = CTX_wm_window(C);
104         const int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
105
106         /* watch it: if sa->win does not exist, check that when calling direct drawing routines */
107
108         switch (event) {
109                 case B_SEL_VERT:
110                         if (EDBM_selectmode_toggle(C, SCE_SELECT_VERTEX, -1, shift, ctrl)) {
111                                 ED_undo_push(C, "Selectmode Set: Vertex");
112                         }
113                         break;
114                 case B_SEL_EDGE:
115                         if (EDBM_selectmode_toggle(C, SCE_SELECT_EDGE, -1, shift, ctrl)) {
116                                 ED_undo_push(C, "Selectmode Set: Edge");
117                         }
118                         break;
119                 case B_SEL_FACE:
120                         if (EDBM_selectmode_toggle(C, SCE_SELECT_FACE, -1, shift, ctrl)) {
121                                 ED_undo_push(C, "Selectmode Set: Face");
122                         }
123                         break;
124                 default:
125                         break;
126         }
127 }
128
129 void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
130 {
131         Object *obedit = CTX_data_edit_object(C);
132         uiBlock *block = uiLayoutGetBlock(layout);
133
134         UI_block_func_handle_set(block, do_view3d_header_buttons, NULL);
135
136         if (obedit && (obedit->type == OB_MESH)) {
137                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
138                 uiLayout *row;
139
140                 row = uiLayoutRow(layout, true);
141                 block = uiLayoutGetBlock(row);
142                 uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL,
143                                  0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
144                                  TIP_("Vertex select - Shift-Click for multiple modes, Ctrl-Click contracts selection"));
145                 uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL,
146                                  0, 0, ceilf(UI_UNIT_X - UI_DPI_FAC), UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
147                                  TIP_("Edge select - Shift-Click for multiple modes, Ctrl-Click expands/contracts selection"));
148                 uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL,
149                                  0, 0, ceilf(UI_UNIT_X - UI_DPI_FAC), UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
150                                  TIP_("Face select - Shift-Click for multiple modes, Ctrl-Click expands selection"));
151         }
152 }
153
154 static void uiTemplatePaintModeSelection(uiLayout *layout, struct bContext *C)
155 {
156         ViewLayer *view_layer = CTX_data_view_layer(C);
157         Object *ob = OBACT(view_layer);
158
159         /* Gizmos aren't used in paint modes */
160         if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) {
161                 /* masks aren't used for sculpt and particle painting */
162                 PointerRNA meshptr;
163
164                 RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr);
165                 if (ob->mode & (OB_MODE_TEXTURE_PAINT)) {
166                         uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
167                 }
168                 else {
169                         uiLayout *row = uiLayoutRow(layout, true);
170                         uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
171                         if (ob->mode & OB_MODE_WEIGHT_PAINT) {
172                                 uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
173                         }
174                 }
175         }
176 }
177
178 void uiTemplateHeader3D_mode(uiLayout *layout, struct bContext *C)
179 {
180         /* Extracted from: uiTemplateHeader3D */
181         ViewLayer *view_layer = CTX_data_view_layer(C);
182         Object *ob = OBACT(view_layer);
183         Object *obedit = CTX_data_edit_object(C);
184         bGPdata *gpd = CTX_data_gpencil_data(C);
185
186         bool is_paint = (
187                 ob && !(gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
188                 ELEM(ob->mode,
189                      OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT));
190
191         uiTemplateEditModeSelection(layout, C);
192         if ((obedit == NULL) && is_paint) {
193                 uiTemplatePaintModeSelection(layout, C);
194         }
195 }
196
197 void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
198 {
199         bScreen *screen = CTX_wm_screen(C);
200         ScrArea *sa = CTX_wm_area(C);
201         View3D *v3d = sa->spacedata.first;
202         Scene *scene = CTX_data_scene(C);
203         ViewLayer *view_layer = CTX_data_view_layer(C);
204         ToolSettings *ts = CTX_data_tool_settings(C);
205         PointerRNA v3dptr, toolsptr, sceneptr;
206         Object *ob = OBACT(view_layer);
207         Object *obedit = CTX_data_edit_object(C);
208         bGPdata *gpd = CTX_data_gpencil_data(C);
209         uiBlock *block;
210         bool is_paint = (
211                 ob && !(gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
212                 ELEM(ob->mode,
213                      OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT));
214
215         RNA_pointer_create(&screen->id, &RNA_SpaceView3D, v3d, &v3dptr);
216         RNA_pointer_create(&scene->id, &RNA_ToolSettings, ts, &toolsptr);
217         RNA_pointer_create(&scene->id, &RNA_Scene, scene, &sceneptr);
218
219         block = uiLayoutGetBlock(layout);
220         UI_block_func_handle_set(block, do_view3d_header_buttons, NULL);
221
222         /* other buttons: */
223         UI_block_emboss_set(block, UI_EMBOSS);
224
225         /* moved to topbar */
226 #if 0
227         uiLayout *row = uiLayoutRow(layout, true);
228         uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
229         if (!ob || ELEM(ob->mode, OB_MODE_OBJECT, OB_MODE_POSE, OB_MODE_WEIGHT_PAINT)) {
230                 uiItemR(row, &v3dptr, "use_pivot_point_align", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
231         }
232 #endif
233
234         if (obedit == NULL && is_paint) {
235                 /* Currently Python calls this directly. */
236 #if 0
237                 uiTemplatePaintModeSelection(layout, C);
238 #endif
239
240         }
241         else {
242                 /* Moved to popover and topbar. */
243 #if 0
244                 /* Transform widget / gizmos */
245                 row = uiLayoutRow(layout, true);
246                 uiItemR(row, &v3dptr, "show_gizmo", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
247                 uiItemR(row, &sceneptr, "transform_orientation", 0, "", ICON_NONE);
248 #endif
249         }
250
251         if (obedit == NULL && v3d->localvd == NULL) {
252                 /* Scene lock */
253                 uiItemR(layout, &v3dptr, "lock_camera_and_layers", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
254         }
255
256         /* Currently Python calls this directly. */
257 #if 0
258         uiTemplateEditModeSelection(layout, C);
259 #endif
260 }