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 
17 /** \file
18  * \ingroup edinterface
19  *
20  * A special set of icons to represent input devices,
21  * this is a mix of text (via fonts) and a handful of custom glyphs for special keys.
22  *
23  * Event codes are used as identifiers.
24  */
25 
26 #include <math.h>
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include "MEM_guardedalloc.h"
31 
32 #include "GPU_batch.h"
33 #include "GPU_immediate.h"
34 #include "GPU_state.h"
35 
36 #include "BLI_blenlib.h"
37 #include "BLI_math_vector.h"
38 #include "BLI_utildefines.h"
39 
40 #include "DNA_brush_types.h"
41 #include "DNA_curve_types.h"
42 #include "DNA_dynamicpaint_types.h"
43 #include "DNA_object_types.h"
44 #include "DNA_screen_types.h"
45 #include "DNA_space_types.h"
46 #include "DNA_workspace_types.h"
47 
48 #include "RNA_access.h"
49 #include "RNA_enum_types.h"
50 
51 #include "BKE_appdir.h"
52 #include "BKE_icons.h"
53 #include "BKE_studiolight.h"
54 
55 #include "IMB_imbuf.h"
56 #include "IMB_imbuf_types.h"
57 #include "IMB_thumbs.h"
58 
59 #include "BLF_api.h"
60 
61 #include "DEG_depsgraph.h"
62 
63 #include "DRW_engine.h"
64 
65 #include "ED_datafiles.h"
66 #include "ED_keyframes_draw.h"
67 #include "ED_render.h"
68 
69 #include "UI_interface.h"
70 #include "UI_interface_icons.h"
71 
72 #include "WM_api.h"
73 #include "WM_types.h"
74 
75 #include "interface_intern.h"
76 
icon_draw_rect_input_text(const rctf * rect,const float color[4],const char * str,int font_size)77 static void icon_draw_rect_input_text(const rctf *rect,
78                                       const float color[4],
79                                       const char *str,
80                                       int font_size)
81 {
82   BLF_batch_draw_flush();
83   const int font_id = BLF_default();
84   BLF_color4fv(font_id, color);
85   BLF_size(font_id, font_size * U.pixelsize, U.dpi);
86   float width, height;
87   BLF_width_and_height(font_id, str, BLF_DRAW_STR_DUMMY_MAX, &width, &height);
88   const float x = rect->xmin + (((rect->xmax - rect->xmin) - width) / 2.0f);
89   const float y = rect->ymin + (((rect->ymax - rect->ymin) - height) / 2.0f);
90   BLF_position(font_id, x, y, 0.0f);
91   BLF_draw(font_id, str, BLF_DRAW_STR_DUMMY_MAX);
92   BLF_batch_draw_flush();
93 }
94 
icon_draw_rect_input_symbol(const rctf * rect,const float color[4],const char * str)95 static void icon_draw_rect_input_symbol(const rctf *rect, const float color[4], const char *str)
96 {
97   BLF_batch_draw_flush();
98   const int font_id = blf_mono_font;
99   BLF_color4fv(font_id, color);
100   BLF_size(font_id, 19 * U.pixelsize, U.dpi);
101   const float x = rect->xmin + (2.0f * U.pixelsize);
102   const float y = rect->ymin + (1.0f * U.pixelsize);
103   BLF_position(font_id, x, y, 0.0f);
104   BLF_draw(font_id, str, BLF_DRAW_STR_DUMMY_MAX);
105   BLF_batch_draw_flush();
106 }
107 
icon_draw_rect_input(float x,float y,int w,int h,float UNUSED (alpha),short event_type,short UNUSED (event_value))108 void icon_draw_rect_input(float x,
109                           float y,
110                           int w,
111                           int h,
112                           float UNUSED(alpha),
113                           short event_type,
114                           short UNUSED(event_value))
115 {
116   float color[4];
117   GPU_line_width(1.0f);
118   UI_GetThemeColor4fv(TH_TEXT, color);
119   UI_draw_roundbox_corner_set(UI_CNR_ALL);
120   UI_draw_roundbox_aa(
121       false, (int)x - U.pixelsize, (int)y, (int)(x + w), (int)(y + h), 3.0f * U.pixelsize, color);
122 
123   const enum {
124     UNIX,
125     MACOS,
126     MSWIN,
127   } platform =
128 
129 #if defined(__APPLE__)
130       MACOS
131 #elif defined(_WIN32)
132       MSWIN
133 #else
134       UNIX
135 #endif
136       ;
137 
138   const rctf rect = {
139       .xmin = x,
140       .ymin = y,
141       .xmax = x + w,
142       .ymax = y + h,
143   };
144 
145   if ((event_type >= EVT_AKEY) && (event_type <= EVT_ZKEY)) {
146     const char str[2] = {'A' + (event_type - EVT_AKEY), '\0'};
147     icon_draw_rect_input_text(&rect, color, str, 13);
148   }
149   else if ((event_type >= EVT_F1KEY) && (event_type <= EVT_F12KEY)) {
150     char str[4];
151     SNPRINTF(str, "F%d", 1 + (event_type - EVT_F1KEY));
152     icon_draw_rect_input_text(&rect, color, str, event_type > EVT_F9KEY ? 8 : 10);
153   }
154   else if (event_type == EVT_LEFTSHIFTKEY) {
155     icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x87, 0xa7, 0x0});
156   }
157   else if (event_type == EVT_LEFTCTRLKEY) {
158     if (platform == MACOS) {
159       icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x8c, 0x83, 0x0});
160     }
161     else {
162       icon_draw_rect_input_text(&rect, color, "Ctrl", 9);
163     }
164   }
165   else if (event_type == EVT_LEFTALTKEY) {
166     if (platform == MACOS) {
167       icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x8c, 0xa5, 0x0});
168     }
169     else {
170       icon_draw_rect_input_text(&rect, color, "Alt", 10);
171     }
172   }
173   else if (event_type == EVT_OSKEY) {
174     if (platform == MACOS) {
175       icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x8c, 0x98, 0x0});
176     }
177     else if (platform == MSWIN) {
178       icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x9d, 0x96, 0x0});
179     }
180     else {
181       icon_draw_rect_input_text(&rect, color, "OS", 10);
182     }
183   }
184   else if (event_type == EVT_DELKEY) {
185     icon_draw_rect_input_text(&rect, color, "Del", 9);
186   }
187   else if (event_type == EVT_TABKEY) {
188     icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0xad, 0xbe, 0x0});
189   }
190   else if (event_type == EVT_HOMEKEY) {
191     icon_draw_rect_input_text(&rect, color, "Home", 6);
192   }
193   else if (event_type == EVT_ENDKEY) {
194     icon_draw_rect_input_text(&rect, color, "End", 8);
195   }
196   else if (event_type == EVT_RETKEY) {
197     icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x8f, 0x8e, 0x0});
198   }
199   else if (event_type == EVT_ESCKEY) {
200     if (platform == MACOS) {
201       icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x8e, 0x8b, 0x0});
202     }
203     else {
204       icon_draw_rect_input_text(&rect, color, "Esc", 8);
205     }
206   }
207   else if (event_type == EVT_PAGEUPKEY) {
208     icon_draw_rect_input_text(&rect, color, (const char[]){'P', 0xe2, 0x86, 0x91, 0x0}, 8);
209   }
210   else if (event_type == EVT_PAGEDOWNKEY) {
211     icon_draw_rect_input_text(&rect, color, (const char[]){'P', 0xe2, 0x86, 0x93, 0x0}, 8);
212   }
213   else if (event_type == EVT_LEFTARROWKEY) {
214     icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x86, 0x90, 0x0});
215   }
216   else if (event_type == EVT_UPARROWKEY) {
217     icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x86, 0x91, 0x0});
218   }
219   else if (event_type == EVT_RIGHTARROWKEY) {
220     icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x86, 0x92, 0x0});
221   }
222   else if (event_type == EVT_DOWNARROWKEY) {
223     icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x86, 0x93, 0x0});
224   }
225   else if (event_type == EVT_SPACEKEY) {
226     icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x90, 0xa3, 0x0});
227   }
228 }
229