Merge branch 'blender-v2.90-release' into master
[blender.git] / source / blender / editors / space_view3d / view3d_header.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2004-2008 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup spview3d
22  */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "DNA_gpencil_types.h"
29 #include "DNA_object_types.h"
30 #include "DNA_scene_types.h"
31
32 #include "BLI_math_base.h"
33 #include "BLI_utildefines.h"
34
35 #include "BLT_translation.h"
36
37 #include "BKE_context.h"
38 #include "BKE_editmesh.h"
39
40 #include "DEG_depsgraph.h"
41
42 #include "RNA_access.h"
43 #include "RNA_define.h"
44 #include "RNA_enum_types.h"
45
46 #include "WM_api.h"
47 #include "WM_types.h"
48
49 #include "ED_mesh.h"
50 #include "ED_screen.h"
51 #include "ED_undo.h"
52
53 #include "UI_interface.h"
54 #include "UI_resources.h"
55
56 #include "view3d_intern.h"
57
58 static void do_view3d_header_buttons(bContext *C, void *arg, int event);
59
60 #define B_SEL_VERT 110
61 #define B_SEL_EDGE 111
62 #define B_SEL_FACE 112
63
64 /* -------------------------------------------------------------------- */
65 /** \name Toggle Matcap Flip Operator
66  * \{ */
67
68 static int toggle_matcap_flip(bContext *C, wmOperator *UNUSED(op))
69 {
70   View3D *v3d = CTX_wm_view3d(C);
71
72   if (v3d) {
73     v3d->shading.flag ^= V3D_SHADING_MATCAP_FLIP_X;
74     ED_view3d_shade_update(CTX_data_main(C), v3d, CTX_wm_area(C));
75     WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
76   }
77   else {
78     Scene *scene = CTX_data_scene(C);
79     scene->display.shading.flag ^= V3D_SHADING_MATCAP_FLIP_X;
80     DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
81     WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
82   }
83
84   return OPERATOR_FINISHED;
85 }
86
87 void VIEW3D_OT_toggle_matcap_flip(wmOperatorType *ot)
88 {
89   /* identifiers */
90   ot->name = "Flip MatCap";
91   ot->description = "Flip MatCap";
92   ot->idname = "VIEW3D_OT_toggle_matcap_flip";
93
94   /* api callbacks */
95   ot->exec = toggle_matcap_flip;
96 }
97
98 /** \} */
99
100 /* -------------------------------------------------------------------- */
101 /** \name UI Templates
102  * \{ */
103
104 static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
105 {
106   wmWindow *win = CTX_wm_window(C);
107   const int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
108
109   /* watch it: if area->win does not exist, check that when calling direct drawing routines */
110
111   switch (event) {
112     case B_SEL_VERT:
113       if (EDBM_selectmode_toggle_multi(C, SCE_SELECT_VERTEX, -1, shift, ctrl)) {
114         ED_undo_push(C, "Selectmode Set: Vertex");
115       }
116       break;
117     case B_SEL_EDGE:
118       if (EDBM_selectmode_toggle_multi(C, SCE_SELECT_EDGE, -1, shift, ctrl)) {
119         ED_undo_push(C, "Selectmode Set: Edge");
120       }
121       break;
122     case B_SEL_FACE:
123       if (EDBM_selectmode_toggle_multi(C, SCE_SELECT_FACE, -1, shift, ctrl)) {
124         ED_undo_push(C, "Selectmode Set: Face");
125       }
126       break;
127     default:
128       break;
129   }
130 }
131
132 void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
133 {
134   Object *obedit = CTX_data_edit_object(C);
135   uiBlock *block = uiLayoutGetBlock(layout);
136
137   UI_block_func_handle_set(block, do_view3d_header_buttons, NULL);
138
139   if (obedit && (obedit->type == OB_MESH)) {
140     BMEditMesh *em = BKE_editmesh_from_object(obedit);
141     uiLayout *row;
142     uiBut *but;
143
144     row = uiLayoutRow(layout, true);
145     block = uiLayoutGetBlock(row);
146     but = uiDefIconButBitS(
147         block,
148         UI_BTYPE_TOGGLE,
149         SCE_SELECT_VERTEX,
150         B_SEL_VERT,
151         ICON_VERTEXSEL,
152         0,
153         0,
154         UI_UNIT_X,
155         UI_UNIT_Y,
156         &em->selectmode,
157         1.0,
158         0.0,
159         0,
160         0,
161         TIP_("Vertex select - Shift-Click for multiple modes, Ctrl-Click contracts selection"));
162     UI_but_flag_disable(but, UI_BUT_UNDO);
163     but = uiDefIconButBitS(
164         block,
165         UI_BTYPE_TOGGLE,
166         SCE_SELECT_EDGE,
167         B_SEL_EDGE,
168         ICON_EDGESEL,
169         0,
170         0,
171         ceilf(UI_UNIT_X - U.pixelsize),
172         UI_UNIT_Y,
173         &em->selectmode,
174         1.0,
175         0.0,
176         0,
177         0,
178         TIP_("Edge select - Shift-Click for multiple modes, "
179              "Ctrl-Click expands/contracts selection depending on the current mode"));
180     UI_but_flag_disable(but, UI_BUT_UNDO);
181     but = uiDefIconButBitS(
182         block,
183         UI_BTYPE_TOGGLE,
184         SCE_SELECT_FACE,
185         B_SEL_FACE,
186         ICON_FACESEL,
187         0,
188         0,
189         ceilf(UI_UNIT_X - U.pixelsize),
190         UI_UNIT_Y,
191         &em->selectmode,
192         1.0,
193         0.0,
194         0,
195         0,
196         TIP_("Face select - Shift-Click for multiple modes, Ctrl-Click expands selection"));
197     UI_but_flag_disable(but, UI_BUT_UNDO);
198   }
199 }
200
201 static void uiTemplatePaintModeSelection(uiLayout *layout, struct bContext *C)
202 {
203   ViewLayer *view_layer = CTX_data_view_layer(C);
204   Object *ob = OBACT(view_layer);
205
206   /* Gizmos aren't used in paint modes */
207   if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) {
208     /* masks aren't used for sculpt and particle painting */
209     PointerRNA meshptr;
210
211     RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr);
212     if (ob->mode & OB_MODE_TEXTURE_PAINT) {
213       uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
214     }
215     else {
216       uiLayout *row = uiLayoutRow(layout, true);
217       uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
218       uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
219     }
220   }
221 }
222
223 void uiTemplateHeader3D_mode(uiLayout *layout, struct bContext *C)
224 {
225   ViewLayer *view_layer = CTX_data_view_layer(C);
226   Object *ob = OBACT(view_layer);
227   Object *obedit = CTX_data_edit_object(C);
228   bGPdata *gpd = CTX_data_gpencil_data(C);
229
230   bool is_paint = (ob && !(gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
231                    ELEM(ob->mode,
232                         OB_MODE_SCULPT,
233                         OB_MODE_VERTEX_PAINT,
234                         OB_MODE_WEIGHT_PAINT,
235                         OB_MODE_TEXTURE_PAINT));
236
237   uiTemplateEditModeSelection(layout, C);
238   if ((obedit == NULL) && is_paint) {
239     uiTemplatePaintModeSelection(layout, C);
240   }
241 }
242
243 /** \} */