d99681fcd5b778db7916d0a034f2d119d017bb5d
[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 <string.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27
28 #include "DNA_scene_types.h"
29 #include "DNA_object_types.h"
30 #include "DNA_gpencil_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_undo.h"
51 #include "ED_screen.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         v3d->shading.flag ^= V3D_SHADING_MATCAP_FLIP_X;
72         ED_view3d_shade_update(CTX_data_main(C), v3d, CTX_wm_area(C));
73         WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
74         return OPERATOR_FINISHED;
75 }
76
77 void VIEW3D_OT_toggle_matcap_flip(wmOperatorType *ot)
78 {
79         /* identifiers */
80         ot->name = "Flip MatCap";
81         ot->description = "Flip MatCap";
82         ot->idname = "VIEW3D_OT_toggle_matcap_flip";
83
84         /* api callbacks */
85         ot->exec = toggle_matcap_flip;
86         ot->poll = ED_operator_view3d_active;
87 }
88
89 /** \} */
90
91
92 static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event)
93 {
94         wmWindow *win = CTX_wm_window(C);
95         const int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
96
97         /* watch it: if sa->win does not exist, check that when calling direct drawing routines */
98
99         switch (event) {
100                 case B_SEL_VERT:
101                         if (EDBM_selectmode_toggle(C, SCE_SELECT_VERTEX, -1, shift, ctrl)) {
102                                 ED_undo_push(C, "Selectmode Set: Vertex");
103                         }
104                         break;
105                 case B_SEL_EDGE:
106                         if (EDBM_selectmode_toggle(C, SCE_SELECT_EDGE, -1, shift, ctrl)) {
107                                 ED_undo_push(C, "Selectmode Set: Edge");
108                         }
109                         break;
110                 case B_SEL_FACE:
111                         if (EDBM_selectmode_toggle(C, SCE_SELECT_FACE, -1, shift, ctrl)) {
112                                 ED_undo_push(C, "Selectmode Set: Face");
113                         }
114                         break;
115                 default:
116                         break;
117         }
118 }
119
120 void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
121 {
122         Object *obedit = CTX_data_edit_object(C);
123         uiBlock *block = uiLayoutGetBlock(layout);
124
125         UI_block_func_handle_set(block, do_view3d_header_buttons, NULL);
126
127         if (obedit && (obedit->type == OB_MESH)) {
128                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
129                 uiLayout *row;
130
131                 row = uiLayoutRow(layout, true);
132                 block = uiLayoutGetBlock(row);
133                 uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL,
134                                  0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
135                                  TIP_("Vertex select - Shift-Click for multiple modes, Ctrl-Click contracts selection"));
136                 uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL,
137                                  0, 0, ceilf(UI_UNIT_X - UI_DPI_FAC), UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
138                                  TIP_("Edge select - Shift-Click for multiple modes, Ctrl-Click expands/contracts selection"));
139                 uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL,
140                                  0, 0, ceilf(UI_UNIT_X - UI_DPI_FAC), UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
141                                  TIP_("Face select - Shift-Click for multiple modes, Ctrl-Click expands selection"));
142         }
143 }
144
145 static void uiTemplatePaintModeSelection(uiLayout *layout, struct bContext *C)
146 {
147         ViewLayer *view_layer = CTX_data_view_layer(C);
148         Object *ob = OBACT(view_layer);
149
150         /* Gizmos aren't used in paint modes */
151         if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) {
152                 /* masks aren't used for sculpt and particle painting */
153                 PointerRNA meshptr;
154
155                 RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr);
156                 if (ob->mode & (OB_MODE_TEXTURE_PAINT)) {
157                         uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
158                 }
159                 else {
160                         uiLayout *row = uiLayoutRow(layout, true);
161                         uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
162                         uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
163                 }
164         }
165 }
166
167 void uiTemplateHeader3D_mode(uiLayout *layout, struct bContext *C)
168 {
169         ViewLayer *view_layer = CTX_data_view_layer(C);
170         Object *ob = OBACT(view_layer);
171         Object *obedit = CTX_data_edit_object(C);
172         bGPdata *gpd = CTX_data_gpencil_data(C);
173
174         bool is_paint = (
175                 ob && !(gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
176                 ELEM(ob->mode,
177                      OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT));
178
179         uiTemplateEditModeSelection(layout, C);
180         if ((obedit == NULL) && is_paint) {
181                 uiTemplatePaintModeSelection(layout, C);
182         }
183 }