~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/editors/interface/interface_regions.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
 
1
/*
2
2
 * ***** BEGIN GPL LICENSE BLOCK *****
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or
23
23
 * ***** END GPL LICENSE BLOCK *****
24
24
 */
25
25
 
 
26
/** \file blender/editors/interface/interface_regions.c
 
27
 *  \ingroup edinterface
 
28
 */
 
29
 
 
30
 
26
31
 
27
32
#include <stdarg.h>
28
33
#include <stdlib.h>
29
34
#include <string.h>
 
35
#include <assert.h>
30
36
 
31
37
#include "MEM_guardedalloc.h"
32
38
 
34
40
 
35
41
#include "BLI_math.h"
36
42
#include "BLI_blenlib.h"
 
43
#include "BLI_utildefines.h"
37
44
#include "BLI_dynstr.h"
38
45
#include "BLI_ghash.h"
39
46
 
40
47
#include "BKE_context.h"
41
 
#include "BKE_icons.h"
42
 
#include "BKE_report.h"
43
48
#include "BKE_screen.h"
44
 
#include "BKE_texture.h"
45
 
#include "BKE_utildefines.h"
46
49
 
47
50
#include "WM_api.h"
48
51
#include "WM_types.h"
59
62
#include "UI_view2d.h"
60
63
 
61
64
#include "BLF_api.h"
 
65
#include "BLF_translation.h"
62
66
 
63
67
#include "ED_screen.h"
64
68
 
65
69
#include "interface_intern.h"
66
70
 
67
 
#define MENU_BUTTON_HEIGHT      20
68
 
#define MENU_SEPR_HEIGHT        6
69
 
#define B_NOP                   -1
70
 
#define MENU_SHADOW_SIDE        8
71
 
#define MENU_SHADOW_BOTTOM      10
72
 
#define MENU_TOP                        8
 
71
#define MENU_SEPR_HEIGHT    6
 
72
#define B_NOP               -1
 
73
#define MENU_SHADOW_SIDE    8
 
74
#define MENU_SHADOW_BOTTOM  10
 
75
#define MENU_TOP            8
73
76
 
74
77
/*********************** Menu Data Parsing ********************* */
75
78
 
76
79
typedef struct MenuEntry {
77
 
        char *str;
 
80
        const char *str;
78
81
        int retval;
79
82
        int icon;
80
83
        int sepr;
81
84
} MenuEntry;
82
85
 
83
86
typedef struct MenuData {
84
 
        char *instr;
85
 
        char *title;
 
87
        const char *instr;
 
88
        const char *title;
86
89
        int titleicon;
87
90
        
88
91
        MenuEntry *items;
89
92
        int nitems, itemssize;
90
93
} MenuData;
91
94
 
92
 
static MenuData *menudata_new(char *instr)
 
95
static MenuData *menudata_new(const char *instr)
93
96
{
94
 
        MenuData *md= MEM_mallocN(sizeof(*md), "MenuData");
 
97
        MenuData *md = MEM_mallocN(sizeof(*md), "MenuData");
95
98
 
96
 
        md->instr= instr;
97
 
        md->title= NULL;
98
 
        md->titleicon= 0;
99
 
        md->items= NULL;
100
 
        md->nitems= md->itemssize= 0;
 
99
        md->instr = instr;
 
100
        md->title = NULL;
 
101
        md->titleicon = 0;
 
102
        md->items = NULL;
 
103
        md->nitems = md->itemssize = 0;
101
104
        
102
105
        return md;
103
106
}
104
107
 
105
 
static void menudata_set_title(MenuData *md, char *title, int titleicon)
 
108
static void menudata_set_title(MenuData *md, const char *title, int titleicon)
106
109
{
107
110
        if (!md->title)
108
 
                md->title= title;
 
111
                md->title = title;
109
112
        if (!md->titleicon)
110
 
                md->titleicon= titleicon;
 
113
                md->titleicon = titleicon;
111
114
}
112
115
 
113
 
static void menudata_add_item(MenuData *md, char *str, int retval, int icon, int sepr)
 
116
static void menudata_add_item(MenuData *md, const char *str, int retval, int icon, int sepr)
114
117
{
115
 
        if (md->nitems==md->itemssize) {
116
 
                int nsize= md->itemssize?(md->itemssize<<1):1;
117
 
                MenuEntry *oitems= md->items;
 
118
        if (md->nitems == md->itemssize) {
 
119
                int nsize = md->itemssize ? (md->itemssize << 1) : 1;
 
120
                MenuEntry *oitems = md->items;
118
121
                
119
 
                md->items= MEM_mallocN(nsize*sizeof(*md->items), "md->items");
 
122
                md->items = MEM_mallocN(nsize * sizeof(*md->items), "md->items");
120
123
                if (oitems) {
121
 
                        memcpy(md->items, oitems, md->nitems*sizeof(*md->items));
 
124
                        memcpy(md->items, oitems, md->nitems * sizeof(*md->items));
122
125
                        MEM_freeN(oitems);
123
126
                }
124
127
                
125
 
                md->itemssize= nsize;
 
128
                md->itemssize = nsize;
126
129
        }
127
130
        
128
 
        md->items[md->nitems].str= str;
129
 
        md->items[md->nitems].retval= retval;
130
 
        md->items[md->nitems].icon= icon;
131
 
        md->items[md->nitems].sepr= sepr;
 
131
        md->items[md->nitems].str = str;
 
132
        md->items[md->nitems].retval = retval;
 
133
        md->items[md->nitems].icon = icon;
 
134
        md->items[md->nitems].sepr = sepr;
132
135
        md->nitems++;
133
136
}
134
137
 
135
 
void menudata_free(MenuData *md)
 
138
static void menudata_free(MenuData *md)
136
139
{
137
 
        MEM_freeN(md->instr);
138
 
        if (md->items)
 
140
        MEM_freeN((void *)md->instr);
 
141
        if (md->items) {
139
142
                MEM_freeN(md->items);
 
143
        }
140
144
        MEM_freeN(md);
141
145
}
142
146
 
143
 
        /**
144
 
         * Parse menu description strings, string is of the
145
 
         * form "[sss%t|]{(sss[%xNN]|), (%l|), (sss%l|)}", ssss%t indicates the
146
 
         * menu title, sss or sss%xNN indicates an option, 
147
 
         * if %xNN is given then NN is the return value if
148
 
         * that option is selected otherwise the return value
149
 
         * is the index of the option (starting with 1). %l
150
 
         * indicates a seperator, sss%l indicates a label and
151
 
         * new column.
152
 
         * 
153
 
         * @param str String to be parsed.
154
 
         * @retval new menudata structure, free with menudata_free()
155
 
         */
156
 
MenuData *decompose_menu_string(char *str) 
 
147
/**
 
148
 * Parse menu description strings, string is of the
 
149
 * form "[sss%t|]{(sss[%xNN]|), (%l|), (sss%l|)}", ssss%t indicates the
 
150
 * menu title, sss or sss%xNN indicates an option,
 
151
 * if %xNN is given then NN is the return value if
 
152
 * that option is selected otherwise the return value
 
153
 * is the index of the option (starting with 1). %l
 
154
 * indicates a seperator, sss%l indicates a label and
 
155
 * new column.
 
156
 *
 
157
 * \param str String to be parsed.
 
158
 * \retval new menudata structure, free with menudata_free()
 
159
 */
 
160
static MenuData *decompose_menu_string(const char *str)
157
161
{
158
 
        char *instr= BLI_strdup(str);
159
 
        MenuData *md= menudata_new(instr);
160
 
        char *nitem= NULL, *s= instr;
161
 
        int nicon=0, nretval= 1, nitem_is_title= 0, nitem_is_sepr= 0;
 
162
        char *instr = BLI_strdup(str);
 
163
        MenuData *md = menudata_new(instr);
 
164
        const char *nitem = NULL;
 
165
        char *s = instr;
 
166
        int nicon = 0, nretval = 1, nitem_is_title = 0, nitem_is_sepr = 0;
162
167
        
163
168
        while (1) {
164
 
                char c= *s;
165
 
 
166
 
                if (c=='%') {
167
 
                        if (s[1]=='x') {
168
 
                                nretval= atoi(s+2);
169
 
 
170
 
                                *s= '\0';
171
 
                                s++;
172
 
                        } else if (s[1]=='t') {
173
 
                                nitem_is_title= 1;
174
 
 
175
 
                                *s= '\0';
176
 
                                s++;
177
 
                        } else if (s[1]=='l') {
178
 
                                nitem_is_sepr= 1;
179
 
                                if(!nitem) nitem= "";
180
 
 
181
 
                                *s= '\0';
182
 
                                s++;
183
 
                        } else if (s[1]=='i') {
184
 
                                nicon= atoi(s+2);
 
169
                char c = *s;
 
170
 
 
171
                if (c == '%') {
 
172
                        if (s[1] == 'x') {
 
173
                                nretval = atoi(s + 2);
 
174
 
 
175
                                *s = '\0';
 
176
                                s++;
 
177
                        }
 
178
                        else if (s[1] == 't') {
 
179
                                nitem_is_title = (s != instr); /* check for empty title */
 
180
 
 
181
                                *s = '\0';
 
182
                                s++;
 
183
                        }
 
184
                        else if (s[1] == 'l') {
 
185
                                nitem_is_sepr = 1;
 
186
                                if (!nitem) nitem = "";
 
187
 
 
188
                                *s = '\0';
 
189
                                s++;
 
190
                        }
 
191
                        else if (s[1] == 'i') {
 
192
                                nicon = atoi(s + 2);
185
193
                                
186
 
                                *s= '\0';
 
194
                                *s = '\0';
187
195
                                s++;
188
196
                        }
189
 
                } else if (c=='|' || c == '\n' || c=='\0') {
 
197
                }
 
198
                else if (c == '|' || c == '\n' || c == '\0') {
190
199
                        if (nitem) {
191
 
                                *s= '\0';
 
200
                                *s = '\0';
192
201
 
193
 
                                if(nitem_is_title) {
 
202
                                if (nitem_is_title) {
194
203
                                        menudata_set_title(md, nitem, nicon);
195
 
                                        nitem_is_title= 0;
 
204
                                        nitem_is_title = 0;
196
205
                                }
197
 
                                else if(nitem_is_sepr) {
 
206
                                else if (nitem_is_sepr) {
198
207
                                        /* prevent separator to get a value */
199
208
                                        menudata_add_item(md, nitem, -1, nicon, 1);
200
 
                                        nretval= md->nitems+1;
201
 
                                        nitem_is_sepr= 0;
 
209
                                        nretval = md->nitems + 1;
 
210
                                        nitem_is_sepr = 0;
202
211
                                }
203
212
                                else {
204
213
                                        menudata_add_item(md, nitem, nretval, nicon, 0);
205
 
                                        nretval= md->nitems+1;
 
214
                                        nretval = md->nitems + 1;
206
215
                                } 
207
216
                                
208
 
                                nitem= NULL;
209
 
                                nicon= 0;
 
217
                                nitem = NULL;
 
218
                                nicon = 0;
210
219
                        }
211
220
                        
212
 
                        if (c=='\0')
 
221
                        if (c == '\0') {
213
222
                                break;
214
 
                } else if (!nitem)
215
 
                        nitem= s;
216
 
                
 
223
                        }
 
224
                }
 
225
                else if (!nitem) {
 
226
                        nitem = s;
 
227
                }
 
228
 
217
229
                s++;
218
230
        }
219
231
        
225
237
        MenuData *md;
226
238
        int i;
227
239
        
228
 
        md= decompose_menu_string(but->str);
229
 
        for (i=0; i<md->nitems; i++)
230
 
                if (md->items[i].retval==value)
231
 
                        strcpy(but->drawstr, md->items[i].str);
 
240
        md = decompose_menu_string(but->str);
 
241
        for (i = 0; i < md->nitems; i++) {
 
242
                if (md->items[i].retval == value) {
 
243
                        BLI_strncpy(but->drawstr, md->items[i].str, sizeof(but->drawstr));
 
244
                        break;
 
245
                }
 
246
        }
232
247
        
233
248
        menudata_free(md);
234
249
}
236
251
int ui_step_name_menu(uiBut *but, int step)
237
252
{
238
253
        MenuData *md;
239
 
        int value= ui_get_but_val(but);
 
254
        int value = ui_get_but_val(but);
240
255
        int i;
241
256
        
242
 
        md= decompose_menu_string(but->str);
243
 
        for (i=0; i<md->nitems; i++)
244
 
                if (md->items[i].retval==value)
 
257
        md = decompose_menu_string(but->str);
 
258
        for (i = 0; i < md->nitems; i++)
 
259
                if (md->items[i].retval == value)
245
260
                        break;
246
261
        
247
 
        if(step==1) {
 
262
        if (step == 1) {
248
263
                /* skip separators */
249
 
                for(; i<md->nitems-1; i++) {
250
 
                        if(md->items[i+1].retval != -1) {
251
 
                                value= md->items[i+1].retval;
 
264
                for (; i < md->nitems - 1; i++) {
 
265
                        if (md->items[i + 1].retval != -1) {
 
266
                                value = md->items[i + 1].retval;
252
267
                                break;
253
268
                        }
254
269
                }
255
270
        }
256
271
        else {
257
 
                if(i>0) {
 
272
                if (i > 0) {
258
273
                        /* skip separators */
259
 
                        for(; i>0; i--) {
260
 
                                if(md->items[i-1].retval != -1) {
261
 
                                        value= md->items[i-1].retval;
 
274
                        for (; i > 0; i--) {
 
275
                                if (md->items[i - 1].retval != -1) {
 
276
                                        value = md->items[i - 1].retval;
262
277
                                        break;
263
278
                                }
264
279
                        }
273
288
 
274
289
/******************** Creating Temporary regions ******************/
275
290
 
276
 
ARegion *ui_add_temporary_region(bScreen *sc)
 
291
static ARegion *ui_add_temporary_region(bScreen *sc)
277
292
{
278
293
        ARegion *ar;
279
294
 
280
 
        ar= MEM_callocN(sizeof(ARegion), "area region");
 
295
        ar = MEM_callocN(sizeof(ARegion), "area region");
281
296
        BLI_addtail(&sc->regionbase, ar);
282
297
 
283
 
        ar->regiontype= RGN_TYPE_TEMPORARY;
284
 
        ar->alignment= RGN_ALIGN_FLOAT;
 
298
        ar->regiontype = RGN_TYPE_TEMPORARY;
 
299
        ar->alignment = RGN_ALIGN_FLOAT;
285
300
 
286
301
        return ar;
287
302
}
288
303
 
289
 
void ui_remove_temporary_region(bContext *C, bScreen *sc, ARegion *ar)
 
304
static void ui_remove_temporary_region(bContext *C, bScreen *sc, ARegion *ar)
290
305
{
291
 
        if(CTX_wm_window(C))
 
306
        if (CTX_wm_window(C))
292
307
                wm_draw_region_clear(CTX_wm_window(C), ar);
293
308
 
294
309
        ED_region_exit(C, ar);
295
 
        BKE_area_region_free(NULL, ar);         /* NULL: no spacetype */
 
310
        BKE_area_region_free(NULL, ar);     /* NULL: no spacetype */
296
311
        BLI_freelinkN(&sc->regionbase, ar);
297
312
}
298
313
 
299
314
/************************* Creating Tooltips **********************/
300
315
 
 
316
typedef enum {
 
317
        UI_TIP_LC_MAIN,
 
318
        UI_TIP_LC_NORMAL,
 
319
        UI_TIP_LC_PYTHON,
 
320
        UI_TIP_LC_ALERT,
 
321
        UI_TIP_LC_SUBMENU
 
322
} uiTooltipLineColor;
 
323
#define UI_TIP_LC_MAX 5
 
324
 
301
325
#define MAX_TOOLTIP_LINES 8
302
 
 
303
326
typedef struct uiTooltipData {
304
327
        rcti bbox;
305
328
        uiFontStyle fstyle;
306
329
        char lines[MAX_TOOLTIP_LINES][512];
307
 
        int linedark[MAX_TOOLTIP_LINES];
 
330
        uiTooltipLineColor color_id[MAX_TOOLTIP_LINES];
308
331
        int totline;
309
332
        int toth, spaceh, lineh;
310
333
} uiTooltipData;
311
334
 
312
 
static void ui_tooltip_region_draw(const bContext *C, ARegion *ar)
313
 
{
314
 
        uiTooltipData *data= ar->regiondata;
315
 
        rcti bbox= data->bbox;
316
 
        int a;
317
 
        
318
 
        ui_draw_menu_back(U.uistyles.first, NULL, &data->bbox);
319
 
        
 
335
static void rgb_tint(float col[3],
 
336
                     float h, float h_strength,
 
337
                     float v, float v_strength)
 
338
{
 
339
        float col_hsv_from[3];
 
340
        float col_hsv_to[3];
 
341
 
 
342
        rgb_to_hsv(col[0], col[1], col[2],    col_hsv_from + 0, col_hsv_from + 1, col_hsv_from + 2);
 
343
 
 
344
        col_hsv_to[0] = h;
 
345
        col_hsv_to[1] = h_strength;
 
346
        col_hsv_to[2] = (col_hsv_from[2] * (1.0f - v_strength)) + (v * v_strength);
 
347
 
 
348
        hsv_to_rgb(col_hsv_to[0], col_hsv_to[1], col_hsv_to[2], col + 0, col + 1, col + 2);
 
349
}
 
350
 
 
351
static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
 
352
{
 
353
        uiTooltipData *data = ar->regiondata;
 
354
        uiWidgetColors *theme = ui_tooltip_get_theme();
 
355
        rcti bbox = data->bbox;
 
356
        float tip_colors[UI_TIP_LC_MAX][3];
 
357
 
 
358
        float *main_color    = tip_colors[UI_TIP_LC_MAIN]; /* the color from the theme */
 
359
        float *normal_color  = tip_colors[UI_TIP_LC_NORMAL];
 
360
        float *python_color  = tip_colors[UI_TIP_LC_PYTHON];
 
361
        float *alert_color   = tip_colors[UI_TIP_LC_ALERT];
 
362
        float *submenu_color = tip_colors[UI_TIP_LC_SUBMENU];
 
363
 
 
364
        float background_color[3];
 
365
        float tone_bg;
 
366
        int i;
 
367
 
 
368
        /* draw background */
 
369
        ui_draw_tooltip_background(UI_GetStyle(), NULL, &bbox);
 
370
 
 
371
        /* set background_color */
 
372
        rgb_uchar_to_float(background_color, (const unsigned char *)theme->inner);
 
373
 
 
374
        /* calculate normal_color */
 
375
        rgb_uchar_to_float(main_color, (const unsigned char *)theme->text);
 
376
        copy_v3_v3(normal_color, main_color);
 
377
        copy_v3_v3(python_color, main_color);
 
378
        copy_v3_v3(alert_color, main_color);
 
379
        copy_v3_v3(submenu_color, main_color);
 
380
 
 
381
        /* find the brightness difference between background and text colors */
 
382
        
 
383
        tone_bg = rgb_to_grayscale(background_color);
 
384
        /* tone_fg = rgb_to_grayscale(main_color); */
 
385
 
 
386
        rgb_tint(normal_color, 0.0f, 0.0f, tone_bg, 0.3f);   /* a shade darker (to bg) */
 
387
        rgb_tint(python_color, 0.666f, 0.25f, tone_bg, 0.3f); /* blue */
 
388
        rgb_tint(alert_color, 0.0f, 0.8f, tone_bg, 0.1f);    /* bright red */
 
389
        rgb_tint(submenu_color, 0.0f, 0.0f, tone_bg, 0.3f);  /* a shade darker (to bg) */
 
390
 
320
391
        /* draw text */
321
392
        uiStyleFontSet(&data->fstyle);
322
393
 
323
 
        bbox.ymax= bbox.ymax - 0.5f*((bbox.ymax - bbox.ymin) - data->toth);
324
 
        bbox.ymin= bbox.ymax - data->lineh;
325
 
 
326
 
        for(a=0; a<data->totline; a++) {
327
 
                if(!data->linedark[a]) glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
328
 
                else glColor4f(0.5f, 0.5f, 0.5f, 1.0f);
329
 
 
330
 
                uiStyleFontDraw(&data->fstyle, &bbox, data->lines[a]);
 
394
        bbox.ymax = bbox.ymax - 0.5f * ((bbox.ymax - bbox.ymin) - data->toth);
 
395
        bbox.ymin = bbox.ymax - data->lineh;
 
396
 
 
397
        for (i = 0; i < data->totline; i++) {
 
398
                glColor3fv(tip_colors[data->color_id[i]]);
 
399
                uiStyleFontDraw(&data->fstyle, &bbox, data->lines[i]);
331
400
                bbox.ymin -= data->lineh + data->spaceh;
332
401
                bbox.ymax -= data->lineh + data->spaceh;
333
402
        }
334
403
}
335
404
 
336
 
static void ui_tooltip_region_free(ARegion *ar)
 
405
static void ui_tooltip_region_free_cb(ARegion *ar)
337
406
{
338
407
        uiTooltipData *data;
339
408
 
340
 
        data= ar->regiondata;
 
409
        data = ar->regiondata;
341
410
        MEM_freeN(data);
342
 
        ar->regiondata= NULL;
 
411
        ar->regiondata = NULL;
343
412
}
344
413
 
345
414
ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
346
415
{
347
 
        uiStyle *style= U.uistyles.first;       // XXX pass on as arg
 
416
        uiStyle *style = UI_GetStyle();
348
417
        static ARegionType type;
349
418
        ARegion *ar;
350
419
        uiTooltipData *data;
351
420
        IDProperty *prop;
352
421
        char buf[512];
353
 
        float fonth, fontw, aspect= but->block->aspect;
 
422
        float fonth, fontw, aspect = but->block->aspect;
354
423
        float x1f, x2f, y1f, y2f;
355
424
        int x1, x2, y1, y2, winx, winy, ofsx, ofsy, w, h, a;
356
425
 
357
 
        if(but->flag & UI_BUT_NO_TOOLTIP)
 
426
        if (but->flag & UI_BUT_NO_TOOLTIP)
358
427
                return NULL;
359
428
 
360
429
        /* create tooltip data */
361
 
        data= MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
362
 
 
363
 
        if(but->tip && strlen(but->tip)) {
 
430
        data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
 
431
 
 
432
        /* special case, enum rna buttons only have enum item description, use general enum description too before the specific one */
 
433
        if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) {
 
434
                const char *descr = RNA_property_description(but->rnaprop);
 
435
                if (descr && descr[0]) {
 
436
                        BLI_strncpy(data->lines[data->totline], descr, sizeof(data->lines[0]));
 
437
                        data->color_id[data->totline] = UI_TIP_LC_MAIN;
 
438
                        data->totline++;
 
439
                }
 
440
 
 
441
                if (ELEM(but->type, ROW, MENU)) {
 
442
                        EnumPropertyItem *item;
 
443
                        int i, totitem, free;
 
444
                        int value = (but->type == ROW) ? but->hardmax : ui_get_but_val(but);
 
445
 
 
446
                        RNA_property_enum_items_gettexted(C, &but->rnapoin, but->rnaprop, &item, &totitem, &free);
 
447
 
 
448
                        for (i = 0; i < totitem; i++) {
 
449
                                if (item[i].identifier[0] && item[i].value == value) {
 
450
                                        if (item[i].description && item[i].description[0]) {
 
451
                                                BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "%s: %s", item[i].name, item[i].description);
 
452
                                                data->color_id[data->totline] = UI_TIP_LC_SUBMENU;
 
453
                                                data->totline++;
 
454
                                        }
 
455
                                        break;
 
456
                                }
 
457
                        }
 
458
 
 
459
                        if (free) {
 
460
                                MEM_freeN(item);
 
461
                        }
 
462
                }
 
463
        }
 
464
        
 
465
        if (but->tip && but->tip[0] != '\0') {
364
466
                BLI_strncpy(data->lines[data->totline], but->tip, sizeof(data->lines[0]));
 
467
                data->color_id[data->totline] = UI_TIP_LC_MAIN;
365
468
                data->totline++;
366
469
        }
367
470
 
368
 
        if(but->optype && !(but->block->flag & UI_BLOCK_LOOP)) {
 
471
        if (but->optype && !(but->block->flag & UI_BLOCK_LOOP)) {
369
472
                /* operator keymap (not menus, they already have it) */
370
 
                prop= (but->opptr)? but->opptr->data: NULL;
 
473
                prop = (but->opptr) ? but->opptr->data : NULL;
371
474
 
372
 
                if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, buf, sizeof(buf))) {
373
 
                        BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Shortcut: %s", buf);
374
 
                        data->linedark[data->totline]= 1;
 
475
                if (WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, TRUE,
 
476
                                                 buf, sizeof(buf)))
 
477
                {
 
478
                        BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Shortcut: %s"), buf);
 
479
                        data->color_id[data->totline] = UI_TIP_LC_NORMAL;
375
480
                        data->totline++;
376
481
                }
377
482
        }
378
483
 
379
 
        if(ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
 
484
        if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
380
485
                /* full string */
381
486
                ui_get_but_string(but, buf, sizeof(buf));
382
 
                if(buf[0]) {
383
 
                        BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Value: %s", buf);
384
 
                        data->linedark[data->totline]= 1;
 
487
                if (buf[0]) {
 
488
                        BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Value: %s"), buf);
 
489
                        data->color_id[data->totline] = UI_TIP_LC_NORMAL;
385
490
                        data->totline++;
386
491
                }
387
492
        }
388
493
 
389
 
        if(but->rnaprop) {
390
 
                int unit_type = RNA_SUBTYPE_UNIT(RNA_property_subtype(but->rnaprop));
 
494
        if (but->rnaprop) {
 
495
                int unit_type = uiButGetUnitType(but);
391
496
                
392
497
                if (unit_type == PROP_UNIT_ROTATION) {
393
498
                        if (RNA_property_type(but->rnaprop) == PROP_FLOAT) {
394
 
                                BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Radians: %f", RNA_property_float_get_index(&but->rnapoin, but->rnaprop, but->rnaindex));
395
 
                                data->linedark[data->totline]= 1;
 
499
                                float value = RNA_property_array_check(but->rnaprop) ? RNA_property_float_get_index(&but->rnapoin, but->rnaprop, but->rnaindex) : RNA_property_float_get(&but->rnapoin, but->rnaprop);
 
500
                                BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Radians: %f"), value);
 
501
                                data->color_id[data->totline] = UI_TIP_LC_NORMAL;
396
502
                                data->totline++;
397
503
                        }
398
504
                }
399
505
                
400
 
                if(but->flag & UI_BUT_DRIVEN) {
401
 
                        if(ui_but_anim_expression_get(but, buf, sizeof(buf))) {
 
506
                if (but->flag & UI_BUT_DRIVEN) {
 
507
                        if (ui_but_anim_expression_get(but, buf, sizeof(buf))) {
402
508
                                /* expression */
403
 
                                BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Expression: %s", buf);
404
 
                                data->linedark[data->totline]= 1;
 
509
                                BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Expression: %s"), buf);
 
510
                                data->color_id[data->totline] = UI_TIP_LC_NORMAL;
405
511
                                data->totline++;
406
512
                        }
407
513
                }
408
514
 
409
515
                /* rna info */
410
 
                BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Python: %s.%s", RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop));
411
 
                data->linedark[data->totline]= 1;
412
 
                data->totline++;
 
516
                if ((U.flag & USER_TOOLTIPS_PYTHON) == 0) {
 
517
                        BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Python: %s.%s"), RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop));
 
518
                        data->color_id[data->totline] = UI_TIP_LC_PYTHON;
 
519
                        data->totline++;
 
520
                }
413
521
                
414
 
                if(but->rnapoin.id.data) {
415
 
                        ID *id= but->rnapoin.id.data;
416
 
                        if(id->lib && id->lib->name) {
417
 
                                BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Library: %s", id->lib->name);
418
 
                                data->linedark[data->totline]= 1;
 
522
                if (but->rnapoin.id.data) {
 
523
                        ID *id = but->rnapoin.id.data;
 
524
                        if (id->lib && id->lib->name) {
 
525
                                BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Library: %s"), id->lib->name);
 
526
                                data->color_id[data->totline] = UI_TIP_LC_NORMAL;
419
527
                                data->totline++;
420
528
                        }
421
529
                }
423
531
        else if (but->optype) {
424
532
                PointerRNA *opptr;
425
533
                char *str;
426
 
                opptr= uiButGetOperatorPtrRNA(but); /* allocated when needed, the button owns it */
 
534
                opptr = uiButGetOperatorPtrRNA(but); /* allocated when needed, the button owns it */
427
535
 
428
 
                str= WM_operator_pystring(C, but->optype, opptr, 0);
 
536
                str = WM_operator_pystring(C, but->optype, opptr, 0);
429
537
 
430
538
                /* operator info */
431
 
                BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Python: %s", str);
432
 
                data->linedark[data->totline]= 1;
433
 
                data->totline++;
 
539
                if ((U.flag & USER_TOOLTIPS_PYTHON) == 0) {
 
540
                        BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Python: %s"), str);
 
541
                        data->color_id[data->totline] = UI_TIP_LC_PYTHON;
 
542
                        data->totline++;
 
543
                }
434
544
 
435
545
                MEM_freeN(str);
436
 
        }
437
 
 
438
 
        if(data->totline == 0) {
 
546
 
 
547
                /* second check if we are disabled - why */
 
548
                if (but->flag & UI_BUT_DISABLED) {
 
549
                        const char *poll_msg;
 
550
                        CTX_wm_operator_poll_msg_set(C, NULL);
 
551
                        WM_operator_poll_context(C, but->optype, but->opcontext);
 
552
                        poll_msg = CTX_wm_operator_poll_msg_get(C);
 
553
                        if (poll_msg) {
 
554
                                BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Disabled: %s"), poll_msg);
 
555
                                data->color_id[data->totline] = UI_TIP_LC_ALERT; /* alert */
 
556
                                data->totline++;                        
 
557
                        }
 
558
                }
 
559
        }
 
560
        else if (ELEM(but->type, MENU, PULLDOWN)) {
 
561
                if ((U.flag & USER_TOOLTIPS_PYTHON) == 0) {
 
562
                        MenuType *mt = uiButGetMenuType(but);
 
563
                        if (mt) {
 
564
                                BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Python: %s"), mt->idname);
 
565
                                data->color_id[data->totline] = UI_TIP_LC_PYTHON;
 
566
                                data->totline++;
 
567
                        }
 
568
                }
 
569
 
 
570
        }
 
571
 
 
572
        assert(data->totline < MAX_TOOLTIP_LINES);
 
573
        
 
574
        if (data->totline == 0) {
439
575
                MEM_freeN(data);
440
576
                return NULL;
441
577
        }
442
578
 
443
579
        /* create area region */
444
 
        ar= ui_add_temporary_region(CTX_wm_screen(C));
 
580
        ar = ui_add_temporary_region(CTX_wm_screen(C));
445
581
 
446
582
        memset(&type, 0, sizeof(ARegionType));
447
 
        type.draw= ui_tooltip_region_draw;
448
 
        type.free= ui_tooltip_region_free;
449
 
        ar->type= &type;
 
583
        type.draw = ui_tooltip_region_draw_cb;
 
584
        type.free = ui_tooltip_region_free_cb;
 
585
        ar->type = &type;
450
586
        
451
587
        /* set font, get bb */
452
 
        data->fstyle= style->widget; /* copy struct */
453
 
        data->fstyle.align= UI_STYLE_TEXT_CENTER;
 
588
        data->fstyle = style->widget; /* copy struct */
 
589
        data->fstyle.align = UI_STYLE_TEXT_CENTER;
454
590
        uiStyleFontSet(&data->fstyle);
455
591
 
456
 
        h= BLF_height(data->fstyle.uifont_id, data->lines[0]);
457
 
 
458
 
        for(a=0, fontw=0, fonth=0; a<data->totline; a++) {
459
 
                w= BLF_width(data->fstyle.uifont_id, data->lines[a]);
460
 
                fontw= MAX2(fontw, w);
461
 
                fonth += (a == 0)? h: h+5;
 
592
        /* these defines may need to be tweaked depending on font */
 
593
#define TIP_MARGIN_Y 2
 
594
#define TIP_BORDER_X 16.0f
 
595
#define TIP_BORDER_Y 6.0f
 
596
 
 
597
        h = BLF_height_max(data->fstyle.uifont_id);
 
598
 
 
599
        for (a = 0, fontw = 0, fonth = 0; a < data->totline; a++) {
 
600
                w = BLF_width(data->fstyle.uifont_id, data->lines[a]);
 
601
                fontw = MAX2(fontw, w);
 
602
                fonth += (a == 0) ? h : h + TIP_MARGIN_Y;
462
603
        }
463
604
 
464
605
        fontw *= aspect;
465
606
 
466
 
        ar->regiondata= data;
467
 
 
468
 
        data->toth= fonth;
469
 
        data->lineh= h;
470
 
        data->spaceh= 5;
 
607
        ar->regiondata = data;
 
608
 
 
609
        data->toth = fonth;
 
610
        data->lineh = h;
 
611
        data->spaceh = TIP_MARGIN_Y;
 
612
 
471
613
 
472
614
        /* compute position */
473
 
        ofsx= (but->block->panel)? but->block->panel->ofsx: 0;
474
 
        ofsy= (but->block->panel)? but->block->panel->ofsy: 0;
 
615
        ofsx = (but->block->panel) ? but->block->panel->ofsx : 0;
 
616
        ofsy = (but->block->panel) ? but->block->panel->ofsy : 0;
475
617
 
476
 
        x1f= (but->x1+but->x2)/2.0f + ofsx - 16.0f*aspect;
477
 
        x2f= x1f + fontw + 16.0f*aspect;
478
 
        y2f= but->y1 + ofsy - 15.0f*aspect;
479
 
        y1f= y2f - fonth*aspect - 15.0f*aspect;
 
618
        x1f = (but->x1 + but->x2) * 0.5f + ofsx - (TIP_BORDER_X * aspect);
 
619
        x2f = x1f + fontw + (TIP_BORDER_X * aspect);
 
620
        y2f = but->y1 + ofsy - (TIP_BORDER_Y * aspect);
 
621
        y1f = y2f - fonth * aspect - (TIP_BORDER_Y * aspect);
480
622
        
 
623
#undef TIP_MARGIN_Y
 
624
#undef TIP_BORDER_X
 
625
#undef TIP_BORDER_Y
 
626
 
481
627
        /* copy to int, gets projected if possible too */
482
 
        x1= x1f; y1= y1f; x2= x2f; y2= y2f; 
 
628
        x1 = x1f; y1 = y1f; x2 = x2f; y2 = y2f;
483
629
        
484
 
        if(butregion) {
 
630
        if (butregion) {
485
631
                /* XXX temp, region v2ds can be empty still */
486
 
                if(butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
 
632
                if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
487
633
                        UI_view2d_to_region_no_clip(&butregion->v2d, x1f, y1f, &x1, &y1);
488
634
                        UI_view2d_to_region_no_clip(&butregion->v2d, x2f, y2f, &x2, &y2);
489
635
                }
496
642
 
497
643
        wm_window_get_size(CTX_wm_window(C), &winx, &winy);
498
644
 
499
 
        if(x2 > winx) {
 
645
        if (x2 > winx) {
500
646
                /* super size */
501
 
                if(x2 > winx + x1) {
502
 
                        x2= winx;
503
 
                        x1= 0;
 
647
                if (x2 > winx + x1) {
 
648
                        x2 = winx;
 
649
                        x1 = 0;
504
650
                }
505
651
                else {
506
 
                        x1 -= x2-winx;
507
 
                        x2= winx;
 
652
                        x1 -= x2 - winx;
 
653
                        x2 = winx;
508
654
                }
509
655
        }
510
 
        if(y1 < 0) {
511
 
                y1 += 56;
512
 
                y2 += 56;
 
656
        /* ensure at least 5 px above screen bounds
 
657
         * 25 is just a guess to be above the menu item */
 
658
        if (y1 < 5) {
 
659
                y2 += (-y1) + 30;
 
660
                y1 = 30;
513
661
        }
514
662
 
515
663
        /* widget rect, in region coords */
516
 
        data->bbox.xmin= MENU_SHADOW_SIDE;
517
 
        data->bbox.xmax= x2-x1 + MENU_SHADOW_SIDE;
518
 
        data->bbox.ymin= MENU_SHADOW_BOTTOM;
519
 
        data->bbox.ymax= y2-y1 + MENU_SHADOW_BOTTOM;
 
664
        data->bbox.xmin = MENU_SHADOW_SIDE;
 
665
        data->bbox.xmax = x2 - x1 + MENU_SHADOW_SIDE;
 
666
        data->bbox.ymin = MENU_SHADOW_BOTTOM;
 
667
        data->bbox.ymax = y2 - y1 + MENU_SHADOW_BOTTOM;
520
668
        
521
669
        /* region bigger for shadow */
522
 
        ar->winrct.xmin= x1 - MENU_SHADOW_SIDE;
523
 
        ar->winrct.xmax= x2 + MENU_SHADOW_SIDE;
524
 
        ar->winrct.ymin= y1 - MENU_SHADOW_BOTTOM;
525
 
        ar->winrct.ymax= y2 + MENU_TOP;
 
670
        ar->winrct.xmin = x1 - MENU_SHADOW_SIDE;
 
671
        ar->winrct.xmax = x2 + MENU_SHADOW_SIDE;
 
672
        ar->winrct.ymin = y1 - MENU_SHADOW_BOTTOM;
 
673
        ar->winrct.ymax = y2 + MENU_TOP;
526
674
 
527
675
        /* adds subwindow */
528
676
        ED_region_init(C, ar);
559
707
        rcti bbox;
560
708
        uiFontStyle fstyle;
561
709
        uiSearchItems items;
562
 
        int active;             /* index in items array */
563
 
        int noback;             /* when menu opened with enough space for this */
564
 
        int preview;    /* draw thumbnail previews, rather than list */
 
710
        int active;     /* index in items array */
 
711
        int noback;     /* when menu opened with enough space for this */
 
712
        int preview;    /* draw thumbnail previews, rather than list */
565
713
        int prv_rows, prv_cols;
566
714
} uiSearchboxData;
567
715
 
568
 
#define SEARCH_ITEMS    10
 
716
#define SEARCH_ITEMS    10
569
717
 
570
718
/* exported for use by search callbacks */
571
719
/* returns zero if nothing to add */
572
720
int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int iconid)
573
721
{
574
722
        /* hijack for autocomplete */
575
 
        if(items->autocpl) {
 
723
        if (items->autocpl) {
576
724
                autocomplete_do_name(items->autocpl, name);
577
725
                return 1;
578
726
        }
579
727
        
580
728
        /* hijack for finding active item */
581
 
        if(items->active) {
582
 
                if(poin==items->active)
583
 
                        items->offset_i= items->totitem;
 
729
        if (items->active) {
 
730
                if (poin == items->active)
 
731
                        items->offset_i = items->totitem;
584
732
                items->totitem++;
585
733
                return 1;
586
734
        }
587
735
        
588
 
        if(items->totitem>=items->maxitem) {
589
 
                items->more= 1;
 
736
        if (items->totitem >= items->maxitem) {
 
737
                items->more = 1;
590
738
                return 0;
591
739
        }
592
740
        
593
741
        /* skip first items in list */
594
 
        if(items->offset_i > 0) {
 
742
        if (items->offset_i > 0) {
595
743
                items->offset_i--;
596
744
                return 1;
597
745
        }
598
746
        
599
 
        BLI_strncpy(items->names[items->totitem], name, items->maxstrlen);
600
 
        items->pointers[items->totitem]= poin;
601
 
        items->icons[items->totitem]= iconid;
 
747
        if (items->names)
 
748
                BLI_strncpy(items->names[items->totitem], name, items->maxstrlen);
 
749
        if (items->pointers)
 
750
                items->pointers[items->totitem] = poin;
 
751
        if (items->icons)
 
752
                items->icons[items->totitem] = iconid;
602
753
        
603
754
        items->totitem++;
604
755
        
607
758
 
608
759
int uiSearchBoxhHeight(void)
609
760
{
610
 
        return SEARCH_ITEMS*MENU_BUTTON_HEIGHT + 2*MENU_TOP;
 
761
        return SEARCH_ITEMS * UI_UNIT_Y + 2 * MENU_TOP;
611
762
}
612
763
 
613
764
/* ar is the search box itself */
614
765
static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step)
615
766
{
616
 
        uiSearchboxData *data= ar->regiondata;
 
767
        uiSearchboxData *data = ar->regiondata;
617
768
        
618
769
        /* apply step */
619
 
        data->active+= step;
 
770
        data->active += step;
620
771
        
621
 
        if(data->items.totitem==0)
622
 
                data->active= 0;
623
 
        else if(data->active > data->items.totitem) {
624
 
                if(data->items.more) {
 
772
        if (data->items.totitem == 0)
 
773
                data->active = 0;
 
774
        else if (data->active > data->items.totitem) {
 
775
                if (data->items.more) {
625
776
                        data->items.offset++;
626
 
                        data->active= data->items.totitem;
 
777
                        data->active = data->items.totitem;
627
778
                        ui_searchbox_update(C, ar, but, 0);
628
779
                }
629
780
                else
630
 
                        data->active= data->items.totitem;
 
781
                        data->active = data->items.totitem;
631
782
        }
632
 
        else if(data->active < 1) {
633
 
                if(data->items.offset) {
 
783
        else if (data->active < 1) {
 
784
                if (data->items.offset) {
634
785
                        data->items.offset--;
635
 
                        data->active= 1;
 
786
                        data->active = 1;
636
787
                        ui_searchbox_update(C, ar, but, 0);
637
788
                }
638
 
                else if(data->active < 0)
639
 
                        data->active= 0;
 
789
                else if (data->active < 0)
 
790
                        data->active = 0;
640
791
        }
641
792
        
642
793
        ED_region_tag_redraw(ar);
646
797
{
647
798
        /* thumbnail preview */
648
799
        if (data->preview) {
649
 
                int buth = (data->bbox.ymax - data->bbox.ymin - 2*MENU_TOP) / data->prv_rows;
 
800
                int buth = (data->bbox.ymax - data->bbox.ymin - 2 * MENU_TOP) / data->prv_rows;
650
801
                int butw = (data->bbox.xmax - data->bbox.xmin) / data->prv_cols;
651
802
                int row, col;
652
803
                
653
 
                *rect= data->bbox;
 
804
                *rect = data->bbox;
654
805
                
655
806
                col = itemnr % data->prv_cols;
656
807
                row = itemnr / data->prv_cols;
658
809
                rect->xmin += col * butw;
659
810
                rect->xmax = rect->xmin + butw;
660
811
                
661
 
                rect->ymax = data->bbox.ymax - (row * buth);
 
812
                rect->ymax = data->bbox.ymax - MENU_TOP - (row * buth);
662
813
                rect->ymin = rect->ymax - buth;
663
814
        }
664
815
        /* list view */
665
816
        else {
666
 
                int buth= (data->bbox.ymax-data->bbox.ymin - 2*MENU_TOP)/SEARCH_ITEMS;
667
 
                
668
 
                *rect= data->bbox;
669
 
                rect->xmin= data->bbox.xmin + 3.0f;
670
 
                rect->xmax= data->bbox.xmax - 3.0f;
671
 
                
672
 
                rect->ymax= data->bbox.ymax - MENU_TOP - itemnr*buth;
673
 
                rect->ymin= rect->ymax - buth;
 
817
                int buth = (data->bbox.ymax - data->bbox.ymin - 2 * MENU_TOP) / SEARCH_ITEMS;
 
818
                
 
819
                *rect = data->bbox;
 
820
                rect->xmin = data->bbox.xmin + 3.0f;
 
821
                rect->xmax = data->bbox.xmax - 3.0f;
 
822
                
 
823
                rect->ymax = data->bbox.ymax - MENU_TOP - itemnr * buth;
 
824
                rect->ymin = rect->ymax - buth;
674
825
        }
675
826
        
676
827
}
678
829
/* x and y in screencoords */
679
830
int ui_searchbox_inside(ARegion *ar, int x, int y)
680
831
{
681
 
        uiSearchboxData *data= ar->regiondata;
 
832
        uiSearchboxData *data = ar->regiondata;
682
833
        
683
 
        return(BLI_in_rcti(&data->bbox, x-ar->winrct.xmin, y-ar->winrct.ymin));
 
834
        return(BLI_in_rcti(&data->bbox, x - ar->winrct.xmin, y - ar->winrct.ymin));
684
835
}
685
836
 
686
837
/* string validated to be of correct length (but->hardmax) */
687
838
void ui_searchbox_apply(uiBut *but, ARegion *ar)
688
839
{
689
 
        uiSearchboxData *data= ar->regiondata;
 
840
        uiSearchboxData *data = ar->regiondata;
690
841
 
691
 
        but->func_arg2= NULL;
 
842
        but->func_arg2 = NULL;
692
843
        
693
 
        if(data->active) {
694
 
                char *name= data->items.names[data->active-1];
695
 
                char *cpoin= strchr(name, '|');
 
844
        if (data->active) {
 
845
                char *name = data->items.names[data->active - 1];
 
846
                char *cpoin = strchr(name, '|');
696
847
                
697
 
                if(cpoin) cpoin[0]= 0;
 
848
                if (cpoin) cpoin[0] = 0;
698
849
                BLI_strncpy(but->editstr, name, data->items.maxstrlen);
699
 
                if(cpoin) cpoin[0]= '|';
 
850
                if (cpoin) cpoin[0] = '|';
700
851
                
701
 
                but->func_arg2= data->items.pointers[data->active-1];
 
852
                but->func_arg2 = data->items.pointers[data->active - 1];
702
853
        }
703
854
}
704
855
 
705
856
void ui_searchbox_event(bContext *C, ARegion *ar, uiBut *but, wmEvent *event)
706
857
{
707
 
        uiSearchboxData *data= ar->regiondata;
 
858
        uiSearchboxData *data = ar->regiondata;
708
859
        
709
 
        switch(event->type) {
 
860
        switch (event->type) {
710
861
                case WHEELUPMOUSE:
711
862
                case UPARROWKEY:
712
863
                        ui_searchbox_select(C, ar, but, -1);
716
867
                        ui_searchbox_select(C, ar, but, 1);
717
868
                        break;
718
869
                case MOUSEMOVE:
719
 
                        if(BLI_in_rcti(&ar->winrct, event->x, event->y)) {
 
870
                        if (BLI_in_rcti(&ar->winrct, event->x, event->y)) {
720
871
                                rcti rect;
721
872
                                int a;
722
873
                                
723
 
                                for(a=0; a<data->items.totitem; a++) {
 
874
                                for (a = 0; a < data->items.totitem; a++) {
724
875
                                        ui_searchbox_butrect(&rect, data, a);
725
 
                                        if(BLI_in_rcti(&rect, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin)) {
726
 
                                                if( data->active!= a+1) {
727
 
                                                        data->active= a+1;
 
876
                                        if (BLI_in_rcti(&rect, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin)) {
 
877
                                                if (data->active != a + 1) {
 
878
                                                        data->active = a + 1;
728
879
                                                        ui_searchbox_select(C, ar, but, 0);
729
880
                                                        break;
730
881
                                                }
738
889
/* ar is the search box itself */
739
890
void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, int reset)
740
891
{
741
 
        uiSearchboxData *data= ar->regiondata;
 
892
        uiSearchboxData *data = ar->regiondata;
742
893
        
743
894
        /* reset vars */
744
 
        data->items.totitem= 0;
745
 
        data->items.more= 0;
746
 
        if(reset==0) {
747
 
                data->items.offset_i= data->items.offset;
 
895
        data->items.totitem = 0;
 
896
        data->items.more = 0;
 
897
        if (reset == 0) {
 
898
                data->items.offset_i = data->items.offset;
748
899
        }
749
900
        else {
750
 
                data->items.offset_i= data->items.offset= 0;
751
 
                data->active= 0;
 
901
                data->items.offset_i = data->items.offset = 0;
 
902
                data->active = 0;
752
903
                
753
904
                /* handle active */
754
 
                if(but->search_func && but->func_arg2) {
755
 
                        data->items.active= but->func_arg2;
 
905
                if (but->search_func && but->func_arg2) {
 
906
                        data->items.active = but->func_arg2;
756
907
                        but->search_func(C, but->search_arg, but->editstr, &data->items);
757
 
                        data->items.active= NULL;
 
908
                        data->items.active = NULL;
758
909
                        
759
910
                        /* found active item, calculate real offset by centering it */
760
 
                        if(data->items.totitem) {
 
911
                        if (data->items.totitem) {
761
912
                                /* first case, begin of list */
762
 
                                if(data->items.offset_i < data->items.maxitem) {
763
 
                                        data->active= data->items.offset_i+1;
764
 
                                        data->items.offset_i= 0;
 
913
                                if (data->items.offset_i < data->items.maxitem) {
 
914
                                        data->active = data->items.offset_i + 1;
 
915
                                        data->items.offset_i = 0;
765
916
                                }
766
917
                                else {
767
918
                                        /* second case, end of list */
768
 
                                        if(data->items.totitem - data->items.offset_i <= data->items.maxitem) {
769
 
                                                data->active= 1 + data->items.offset_i - data->items.totitem + data->items.maxitem;
770
 
                                                data->items.offset_i= data->items.totitem - data->items.maxitem;
 
919
                                        if (data->items.totitem - data->items.offset_i <= data->items.maxitem) {
 
920
                                                data->active = 1 + data->items.offset_i - data->items.totitem + data->items.maxitem;
 
921
                                                data->items.offset_i = data->items.totitem - data->items.maxitem;
771
922
                                        }
772
923
                                        else {
773
924
                                                /* center active item */
774
 
                                                data->items.offset_i -= data->items.maxitem/2;
775
 
                                                data->active= 1 + data->items.maxitem/2;
 
925
                                                data->items.offset_i -= data->items.maxitem / 2;
 
926
                                                data->active = 1 + data->items.maxitem / 2;
776
927
                                        }
777
928
                                }
778
929
                        }
779
 
                        data->items.offset= data->items.offset_i;
780
 
                        data->items.totitem= 0;
 
930
                        data->items.offset = data->items.offset_i;
 
931
                        data->items.totitem = 0;
781
932
                }
782
933
        }
783
934
        
784
935
        /* callback */
785
 
        if(but->search_func)
 
936
        if (but->search_func)
786
937
                but->search_func(C, but->search_arg, but->editstr, &data->items);
787
938
        
788
939
        /* handle case where editstr is equal to one of items */
789
 
        if(reset && data->active==0) {
 
940
        if (reset && data->active == 0) {
790
941
                int a;
791
942
                
792
 
                for(a=0; a<data->items.totitem; a++) {
793
 
                        char *cpoin= strchr(data->items.names[a], '|');
 
943
                for (a = 0; a < data->items.totitem; a++) {
 
944
                        char *cpoin = strchr(data->items.names[a], '|');
794
945
                        
795
 
                        if(cpoin) cpoin[0]= 0;
796
 
                        if(0==strcmp(but->editstr, data->items.names[a]))
797
 
                                data->active= a+1;
798
 
                        if(cpoin) cpoin[0]= '|';
 
946
                        if (cpoin) cpoin[0] = 0;
 
947
                        if (0 == strcmp(but->editstr, data->items.names[a]))
 
948
                                data->active = a + 1;
 
949
                        if (cpoin) cpoin[0] = '|';
799
950
                }
800
 
                if(data->items.totitem==1 && but->editstr[0])
801
 
                        data->active= 1;
 
951
                if (data->items.totitem == 1 && but->editstr[0])
 
952
                        data->active = 1;
802
953
        }
803
954
 
804
955
        /* validate selected item */
809
960
 
810
961
void ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str)
811
962
{
812
 
        uiSearchboxData *data= ar->regiondata;
 
963
        uiSearchboxData *data = ar->regiondata;
813
964
 
814
 
        if(str[0]) {
815
 
                data->items.autocpl= autocomplete_begin(str, ui_get_but_string_max_length(but));
 
965
        if (str[0]) {
 
966
                data->items.autocpl = autocomplete_begin(str, ui_get_but_string_max_length(but));
816
967
 
817
968
                but->search_func(C, but->search_arg, but->editstr, &data->items);
818
969
 
819
970
                autocomplete_end(data->items.autocpl, str);
820
 
                data->items.autocpl= NULL;
 
971
                data->items.autocpl = NULL;
821
972
        }
822
973
}
823
974
 
824
 
static void ui_searchbox_region_draw(const bContext *C, ARegion *ar)
 
975
static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
825
976
{
826
 
        uiSearchboxData *data= ar->regiondata;
 
977
        uiSearchboxData *data = ar->regiondata;
827
978
        
828
979
        /* pixel space */
829
 
        wmOrtho2(-0.01f, ar->winx-0.01f, -0.01f, ar->winy-0.01f);
 
980
        wmOrtho2(-0.01f, ar->winx - 0.01f, -0.01f, ar->winy - 0.01f);
830
981
 
831
 
        if(!data->noback)
832
 
                ui_draw_search_back(U.uistyles.first, NULL, &data->bbox);
 
982
        if (!data->noback)
 
983
                ui_draw_search_back(NULL, NULL, &data->bbox);  /* style not used yet */
833
984
        
834
985
        /* draw text */
835
 
        if(data->items.totitem) {
 
986
        if (data->items.totitem) {
836
987
                rcti rect;
837
988
                int a;
838
989
                
839
990
                if (data->preview) {
840
991
                        /* draw items */
841
 
                        for(a=0; a<data->items.totitem; a++) {
 
992
                        for (a = 0; a < data->items.totitem; a++) {
842
993
                                ui_searchbox_butrect(&rect, data, a);
843
994
                                
844
995
                                /* widget itself */
845
996
                                if (data->preview)
846
 
                                        ui_draw_preview_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
 
997
                                        ui_draw_preview_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a + 1) == data->active ? UI_ACTIVE : 0);
847
998
                                else 
848
 
                                        ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
 
999
                                        ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a + 1) == data->active ? UI_ACTIVE : 0);
849
1000
                        }
850
1001
                        
851
1002
                        /* indicate more */
852
 
                        if(data->items.more) {
853
 
                                ui_searchbox_butrect(&rect, data, data->items.maxitem-1);
 
1003
                        if (data->items.more) {
 
1004
                                ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
854
1005
                                glEnable(GL_BLEND);
855
 
                                UI_icon_draw(rect.xmax-18, rect.ymin-7, ICON_TRIA_DOWN);
 
1006
                                UI_icon_draw(rect.xmax - 18, rect.ymin - 7, ICON_TRIA_DOWN);
856
1007
                                glDisable(GL_BLEND);
857
1008
                        }
858
 
                        if(data->items.offset) {
 
1009
                        if (data->items.offset) {
859
1010
                                ui_searchbox_butrect(&rect, data, 0);
860
1011
                                glEnable(GL_BLEND);
861
 
                                UI_icon_draw(rect.xmin, rect.ymax-9, ICON_TRIA_UP);
 
1012
                                UI_icon_draw(rect.xmin, rect.ymax - 9, ICON_TRIA_UP);
862
1013
                                glDisable(GL_BLEND);
863
1014
                        }
864
1015
                        
865
 
                } else {
 
1016
                }
 
1017
                else {
866
1018
                        /* draw items */
867
 
                        for(a=0; a<data->items.totitem; a++) {
 
1019
                        for (a = 0; a < data->items.totitem; a++) {
868
1020
                                ui_searchbox_butrect(&rect, data, a);
869
1021
                                
870
1022
                                /* widget itself */
871
 
                                ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a+1)==data->active?UI_ACTIVE:0);
 
1023
                                ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a + 1) == data->active ? UI_ACTIVE : 0);
872
1024
                                
873
1025
                        }
874
1026
                        /* indicate more */
875
 
                        if(data->items.more) {
876
 
                                ui_searchbox_butrect(&rect, data, data->items.maxitem-1);
 
1027
                        if (data->items.more) {
 
1028
                                ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
877
1029
                                glEnable(GL_BLEND);
878
 
                                UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymin-9, ICON_TRIA_DOWN);
 
1030
                                UI_icon_draw((rect.xmax - rect.xmin) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
879
1031
                                glDisable(GL_BLEND);
880
1032
                        }
881
 
                        if(data->items.offset) {
 
1033
                        if (data->items.offset) {
882
1034
                                ui_searchbox_butrect(&rect, data, 0);
883
1035
                                glEnable(GL_BLEND);
884
 
                                UI_icon_draw((rect.xmax-rect.xmin)/2, rect.ymax-7, ICON_TRIA_UP);
 
1036
                                UI_icon_draw((rect.xmax - rect.xmin) / 2, rect.ymax - 7, ICON_TRIA_UP);
885
1037
                                glDisable(GL_BLEND);
886
1038
                        }
887
1039
                }
888
1040
        }
889
1041
}
890
1042
 
891
 
static void ui_searchbox_region_free(ARegion *ar)
 
1043
static void ui_searchbox_region_free_cb(ARegion *ar)
892
1044
{
893
 
        uiSearchboxData *data= ar->regiondata;
 
1045
        uiSearchboxData *data = ar->regiondata;
894
1046
        int a;
895
1047
 
896
1048
        /* free search data */
897
 
        for(a=0; a<data->items.maxitem; a++)
 
1049
        for (a = 0; a < data->items.maxitem; a++) {
898
1050
                MEM_freeN(data->items.names[a]);
 
1051
        }
899
1052
        MEM_freeN(data->items.names);
900
1053
        MEM_freeN(data->items.pointers);
901
1054
        MEM_freeN(data->items.icons);
902
1055
        
903
1056
        MEM_freeN(data);
904
 
        ar->regiondata= NULL;
 
1057
        ar->regiondata = NULL;
905
1058
}
906
1059
 
907
 
static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, uiBlock *block);
908
 
 
909
1060
ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
910
1061
{
911
 
        uiStyle *style= U.uistyles.first;       // XXX pass on as arg
 
1062
        uiStyle *style = UI_GetStyle();
912
1063
        static ARegionType type;
913
1064
        ARegion *ar;
914
1065
        uiSearchboxData *data;
915
 
        float aspect= but->block->aspect;
 
1066
        float aspect = but->block->aspect;
916
1067
        float x1f, x2f, y1f, y2f;
917
1068
        int x1, x2, y1, y2, winx, winy, ofsx, ofsy;
918
1069
        
919
1070
        /* create area region */
920
 
        ar= ui_add_temporary_region(CTX_wm_screen(C));
 
1071
        ar = ui_add_temporary_region(CTX_wm_screen(C));
921
1072
        
922
1073
        memset(&type, 0, sizeof(ARegionType));
923
 
        type.draw= ui_searchbox_region_draw;
924
 
        type.free= ui_searchbox_region_free;
925
 
        ar->type= &type;
 
1074
        type.draw = ui_searchbox_region_draw_cb;
 
1075
        type.free = ui_searchbox_region_free_cb;
 
1076
        ar->type = &type;
926
1077
        
927
1078
        /* create searchbox data */
928
 
        data= MEM_callocN(sizeof(uiSearchboxData), "uiSearchboxData");
 
1079
        data = MEM_callocN(sizeof(uiSearchboxData), "uiSearchboxData");
929
1080
 
930
1081
        /* set font, get bb */
931
 
        data->fstyle= style->widget; /* copy struct */
932
 
        data->fstyle.align= UI_STYLE_TEXT_CENTER;
 
1082
        data->fstyle = style->widget; /* copy struct */
 
1083
        data->fstyle.align = UI_STYLE_TEXT_CENTER;
933
1084
        ui_fontscale(&data->fstyle.points, aspect);
934
1085
        uiStyleFontSet(&data->fstyle);
935
1086
        
936
 
        ar->regiondata= data;
 
1087
        ar->regiondata = data;
937
1088
        
938
1089
        /* special case, hardcoded feature, not draw backdrop when called from menus,
939
 
           assume for design that popup already added it */
940
 
        if(but->block->flag & UI_BLOCK_LOOP)
941
 
                data->noback= 1;
 
1090
         * assume for design that popup already added it */
 
1091
        if (but->block->flag & UI_BLOCK_LOOP)
 
1092
                data->noback = 1;
942
1093
        
943
1094
        if (but->a1 > 0 && but->a2 > 0) {
944
1095
                data->preview = 1;
947
1098
        }
948
1099
        
949
1100
        /* compute position */
950
 
        if(but->block->flag & UI_BLOCK_LOOP) {
 
1101
        if (but->block->flag & UI_BLOCK_LOOP) {
951
1102
                /* this case is search menu inside other menu */
952
1103
                /* we copy region size */
953
1104
 
954
 
                ar->winrct= butregion->winrct;
 
1105
                ar->winrct = butregion->winrct;
955
1106
                
956
1107
                /* widget rect, in region coords */
957
 
                data->bbox.xmin= MENU_SHADOW_SIDE;
958
 
                data->bbox.xmax= (ar->winrct.xmax-ar->winrct.xmin) - MENU_SHADOW_SIDE;
959
 
                data->bbox.ymin= MENU_SHADOW_BOTTOM;
960
 
                data->bbox.ymax= (ar->winrct.ymax-ar->winrct.ymin) - MENU_SHADOW_BOTTOM;
 
1108
                data->bbox.xmin = MENU_SHADOW_SIDE;
 
1109
                data->bbox.xmax = (ar->winrct.xmax - ar->winrct.xmin) - MENU_SHADOW_SIDE;
 
1110
                data->bbox.ymin = MENU_SHADOW_BOTTOM;
 
1111
                data->bbox.ymax = (ar->winrct.ymax - ar->winrct.ymin) - MENU_SHADOW_BOTTOM;
961
1112
                
962
1113
                /* check if button is lower half */
963
 
                if( but->y2 < (but->block->minx+but->block->maxx)/2 ) {
964
 
                        data->bbox.ymin += (but->y2-but->y1);
 
1114
                if (but->y2 < (but->block->miny + but->block->maxy) / 2) {
 
1115
                        data->bbox.ymin += (but->y2 - but->y1);
965
1116
                }
966
1117
                else {
967
 
                        data->bbox.ymax -= (but->y2-but->y1);
 
1118
                        data->bbox.ymax -= (but->y2 - but->y1);
968
1119
                }
969
1120
        }
970
1121
        else {
971
 
                x1f= but->x1 - 5;       /* align text with button */
972
 
                x2f= but->x2 + 5;       /* symmetrical */
973
 
                y2f= but->y1;
974
 
                y1f= y2f - uiSearchBoxhHeight();
 
1122
                x1f = but->x1 - 5;   /* align text with button */
 
1123
                x2f = but->x2 + 5;   /* symmetrical */
 
1124
                y2f = but->y1;
 
1125
                y1f = y2f - uiSearchBoxhHeight();
975
1126
 
976
 
                ofsx= (but->block->panel)? but->block->panel->ofsx: 0;
977
 
                ofsy= (but->block->panel)? but->block->panel->ofsy: 0;
 
1127
                ofsx = (but->block->panel) ? but->block->panel->ofsx : 0;
 
1128
                ofsy = (but->block->panel) ? but->block->panel->ofsy : 0;
978
1129
 
979
1130
                x1f += ofsx;
980
1131
                x2f += ofsx;
982
1133
                y2f += ofsy;
983
1134
        
984
1135
                /* minimal width */
985
 
                if(x2f - x1f < 150) x2f= x1f+150; // XXX arbitrary
 
1136
                if (x2f - x1f < 150) x2f = x1f + 150;  // XXX arbitrary
986
1137
                
987
1138
                /* copy to int, gets projected if possible too */
988
 
                x1= x1f; y1= y1f; x2= x2f; y2= y2f; 
 
1139
                x1 = x1f; y1 = y1f; x2 = x2f; y2 = y2f;
989
1140
                
990
 
                if(butregion) {
991
 
                        if(butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
992
 
                                UI_view2d_to_region_no_clip(&butregion->v2d, x1f, y1f, &x1, &y1);
993
 
                                UI_view2d_to_region_no_clip(&butregion->v2d, x2f, y2f, &x2, &y2);
994
 
                        }
995
 
                        
996
 
                        x1 += butregion->winrct.xmin;
997
 
                        x2 += butregion->winrct.xmin;
998
 
                        y1 += butregion->winrct.ymin;
999
 
                        y2 += butregion->winrct.ymin;
 
1141
                if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
 
1142
                        UI_view2d_to_region_no_clip(&butregion->v2d, x1f, y1f, &x1, &y1);
 
1143
                        UI_view2d_to_region_no_clip(&butregion->v2d, x2f, y2f, &x2, &y2);
1000
1144
                }
1001
 
                
 
1145
 
 
1146
                x1 += butregion->winrct.xmin;
 
1147
                x2 += butregion->winrct.xmin;
 
1148
                y1 += butregion->winrct.ymin;
 
1149
                y2 += butregion->winrct.ymin;
 
1150
 
1002
1151
                wm_window_get_size(CTX_wm_window(C), &winx, &winy);
1003
1152
                
1004
 
                if(x2 > winx) {
 
1153
                if (x2 > winx) {
1005
1154
                        /* super size */
1006
 
                        if(x2 > winx + x1) {
1007
 
                                x2= winx;
1008
 
                                x1= 0;
 
1155
                        if (x2 > winx + x1) {
 
1156
                                x2 = winx;
 
1157
                                x1 = 0;
1009
1158
                        }
1010
1159
                        else {
1011
 
                                x1 -= x2-winx;
1012
 
                                x2= winx;
 
1160
                                x1 -= x2 - winx;
 
1161
                                x2 = winx;
1013
1162
                        }
1014
1163
                }
1015
 
                if(y1 < 0) {
 
1164
 
 
1165
                if (y1 < 0) {
1016
1166
                        int newy1;
1017
 
                        UI_view2d_to_region_no_clip(&butregion->v2d, 0, but->y2 + ofsy, 0, &newy1);
 
1167
                        UI_view2d_to_region_no_clip(&butregion->v2d, 0, but->y2 + ofsy, NULL, &newy1);
1018
1168
                        newy1 += butregion->winrct.ymin;
1019
1169
 
1020
 
                        y2= y2-y1 + newy1;
1021
 
                        y1= newy1;
 
1170
                        y2 = y2 - y1 + newy1;
 
1171
                        y1 = newy1;
1022
1172
                }
1023
1173
 
1024
1174
                /* widget rect, in region coords */
1025
 
                data->bbox.xmin= MENU_SHADOW_SIDE;
1026
 
                data->bbox.xmax= x2-x1 + MENU_SHADOW_SIDE;
1027
 
                data->bbox.ymin= MENU_SHADOW_BOTTOM;
1028
 
                data->bbox.ymax= y2-y1 + MENU_SHADOW_BOTTOM;
 
1175
                data->bbox.xmin = MENU_SHADOW_SIDE;
 
1176
                data->bbox.xmax = x2 - x1 + MENU_SHADOW_SIDE;
 
1177
                data->bbox.ymin = MENU_SHADOW_BOTTOM;
 
1178
                data->bbox.ymax = y2 - y1 + MENU_SHADOW_BOTTOM;
1029
1179
                
1030
1180
                /* region bigger for shadow */
1031
 
                ar->winrct.xmin= x1 - MENU_SHADOW_SIDE;
1032
 
                ar->winrct.xmax= x2 + MENU_SHADOW_SIDE;
1033
 
                ar->winrct.ymin= y1 - MENU_SHADOW_BOTTOM;
1034
 
                ar->winrct.ymax= y2;
 
1181
                ar->winrct.xmin = x1 - MENU_SHADOW_SIDE;
 
1182
                ar->winrct.xmax = x2 + MENU_SHADOW_SIDE;
 
1183
                ar->winrct.ymin = y1 - MENU_SHADOW_BOTTOM;
 
1184
                ar->winrct.ymax = y2;
1035
1185
        }
1036
1186
        
1037
1187
        /* adds subwindow */
1042
1192
        
1043
1193
        /* prepare search data */
1044
1194
        if (data->preview) {
1045
 
                data->items.maxitem= data->prv_rows * data->prv_cols;
1046
 
        } else {
1047
 
                data->items.maxitem= SEARCH_ITEMS;
1048
 
        }
1049
 
        data->items.maxstrlen= but->hardmax;
1050
 
        data->items.totitem= 0;
1051
 
        data->items.names= MEM_callocN(data->items.maxitem*sizeof(void *), "search names");
1052
 
        data->items.pointers= MEM_callocN(data->items.maxitem*sizeof(void *), "search pointers");
1053
 
        data->items.icons= MEM_callocN(data->items.maxitem*sizeof(int), "search icons");
1054
 
        for(x1=0; x1<data->items.maxitem; x1++)
1055
 
                data->items.names[x1]= MEM_callocN(but->hardmax+1, "search pointers");
 
1195
                data->items.maxitem = data->prv_rows * data->prv_cols;
 
1196
        }
 
1197
        else {
 
1198
                data->items.maxitem = SEARCH_ITEMS;
 
1199
        }
 
1200
        data->items.maxstrlen = but->hardmax;
 
1201
        data->items.totitem = 0;
 
1202
        data->items.names = MEM_callocN(data->items.maxitem * sizeof(void *), "search names");
 
1203
        data->items.pointers = MEM_callocN(data->items.maxitem * sizeof(void *), "search pointers");
 
1204
        data->items.icons = MEM_callocN(data->items.maxitem * sizeof(int), "search icons");
 
1205
        for (x1 = 0; x1 < data->items.maxitem; x1++)
 
1206
                data->items.names[x1] = MEM_callocN(but->hardmax + 1, "search pointers");
1056
1207
        
1057
1208
        return ar;
1058
1209
}
1062
1213
        ui_remove_temporary_region(C, CTX_wm_screen(C), ar);
1063
1214
}
1064
1215
 
 
1216
/* sets red alert if button holds a string it can't find */
 
1217
/* XXX weak: search_func adds all partial matches... */
 
1218
void ui_but_search_test(uiBut *but)
 
1219
{
 
1220
        uiSearchItems *items;
 
1221
        int x1;
 
1222
 
 
1223
        /* possibly very large lists (such as ID datablocks) only
 
1224
         * only validate string RNA buts (not pointers) */
 
1225
        if (but->rnaprop && RNA_property_type(but->rnaprop) != PROP_STRING) {
 
1226
                return;
 
1227
        }
 
1228
 
 
1229
        items = MEM_callocN(sizeof(uiSearchItems), "search items");
 
1230
 
 
1231
        /* setup search struct */
 
1232
        items->maxitem = 10;
 
1233
        items->maxstrlen = 256;
 
1234
        items->names = MEM_callocN(items->maxitem * sizeof(void *), "search names");
 
1235
        for (x1 = 0; x1 < items->maxitem; x1++)
 
1236
                items->names[x1] = MEM_callocN(but->hardmax + 1, "search names");
 
1237
        
 
1238
        but->search_func(but->block->evil_C, but->search_arg, but->drawstr, items);
 
1239
        
 
1240
        /* only redalert when we are sure of it, this can miss cases when >10 matches */
 
1241
        if (items->totitem == 0)
 
1242
                uiButSetFlag(but, UI_BUT_REDALERT);
 
1243
        else if (items->more == 0) {
 
1244
                for (x1 = 0; x1 < items->totitem; x1++)
 
1245
                        if (strcmp(but->drawstr, items->names[x1]) == 0)
 
1246
                                break;
 
1247
                if (x1 == items->totitem)
 
1248
                        uiButSetFlag(but, UI_BUT_REDALERT);
 
1249
        }
 
1250
        
 
1251
        for (x1 = 0; x1 < items->maxitem; x1++) {
 
1252
                MEM_freeN(items->names[x1]);
 
1253
        }
 
1254
        MEM_freeN(items->names);
 
1255
        MEM_freeN(items);
 
1256
}
 
1257
 
1065
1258
 
1066
1259
/************************* Creating Menu Blocks **********************/
1067
1260
 
1071
1264
        uiBut *bt;
1072
1265
        uiSafetyRct *saferct;
1073
1266
        rctf butrct;
1074
 
        float aspect;
1075
 
        int xsize, ysize, xof=0, yof=0, center;
1076
 
        short dir1= 0, dir2=0;
 
1267
        /*float aspect;*/ /*UNUSED*/
 
1268
        int xsize, ysize, xof = 0, yof = 0, center;
 
1269
        short dir1 = 0, dir2 = 0;
1077
1270
        
1078
1271
        /* transform to window coordinates, using the source button region/block */
1079
 
        butrct.xmin= but->x1; butrct.xmax= but->x2;
1080
 
        butrct.ymin= but->y1; butrct.ymax= but->y2;
 
1272
        butrct.xmin = but->x1; butrct.xmax = but->x2;
 
1273
        butrct.ymin = but->y1; butrct.ymax = but->y2;
1081
1274
 
1082
1275
        ui_block_to_window_fl(butregion, but->block, &butrct.xmin, &butrct.ymin);
1083
1276
        ui_block_to_window_fl(butregion, but->block, &butrct.xmax, &butrct.ymax);
1084
1277
 
1085
1278
        /* calc block rect */
1086
 
        if(block->minx == 0.0f && block->maxx == 0.0f) {
1087
 
                if(block->buttons.first) {
1088
 
                        block->minx= block->miny= 10000;
1089
 
                        block->maxx= block->maxy= -10000;
 
1279
        if (block->minx == 0.0f && block->maxx == 0.0f) {
 
1280
                if (block->buttons.first) {
 
1281
                        block->minx = block->miny = 10000;
 
1282
                        block->maxx = block->maxy = -10000;
1090
1283
                        
1091
 
                        bt= block->buttons.first;
1092
 
                        while(bt) {
1093
 
                                if(bt->x1 < block->minx) block->minx= bt->x1;
1094
 
                                if(bt->y1 < block->miny) block->miny= bt->y1;
 
1284
                        bt = block->buttons.first;
 
1285
                        while (bt) {
 
1286
                                if (bt->x1 < block->minx) block->minx = bt->x1;
 
1287
                                if (bt->y1 < block->miny) block->miny = bt->y1;
1095
1288
 
1096
 
                                if(bt->x2 > block->maxx) block->maxx= bt->x2;
1097
 
                                if(bt->y2 > block->maxy) block->maxy= bt->y2;
 
1289
                                if (bt->x2 > block->maxx) block->maxx = bt->x2;
 
1290
                                if (bt->y2 > block->maxy) block->maxy = bt->y2;
1098
1291
                                
1099
 
                                bt= bt->next;
 
1292
                                bt = bt->next;
1100
1293
                        }
1101
1294
                }
1102
1295
                else {
1103
1296
                        /* we're nice and allow empty blocks too */
1104
 
                        block->minx= block->miny= 0;
1105
 
                        block->maxx= block->maxy= 20;
 
1297
                        block->minx = block->miny = 0;
 
1298
                        block->maxx = block->maxy = 20;
1106
1299
                }
1107
1300
        }
1108
1301
        
1109
 
        aspect= (float)(block->maxx - block->minx + 4);
 
1302
        /*aspect= (float)(block->maxx - block->minx + 4);*/ /*UNUSED*/
1110
1303
        ui_block_to_window_fl(butregion, but->block, &block->minx, &block->miny);
1111
1304
        ui_block_to_window_fl(butregion, but->block, &block->maxx, &block->maxy);
1112
1305
 
1113
1306
        //block->minx-= 2.0; block->miny-= 2.0;
1114
1307
        //block->maxx+= 2.0; block->maxy+= 2.0;
1115
1308
        
1116
 
        xsize= block->maxx - block->minx+4; // 4 for shadow
1117
 
        ysize= block->maxy - block->miny+4;
1118
 
        aspect/= (float)xsize;
 
1309
        xsize = block->maxx - block->minx + 4; // 4 for shadow
 
1310
        ysize = block->maxy - block->miny + 4;
 
1311
        /*aspect/= (float)xsize;*/ /*UNUSED*/
1119
1312
 
1120
 
        if(but) {
1121
 
                int left=0, right=0, top=0, down=0;
 
1313
        {
 
1314
                int left = 0, right = 0, top = 0, down = 0;
1122
1315
                int winx, winy;
 
1316
                // int offscreen;
1123
1317
 
1124
1318
                wm_window_get_size(window, &winx, &winy);
1125
1319
 
1126
 
                if(block->direction & UI_CENTER) center= ysize/2;
1127
 
                else center= 0;
 
1320
                if (block->direction & UI_CENTER) center = ysize / 2;
 
1321
                else center = 0;
 
1322
                
 
1323
                /* check if there's space at all */
 
1324
                if (butrct.xmin - xsize > 0.0f) left = 1;
 
1325
                if (butrct.xmax + xsize < winx) right = 1;
 
1326
                if (butrct.ymin - ysize + center > 0.0f) down = 1;
 
1327
                if (butrct.ymax + ysize - center < winy) top = 1;
1128
1328
 
1129
 
                if( butrct.xmin-xsize > 0.0) left= 1;
1130
 
                if( butrct.xmax+xsize < winx) right= 1;
1131
 
                if( butrct.ymin-ysize+center > 0.0) down= 1;
1132
 
                if( butrct.ymax+ysize-center < winy) top= 1;
 
1329
                if (top == 0 && down == 0) {
 
1330
                        if (butrct.ymin - ysize < winy - butrct.ymax - ysize)
 
1331
                                top = 1;
 
1332
                        else
 
1333
                                down = 1;
 
1334
                }
1133
1335
                
1134
 
                dir1= block->direction & UI_DIRECTION;
 
1336
                dir1 = block->direction & UI_DIRECTION;
1135
1337
 
1136
1338
                /* secundary directions */
1137
 
                if(dir1 & (UI_TOP|UI_DOWN)) {
1138
 
                        if(dir1 & UI_LEFT) dir2= UI_LEFT;
1139
 
                        else if(dir1 & UI_RIGHT) dir2= UI_RIGHT;
1140
 
                        dir1 &= (UI_TOP|UI_DOWN);
 
1339
                if (dir1 & (UI_TOP | UI_DOWN)) {
 
1340
                        if (dir1 & UI_LEFT) dir2 = UI_LEFT;
 
1341
                        else if (dir1 & UI_RIGHT) dir2 = UI_RIGHT;
 
1342
                        dir1 &= (UI_TOP | UI_DOWN);
1141
1343
                }
1142
1344
 
1143
 
                if(dir2==0) if(dir1==UI_LEFT || dir1==UI_RIGHT) dir2= UI_DOWN;
1144
 
                if(dir2==0) if(dir1==UI_TOP || dir1==UI_DOWN) dir2= UI_LEFT;
 
1345
                if (dir2 == 0) if (dir1 == UI_LEFT || dir1 == UI_RIGHT) dir2 = UI_DOWN;
 
1346
                if (dir2 == 0) if (dir1 == UI_TOP || dir1 == UI_DOWN) dir2 = UI_LEFT;
1145
1347
                
1146
 
                /* no space at all? dont change */
1147
 
                if(left || right) {
1148
 
                        if(dir1==UI_LEFT && left==0) dir1= UI_RIGHT;
1149
 
                        if(dir1==UI_RIGHT && right==0) dir1= UI_LEFT;
 
1348
                /* no space at all? don't change */
 
1349
                if (left || right) {
 
1350
                        if (dir1 == UI_LEFT && left == 0) dir1 = UI_RIGHT;
 
1351
                        if (dir1 == UI_RIGHT && right == 0) dir1 = UI_LEFT;
1150
1352
                        /* this is aligning, not append! */
1151
 
                        if(dir2==UI_LEFT && right==0) dir2= UI_RIGHT;
1152
 
                        if(dir2==UI_RIGHT && left==0) dir2= UI_LEFT;
1153
 
                }
1154
 
                if(down || top) {
1155
 
                        if(dir1==UI_TOP && top==0) dir1= UI_DOWN;
1156
 
                        if(dir1==UI_DOWN && down==0) dir1= UI_TOP;
1157
 
                        if(dir2==UI_TOP && top==0) dir2= UI_DOWN;
1158
 
                        if(dir2==UI_DOWN && down==0) dir2= UI_TOP;
1159
 
                }
1160
 
                
1161
 
                if(dir1==UI_LEFT) {
1162
 
                        xof= butrct.xmin - block->maxx;
1163
 
                        if(dir2==UI_TOP) yof= butrct.ymin - block->miny-center;
1164
 
                        else yof= butrct.ymax - block->maxy+center;
1165
 
                }
1166
 
                else if(dir1==UI_RIGHT) {
1167
 
                        xof= butrct.xmax - block->minx;
1168
 
                        if(dir2==UI_TOP) yof= butrct.ymin - block->miny-center;
1169
 
                        else yof= butrct.ymax - block->maxy+center;
1170
 
                }
1171
 
                else if(dir1==UI_TOP) {
1172
 
                        yof= butrct.ymax - block->miny;
1173
 
                        if(dir2==UI_RIGHT) xof= butrct.xmax - block->maxx;
1174
 
                        else xof= butrct.xmin - block->minx;
 
1353
                        if (dir2 == UI_LEFT && right == 0) dir2 = UI_RIGHT;
 
1354
                        if (dir2 == UI_RIGHT && left == 0) dir2 = UI_LEFT;
 
1355
                }
 
1356
                if (down || top) {
 
1357
                        if (dir1 == UI_TOP && top == 0) dir1 = UI_DOWN;
 
1358
                        if (dir1 == UI_DOWN && down == 0) dir1 = UI_TOP;
 
1359
                        if (dir2 == UI_TOP && top == 0) dir2 = UI_DOWN;
 
1360
                        if (dir2 == UI_DOWN && down == 0) dir2 = UI_TOP;
 
1361
                }
 
1362
 
 
1363
                if (dir1 == UI_LEFT) {
 
1364
                        xof = butrct.xmin - block->maxx;
 
1365
                        if (dir2 == UI_TOP) yof = butrct.ymin - block->miny - center;
 
1366
                        else yof = butrct.ymax - block->maxy + center;
 
1367
                }
 
1368
                else if (dir1 == UI_RIGHT) {
 
1369
                        xof = butrct.xmax - block->minx;
 
1370
                        if (dir2 == UI_TOP) yof = butrct.ymin - block->miny - center;
 
1371
                        else yof = butrct.ymax - block->maxy + center;
 
1372
                }
 
1373
                else if (dir1 == UI_TOP) {
 
1374
                        yof = butrct.ymax - block->miny;
 
1375
                        if (dir2 == UI_RIGHT) xof = butrct.xmax - block->maxx;
 
1376
                        else xof = butrct.xmin - block->minx;
1175
1377
                        // changed direction? 
1176
 
                        if((dir1 & block->direction)==0) {
1177
 
                                if(block->direction & UI_SHIFT_FLIPPED)
1178
 
                                        xof+= dir2==UI_LEFT?25:-25;
 
1378
                        if ((dir1 & block->direction) == 0) {
 
1379
                                if (block->direction & UI_SHIFT_FLIPPED)
 
1380
                                        xof += dir2 == UI_LEFT ? 25 : -25;
1179
1381
                                uiBlockFlipOrder(block);
1180
1382
                        }
1181
1383
                }
1182
 
                else if(dir1==UI_DOWN) {
1183
 
                        yof= butrct.ymin - block->maxy;
1184
 
                        if(dir2==UI_RIGHT) xof= butrct.xmax - block->maxx;
1185
 
                        else xof= butrct.xmin - block->minx;
 
1384
                else if (dir1 == UI_DOWN) {
 
1385
                        yof = butrct.ymin - block->maxy;
 
1386
                        if (dir2 == UI_RIGHT) xof = butrct.xmax - block->maxx;
 
1387
                        else xof = butrct.xmin - block->minx;
1186
1388
                        // changed direction?
1187
 
                        if((dir1 & block->direction)==0) {
1188
 
                                if(block->direction & UI_SHIFT_FLIPPED)
1189
 
                                        xof+= dir2==UI_LEFT?25:-25;
 
1389
                        if ((dir1 & block->direction) == 0) {
 
1390
                                if (block->direction & UI_SHIFT_FLIPPED)
 
1391
                                        xof += dir2 == UI_LEFT ? 25 : -25;
1190
1392
                                uiBlockFlipOrder(block);
1191
1393
                        }
1192
1394
                }
1193
1395
 
1194
1396
                /* and now we handle the exception; no space below or to top */
1195
 
                if(top==0 && down==0) {
1196
 
                        if(dir1==UI_LEFT || dir1==UI_RIGHT) {
 
1397
                if (top == 0 && down == 0) {
 
1398
                        if (dir1 == UI_LEFT || dir1 == UI_RIGHT) {
1197
1399
                                // align with bottom of screen 
1198
 
                                yof= ysize;
 
1400
                                // yof= ysize; (not with menu scrolls)
1199
1401
                        }
1200
1402
                }
1201
1403
                
1202
1404
                /* or no space left or right */
1203
 
                if(left==0 && right==0) {
1204
 
                        if(dir1==UI_TOP || dir1==UI_DOWN) {
 
1405
                if (left == 0 && right == 0) {
 
1406
                        if (dir1 == UI_TOP || dir1 == UI_DOWN) {
1205
1407
                                // align with left size of screen 
1206
 
                                xof= -block->minx+5;
 
1408
                                xof = -block->minx + 5;
1207
1409
                        }
1208
1410
                }
1209
1411
                
1210
1412
                // apply requested offset in the block
1211
 
                xof += block->xofs/block->aspect;
1212
 
                yof += block->yofs/block->aspect;
 
1413
                xof += block->xofs / block->aspect;
 
1414
                yof += block->yofs / block->aspect;
 
1415
#if 0
 
1416
                /* clamp to window bounds, could be made into an option if its ever annoying */
 
1417
                if (     (offscreen = (block->miny + yof)) < 0) yof -= offscreen;   /* bottom */
 
1418
                else if ((offscreen = (block->maxy + yof) - winy) > 0) yof -= offscreen;  /* top */
 
1419
                if (     (offscreen = (block->minx + xof)) < 0) xof -= offscreen;   /* left */
 
1420
                else if ((offscreen = (block->maxx + xof) - winx) > 0) xof -= offscreen;  /* right */
 
1421
#endif
1213
1422
        }
1214
1423
        
1215
 
        /* apply */
 
1424
        /* apply offset, buttons in window coords */
1216
1425
        
1217
 
        for(bt= block->buttons.first; bt; bt= bt->next) {
 
1426
        for (bt = block->buttons.first; bt; bt = bt->next) {
1218
1427
                ui_block_to_window_fl(butregion, but->block, &bt->x1, &bt->y1);
1219
1428
                ui_block_to_window_fl(butregion, but->block, &bt->x2, &bt->y2);
1220
1429
 
1223
1432
                bt->y1 += yof;
1224
1433
                bt->y2 += yof;
1225
1434
 
1226
 
                bt->aspect= 1.0;
 
1435
                bt->aspect = 1.0;
1227
1436
                // ui_check_but recalculates drawstring size in pixels
1228
1437
                ui_check_but(bt);
1229
1438
        }
1234
1443
        block->maxy += yof;
1235
1444
 
1236
1445
        /* safety calculus */
1237
 
        if(but) {
1238
 
                float midx= (butrct.xmin+butrct.xmax)/2.0;
1239
 
                float midy= (butrct.ymin+butrct.ymax)/2.0;
 
1446
        if (but) {
 
1447
                float midx = (butrct.xmin + butrct.xmax) / 2.0f;
 
1448
                float midy = (butrct.ymin + butrct.ymax) / 2.0f;
1240
1449
                
1241
1450
                /* when you are outside parent button, safety there should be smaller */
1242
1451
                
1243
1452
                // parent button to left
1244
 
                if( midx < block->minx ) block->safety.xmin= block->minx-3; 
1245
 
                else block->safety.xmin= block->minx-40;
 
1453
                if (midx < block->minx) block->safety.xmin = block->minx - 3;
 
1454
                else block->safety.xmin = block->minx - 40;
1246
1455
                // parent button to right
1247
 
                if( midx > block->maxx ) block->safety.xmax= block->maxx+3; 
1248
 
                else block->safety.xmax= block->maxx+40;
 
1456
                if (midx > block->maxx) block->safety.xmax = block->maxx + 3;
 
1457
                else block->safety.xmax = block->maxx + 40;
1249
1458
                
1250
1459
                // parent button on bottom
1251
 
                if( midy < block->miny ) block->safety.ymin= block->miny-3; 
1252
 
                else block->safety.ymin= block->miny-40;
 
1460
                if (midy < block->miny) block->safety.ymin = block->miny - 3;
 
1461
                else block->safety.ymin = block->miny - 40;
1253
1462
                // parent button on top
1254
 
                if( midy > block->maxy ) block->safety.ymax= block->maxy+3; 
1255
 
                else block->safety.ymax= block->maxy+40;
 
1463
                if (midy > block->maxy) block->safety.ymax = block->maxy + 3;
 
1464
                else block->safety.ymax = block->maxy + 40;
1256
1465
                
1257
1466
                // exception for switched pulldowns...
1258
 
                if(dir1 && (dir1 & block->direction)==0) {
1259
 
                        if(dir2==UI_RIGHT) block->safety.xmax= block->maxx+3; 
1260
 
                        if(dir2==UI_LEFT) block->safety.xmin= block->minx-3; 
 
1467
                if (dir1 && (dir1 & block->direction) == 0) {
 
1468
                        if (dir2 == UI_RIGHT) block->safety.xmax = block->maxx + 3;
 
1469
                        if (dir2 == UI_LEFT) block->safety.xmin = block->minx - 3;
1261
1470
                }
1262
 
                block->direction= dir1;
 
1471
                block->direction = dir1;
1263
1472
        }
1264
1473
        else {
1265
 
                block->safety.xmin= block->minx-40;
1266
 
                block->safety.ymin= block->miny-40;
1267
 
                block->safety.xmax= block->maxx+40;
1268
 
                block->safety.ymax= block->maxy+40;
 
1474
                block->safety.xmin = block->minx - 40;
 
1475
                block->safety.ymin = block->miny - 40;
 
1476
                block->safety.xmax = block->maxx + 40;
 
1477
                block->safety.ymax = block->maxy + 40;
1269
1478
        }
1270
1479
 
1271
1480
        /* keep a list of these, needed for pulldown menus */
1272
 
        saferct= MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
1273
 
        saferct->parent= butrct;
1274
 
        saferct->safety= block->safety;
 
1481
        saferct = MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
 
1482
        saferct->parent = butrct;
 
1483
        saferct->safety = block->safety;
1275
1484
        BLI_freelistN(&block->saferct);
1276
 
        if(but)
 
1485
        if (but)
1277
1486
                BLI_duplicatelist(&block->saferct, &but->block->saferct);
1278
1487
        BLI_addhead(&block->saferct, saferct);
1279
1488
}
1282
1491
{
1283
1492
        uiBlock *block;
1284
1493
 
1285
 
        for(block=ar->uiblocks.first; block; block=block->next)
 
1494
        for (block = ar->uiblocks.first; block; block = block->next)
1286
1495
                uiDrawBlock(C, block);
1287
1496
}
1288
1497
 
 
1498
static void ui_popup_block_clip(wmWindow *window, uiBlock *block)
 
1499
{
 
1500
        int winx, winy;
 
1501
        
 
1502
        wm_window_get_size(window, &winx, &winy);
 
1503
        
 
1504
        if (block->minx < MENU_SHADOW_SIDE)
 
1505
                block->minx = MENU_SHADOW_SIDE;
 
1506
        if (block->maxx > winx - MENU_SHADOW_SIDE)
 
1507
                block->maxx = winx - MENU_SHADOW_SIDE;
 
1508
        
 
1509
        if (block->miny < MENU_SHADOW_BOTTOM)
 
1510
                block->miny = MENU_SHADOW_BOTTOM;
 
1511
        if (block->maxy > winy - MENU_TOP)
 
1512
                block->maxy = winy - MENU_TOP;
 
1513
}
 
1514
 
 
1515
void ui_popup_block_scrolltest(uiBlock *block)
 
1516
{
 
1517
        uiBut *bt;
 
1518
        /* Knowing direction is necessary for multi-column menus... */
 
1519
        int is_flip = (block->direction & UI_TOP) && !(block->flag & UI_BLOCK_NO_FLIP);
 
1520
        
 
1521
        block->flag &= ~(UI_BLOCK_CLIPBOTTOM | UI_BLOCK_CLIPTOP);
 
1522
        
 
1523
        for (bt = block->buttons.first; bt; bt = bt->next)
 
1524
                bt->flag &= ~UI_SCROLLED;
 
1525
        
 
1526
        if (block->buttons.first == block->buttons.last)
 
1527
                return;
 
1528
        
 
1529
        /* mark buttons that are outside boundary and the ones next to it for arrow(s) */
 
1530
        for (bt = block->buttons.first; bt; bt = bt->next) {
 
1531
                if (bt->y1 < block->miny) {
 
1532
                        bt->flag |= UI_SCROLLED;
 
1533
                        block->flag |= UI_BLOCK_CLIPBOTTOM;
 
1534
                        /* make space for arrow */
 
1535
                        if (bt->y2 < block->miny + 10) {
 
1536
                                if (is_flip && bt->next && bt->next->y1 > bt->y1)
 
1537
                                        bt->next->flag |= UI_SCROLLED;
 
1538
                                else if (!is_flip && bt->prev && bt->prev->y1 > bt->y1)
 
1539
                                        bt->prev->flag |= UI_SCROLLED;
 
1540
                        }
 
1541
                }
 
1542
                if (bt->y2 > block->maxy) {
 
1543
                        bt->flag |= UI_SCROLLED;
 
1544
                        block->flag |= UI_BLOCK_CLIPTOP;
 
1545
                        /* make space for arrow */
 
1546
                        if (bt->y1 > block->maxy - 10) {
 
1547
                                if (!is_flip && bt->next && bt->next->y2 < bt->y2)
 
1548
                                        bt->next->flag |= UI_SCROLLED;
 
1549
                                else if (is_flip && bt->prev && bt->prev->y2 < bt->y2)
 
1550
                                        bt->prev->flag |= UI_SCROLLED;
 
1551
                        }
 
1552
                }
 
1553
        }
 
1554
}
 
1555
 
1289
1556
uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut *but, uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func, void *arg)
1290
1557
{
1291
 
        wmWindow *window= CTX_wm_window(C);
 
1558
        wmWindow *window = CTX_wm_window(C);
1292
1559
        static ARegionType type;
1293
1560
        ARegion *ar;
1294
1561
        uiBlock *block;
1297
1564
        uiSafetyRct *saferct;
1298
1565
 
1299
1566
        /* create handle */
1300
 
        handle= MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
 
1567
        handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
1301
1568
 
1302
1569
        /* store context for operator */
1303
 
        handle->ctx_area= CTX_wm_area(C);
1304
 
        handle->ctx_region= CTX_wm_region(C);
 
1570
        handle->ctx_area = CTX_wm_area(C);
 
1571
        handle->ctx_region = CTX_wm_region(C);
1305
1572
        
1306
1573
        /* create area region */
1307
 
        ar= ui_add_temporary_region(CTX_wm_screen(C));
1308
 
        handle->region= ar;
 
1574
        ar = ui_add_temporary_region(CTX_wm_screen(C));
 
1575
        handle->region = ar;
1309
1576
 
1310
1577
        memset(&type, 0, sizeof(ARegionType));
1311
 
        type.draw= ui_block_region_draw;
1312
 
        ar->type= &type;
 
1578
        type.draw = ui_block_region_draw;
 
1579
        ar->type = &type;
1313
1580
 
1314
1581
        UI_add_region_handlers(&ar->handlers);
1315
1582
 
1316
1583
        /* create ui block */
1317
 
        if(create_func)
1318
 
                block= create_func(C, handle->region, arg);
 
1584
        if (create_func)
 
1585
                block = create_func(C, handle->region, arg);
1319
1586
        else
1320
 
                block= handle_create_func(C, handle, arg);
 
1587
                block = handle_create_func(C, handle, arg);
1321
1588
        
1322
 
        if(block->handle) {
 
1589
        if (block->handle) {
1323
1590
                memcpy(block->handle, handle, sizeof(uiPopupBlockHandle));
1324
1591
                MEM_freeN(handle);
1325
 
                handle= block->handle;
 
1592
                handle = block->handle;
1326
1593
        }
1327
1594
        else
1328
 
                block->handle= handle;
1329
 
 
1330
 
        ar->regiondata= handle;
1331
 
 
1332
 
        if(!block->endblock)
 
1595
                block->handle = handle;
 
1596
 
 
1597
        ar->regiondata = handle;
 
1598
 
 
1599
        if (!block->endblock)
1333
1600
                uiEndBlock(C, block);
1334
1601
 
1335
1602
        /* if this is being created from a button */
1336
 
        if(but) {
1337
 
                if(ELEM(but->type, BLOCK, PULLDOWN))
1338
 
                        block->xofs = -2;       /* for proper alignment */
 
1603
        if (but) {
 
1604
                if (ELEM(but->type, BLOCK, PULLDOWN))
 
1605
                        block->xofs = -2;   /* for proper alignment */
1339
1606
 
1340
 
                /* only used for automatic toolbox, so can set the shift flag */
1341
 
                if(but->flag & UI_MAKE_TOP) {
1342
 
                        block->direction= UI_TOP|UI_SHIFT_FLIPPED;
1343
 
                        uiBlockFlipOrder(block);
1344
 
                }
1345
 
                if(but->flag & UI_MAKE_DOWN) block->direction= UI_DOWN|UI_SHIFT_FLIPPED;
1346
 
                if(but->flag & UI_MAKE_LEFT) block->direction |= UI_LEFT;
1347
 
                if(but->flag & UI_MAKE_RIGHT) block->direction |= UI_RIGHT;
 
1607
                block->aspect = but->block->aspect;
1348
1608
 
1349
1609
                ui_block_position(window, butregion, but, block);
1350
1610
        }
1351
1611
        else {
1352
1612
                /* keep a list of these, needed for pulldown menus */
1353
 
                saferct= MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
1354
 
                saferct->safety= block->safety;
 
1613
                saferct = MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
 
1614
                saferct->safety = block->safety;
1355
1615
                BLI_addhead(&block->saferct, saferct);
1356
 
                block->flag |= UI_BLOCK_POPUP|UI_BLOCK_NUMSELECT;
 
1616
                block->flag |= UI_BLOCK_POPUP | UI_BLOCK_NUMSELECT;
1357
1617
        }
1358
1618
 
 
1619
        /* clip block with window boundary */
 
1620
        ui_popup_block_clip(window, block);
 
1621
        
1359
1622
        /* the block and buttons were positioned in window space as in 2.4x, now
1360
1623
         * these menu blocks are regions so we bring it back to region space.
1361
1624
         * additionally we add some padding for the menu shadow or rounded menus */
1362
 
        ar->winrct.xmin= block->minx - MENU_SHADOW_SIDE;
1363
 
        ar->winrct.xmax= block->maxx + MENU_SHADOW_SIDE;
1364
 
        ar->winrct.ymin= block->miny - MENU_SHADOW_BOTTOM;
1365
 
        ar->winrct.ymax= block->maxy + MENU_TOP;
1366
 
 
 
1625
        ar->winrct.xmin = block->minx - MENU_SHADOW_SIDE;
 
1626
        ar->winrct.xmax = block->maxx + MENU_SHADOW_SIDE;
 
1627
        ar->winrct.ymin = block->miny - MENU_SHADOW_BOTTOM;
 
1628
        ar->winrct.ymax = block->maxy + MENU_TOP;
 
1629
        
1367
1630
        block->minx -= ar->winrct.xmin;
1368
1631
        block->maxx -= ar->winrct.xmin;
1369
1632
        block->miny -= ar->winrct.ymin;
1370
1633
        block->maxy -= ar->winrct.ymin;
1371
1634
 
1372
 
        for(bt= block->buttons.first; bt; bt= bt->next) {
 
1635
        for (bt = block->buttons.first; bt; bt = bt->next) {
1373
1636
                bt->x1 -= ar->winrct.xmin;
1374
1637
                bt->x2 -= ar->winrct.xmin;
1375
1638
                bt->y1 -= ar->winrct.ymin;
1376
1639
                bt->y2 -= ar->winrct.ymin;
1377
1640
        }
1378
 
 
 
1641
        
1379
1642
        block->flag |= UI_BLOCK_LOOP;
1380
1643
 
1381
1644
        /* adds subwindow */
1382
1645
        ED_region_init(C, ar);
1383
1646
 
 
1647
        /* checks which buttons are visible, sets flags to prevent draw (do after region init) */
 
1648
        ui_popup_block_scrolltest(block);
 
1649
        
1384
1650
        /* get winmat now that we actually have the subwindow */
1385
1651
        wmSubWindowSet(window, ar->swinid);
1386
1652
        
1395
1661
void ui_popup_block_free(bContext *C, uiPopupBlockHandle *handle)
1396
1662
{
1397
1663
        ui_remove_temporary_region(C, CTX_wm_screen(C), handle->region);
 
1664
        
 
1665
        if (handle->scrolltimer)
 
1666
                WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), handle->scrolltimer);
 
1667
        
1398
1668
        MEM_freeN(handle);
1399
1669
}
1400
1670
 
1401
1671
/***************************** Menu Button ***************************/
1402
1672
 
1403
 
static void ui_block_func_MENUSTR(bContext *C, uiLayout *layout, void *arg_str)
 
1673
static void ui_block_func_MENUSTR(bContext *UNUSED(C), uiLayout *layout, void *arg_str)
1404
1674
{
1405
 
        uiBlock *block= uiLayoutGetBlock(layout);
1406
 
        uiPopupBlockHandle *handle= block->handle;
1407
 
        uiLayout *split, *column=NULL;
 
1675
        uiBlock *block = uiLayoutGetBlock(layout);
 
1676
        uiPopupBlockHandle *handle = block->handle;
 
1677
        uiLayout *split, *column = NULL;
1408
1678
        uiBut *bt;
1409
1679
        MenuData *md;
1410
1680
        MenuEntry *entry;
1411
 
        char *instr= arg_str;
 
1681
        const char *instr = arg_str;
1412
1682
        int columns, rows, a, b;
 
1683
        int column_start = 0, column_end = 0;
1413
1684
 
1414
1685
        uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
1415
1686
        
1416
1687
        /* compute menu data */
1417
 
        md= decompose_menu_string(instr);
 
1688
        md = decompose_menu_string(instr);
1418
1689
 
1419
1690
        /* columns and row estimation */
1420
 
        columns= (md->nitems+20)/20;
1421
 
        if(columns<1)
1422
 
                columns= 1;
1423
 
        if(columns>8)
1424
 
                columns= (md->nitems+25)/25;
1425
 
        
1426
 
        rows= md->nitems/columns;
1427
 
        if(rows<1)
1428
 
                rows= 1;
1429
 
        while(rows*columns<md->nitems)
 
1691
        columns = (md->nitems + 20) / 20;
 
1692
        if (columns < 1)
 
1693
                columns = 1;
 
1694
        if (columns > 8)
 
1695
                columns = (md->nitems + 25) / 25;
 
1696
 
 
1697
        rows = md->nitems / columns;
 
1698
        if (rows < 1)
 
1699
                rows = 1;
 
1700
        while (rows * columns < md->nitems)
1430
1701
                rows++;
1431
1702
 
1432
1703
        /* create title */
1433
 
        if(md->title) {
1434
 
                if(md->titleicon) {
 
1704
        if (md->title) {
 
1705
                if (md->titleicon) {
1435
1706
                        uiItemL(layout, md->title, md->titleicon);
1436
1707
                }
1437
1708
                else {
1438
 
                        uiItemL(layout, md->title, 0);
1439
 
                        bt= block->buttons.last;
1440
 
                        bt->flag= UI_TEXT_LEFT;
 
1709
                        uiItemL(layout, md->title, ICON_NONE);
 
1710
                        bt = block->buttons.last;
 
1711
                        bt->flag = UI_TEXT_LEFT;
1441
1712
                }
1442
1713
        }
1443
1714
 
1444
1715
        /* inconsistent, but menus with labels do not look good flipped */
1445
 
        for(a=0, b=0; a<md->nitems; a++, b++) {
1446
 
                entry= &md->items[a];
1447
 
 
1448
 
                if(entry->sepr && entry->str[0])
 
1716
        entry = md->items;
 
1717
        for (a = 0; a < md->nitems; a++, entry++) {
 
1718
                if (entry->sepr && entry->str[0]) {
1449
1719
                        block->flag |= UI_BLOCK_NO_FLIP;
 
1720
                        break;
 
1721
                }
1450
1722
        }
1451
1723
 
1452
1724
        /* create items */
1453
 
        split= uiLayoutSplit(layout, 0, 0);
1454
 
 
1455
 
        for(a=0, b=0; a<md->nitems; a++, b++) {
1456
 
                if(block->flag & UI_BLOCK_NO_FLIP)
1457
 
                        entry= &md->items[a];
 
1725
        split = uiLayoutSplit(layout, 0, 0);
 
1726
 
 
1727
        for (a = 0; a < md->nitems; a++) {
 
1728
                if (a == column_end) {
 
1729
                        /* start new column, and find out where it ends in advance, so we
 
1730
                         * can flip the order of items properly per column */
 
1731
                        column_start = a;
 
1732
                        column_end = md->nitems;
 
1733
 
 
1734
                        for (b = a + 1; b < md->nitems; b++) {
 
1735
                                entry = &md->items[b];
 
1736
 
 
1737
                                /* new column on N rows or on separation label */
 
1738
                                if (((b - a) % rows == 0) || (entry->sepr && entry->str[0])) {
 
1739
                                        column_end = b;
 
1740
                                        break;
 
1741
                                }
 
1742
                        }
 
1743
 
 
1744
                        column = uiLayoutColumn(split, 0);
 
1745
                }
 
1746
 
 
1747
                if (block->flag & UI_BLOCK_NO_FLIP)
 
1748
                        entry = &md->items[a];
1458
1749
                else
1459
 
                        entry= &md->items[md->nitems-a-1];
1460
 
                
1461
 
                /* new column on N rows or on separation label */
1462
 
                if((b % rows == 0) || (entry->sepr && entry->str[0])) {
1463
 
                        column= uiLayoutColumn(split, 0);
1464
 
                        b= 0;
1465
 
                }
 
1750
                        entry = &md->items[column_start + column_end - 1 - a];
1466
1751
 
1467
 
                if(entry->sepr) {
 
1752
                if (entry->sepr) {
1468
1753
                        uiItemL(column, entry->str, entry->icon);
1469
 
                        bt= block->buttons.last;
1470
 
                        bt->flag= UI_TEXT_LEFT;
 
1754
                        bt = block->buttons.last;
 
1755
                        bt->flag = UI_TEXT_LEFT;
1471
1756
                }
1472
 
                else if(entry->icon) {
1473
 
                        uiDefIconTextButF(block, BUTM|FLO, B_NOP, entry->icon, entry->str, 0, 0,
1474
 
                                UI_UNIT_X*5, UI_UNIT_Y, &handle->retvalue, (float) entry->retval, 0.0, 0, 0, "");
 
1757
                else if (entry->icon) {
 
1758
                        uiDefIconTextButF(block, BUTM | FLO, B_NOP, entry->icon, entry->str, 0, 0,
 
1759
                                          UI_UNIT_X * 5, UI_UNIT_Y, &handle->retvalue, (float) entry->retval, 0.0, 0, 0, "");
1475
1760
                }
1476
1761
                else {
1477
 
                        uiDefButF(block, BUTM|FLO, B_NOP, entry->str, 0, 0,
1478
 
                                UI_UNIT_X*5, UI_UNIT_X, &handle->retvalue, (float) entry->retval, 0.0, 0, 0, "");
 
1762
                        uiDefButF(block, BUTM | FLO, B_NOP, entry->str, 0, 0,
 
1763
                                  UI_UNIT_X * 5, UI_UNIT_X, &handle->retvalue, (float) entry->retval, 0.0, 0, 0, "");
1479
1764
                }
1480
1765
        }
1481
1766
        
1482
1767
        menudata_free(md);
1483
1768
}
1484
1769
 
1485
 
void ui_block_func_ICONROW(bContext *C, uiLayout *layout, void *arg_but)
 
1770
void ui_block_func_ICONROW(bContext *UNUSED(C), uiLayout *layout, void *arg_but)
1486
1771
{
1487
 
        uiBlock *block= uiLayoutGetBlock(layout);
1488
 
        uiPopupBlockHandle *handle= block->handle;
1489
 
        uiBut *but= arg_but;
 
1772
        uiBlock *block = uiLayoutGetBlock(layout);
 
1773
        uiPopupBlockHandle *handle = block->handle;
 
1774
        uiBut *but = arg_but;
1490
1775
        int a;
1491
1776
        
1492
1777
        uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
1493
1778
        
1494
 
        for(a=(int)but->hardmin; a<=(int)but->hardmax; a++)
1495
 
                uiDefIconButF(block, BUTM|FLO, B_NOP, but->icon+(a-but->hardmin), 0, 0, UI_UNIT_X*5, UI_UNIT_Y,
1496
 
                        &handle->retvalue, (float)a, 0.0, 0, 0, "");
 
1779
        for (a = (int)but->hardmin; a <= (int)but->hardmax; a++)
 
1780
                uiDefIconButF(block, BUTM | FLO, B_NOP, but->icon + (a - but->hardmin), 0, 0, UI_UNIT_X * 5, UI_UNIT_Y,
 
1781
                              &handle->retvalue, (float)a, 0.0, 0, 0, "");
1497
1782
}
1498
1783
 
1499
 
void ui_block_func_ICONTEXTROW(bContext *C, uiLayout *layout, void *arg_but)
 
1784
void ui_block_func_ICONTEXTROW(bContext *UNUSED(C), uiLayout *layout, void *arg_but)
1500
1785
{
1501
 
        uiBlock *block= uiLayoutGetBlock(layout);
1502
 
        uiPopupBlockHandle *handle= block->handle;
1503
 
        uiBut *but= arg_but, *bt;
 
1786
        uiBlock *block = uiLayoutGetBlock(layout);
 
1787
        uiPopupBlockHandle *handle = block->handle;
 
1788
        uiBut *but = arg_but, *bt;
1504
1789
        MenuData *md;
1505
1790
        MenuEntry *entry;
1506
1791
        int a;
1507
1792
        
1508
1793
        uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
1509
1794
 
1510
 
        md= decompose_menu_string(but->str);
 
1795
        md = decompose_menu_string(but->str);
1511
1796
 
1512
1797
        /* title */
1513
 
        if(md->title) {
1514
 
                bt= uiDefBut(block, LABEL, 0, md->title, 0, 0, UI_UNIT_X*5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
1515
 
                bt->flag= UI_TEXT_LEFT;
 
1798
        if (md->title) {
 
1799
                bt = uiDefBut(block, LABEL, 0, md->title, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
 
1800
                bt->flag = UI_TEXT_LEFT;
1516
1801
        }
1517
1802
 
1518
1803
        /* loop through the menu options and draw them out with icons & text labels */
1519
 
        for(a=0; a<md->nitems; a++) {
1520
 
                entry= &md->items[md->nitems-a-1];
 
1804
        for (a = 0; a < md->nitems; a++) {
 
1805
                entry = &md->items[md->nitems - a - 1];
1521
1806
 
1522
 
                if(entry->sepr)
 
1807
                if (entry->sepr)
1523
1808
                        uiItemS(layout);
1524
1809
                else
1525
 
                        uiDefIconTextButF(block, BUTM|FLO, B_NOP, (short)((but->icon)+(entry->retval-but->hardmin)), entry->str,
1526
 
                                0, 0, UI_UNIT_X*5, UI_UNIT_Y, &handle->retvalue, (float) entry->retval, 0.0, 0, 0, "");
 
1810
                        uiDefIconTextButF(block, BUTM | FLO, B_NOP, (short)((but->icon) + (entry->retval - but->hardmin)), entry->str,
 
1811
                                          0, 0, UI_UNIT_X * 5, UI_UNIT_Y, &handle->retvalue, (float) entry->retval, 0.0, 0, 0, "");
1527
1812
        }
1528
1813
 
1529
1814
        menudata_free(md);
1530
1815
}
1531
1816
 
1532
1817
#if 0
1533
 
static void ui_warp_pointer(short x, short y)
 
1818
static void ui_warp_pointer(int x, int y)
1534
1819
{
1535
1820
        /* XXX 2.50 which function to use for this? */
1536
 
        /* OSX has very poor mousewarp support, it sends events;
1537
 
           this causes a menu being pressed immediately ... */
1538
 
        #ifndef __APPLE__
 
1821
        /* OSX has very poor mouse-warp support, it sends events;
 
1822
         * this causes a menu being pressed immediately ... */
 
1823
#  ifndef __APPLE__
1539
1824
        warp_pointer(x, y);
1540
 
        #endif
 
1825
#  endif
1541
1826
}
1542
1827
#endif
1543
1828
 
1544
1829
/********************* Color Button ****************/
1545
1830
 
1546
1831
/* picker sizes S hsize, F full size, D spacer, B button/pallette height  */
1547
 
#define SPICK   110.0
1548
 
#define FPICK   180.0
1549
 
#define DPICK   6.0
1550
 
#define BPICK   24.0
 
1832
#define SPICK   110.0
 
1833
#define FPICK   180.0
 
1834
#define DPICK   6.0
 
1835
#define BPICK   24.0
1551
1836
 
1552
1837
/* for picker, while editing hsv */
1553
1838
void ui_set_but_hsv(uiBut *but)
1554
1839
{
1555
1840
        float col[3];
 
1841
        float *hsv = ui_block_hsv_get(but->block);
1556
1842
        
1557
 
        hsv_to_rgb(but->hsv[0], but->hsv[1], but->hsv[2], col, col+1, col+2);
 
1843
        hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col + 1, col + 2);
1558
1844
        ui_set_but_vectorf(but, col);
1559
1845
}
1560
1846
 
1561
1847
/* also used by small picker, be careful with name checks below... */
1562
 
void ui_update_block_buts_rgb(uiBlock *block, float *rgb, float *rhsv)
 
1848
static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3])
1563
1849
{
1564
1850
        uiBut *bt;
1565
 
        float hsv[3];
 
1851
        float *hsv = ui_block_hsv_get(block);
1566
1852
        
1567
1853
        /* this is to keep the H and S value when V is equal to zero
1568
1854
         * and we are working in HSV mode, of course!
1569
1855
         */
1570
 
        if (rhsv) {
1571
 
                hsv[0]= rhsv[0];
1572
 
                hsv[1]= rhsv[1];
1573
 
                hsv[2]= rhsv[2];
1574
 
        }
1575
 
        else
1576
 
                rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
 
1856
        rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], hsv, hsv + 1, hsv + 2);
1577
1857
        
1578
1858
        // this updates button strings, is hackish... but button pointers are on stack of caller function
1579
 
        for(bt= block->buttons.first; bt; bt= bt->next) {
 
1859
        for (bt = block->buttons.first; bt; bt = bt->next) {
1580
1860
                if (bt->rnaprop) {
1581
1861
                        
1582
1862
                        ui_set_but_vectorf(bt, rgb);
1583
1863
                        
1584
1864
                }
1585
 
                else if(strcmp(bt->str, "Hex: ")==0) {
 
1865
                else if (strcmp(bt->str, "Hex: ") == 0) {
1586
1866
                        float rgb_gamma[3];
1587
1867
                        double intpart;
1588
1868
                        char col[16];
1591
1871
                        
1592
1872
                        if (block->color_profile == BLI_PR_NONE) {
1593
1873
                                copy_v3_v3(rgb_gamma, rgb);
1594
 
                        } else {
 
1874
                        }
 
1875
                        else {
1595
1876
                                /* make an sRGB version, for Hex code */
1596
1877
                                linearrgb_to_srgb_v3_v3(rgb_gamma, rgb);
1597
1878
                        }
1600
1881
                        if (rgb_gamma[1] > 1.0f) rgb_gamma[1] = modf(rgb_gamma[1], &intpart);
1601
1882
                        if (rgb_gamma[2] > 1.0f) rgb_gamma[2] = modf(rgb_gamma[2], &intpart);
1602
1883
 
1603
 
                        sprintf(col, "%02X%02X%02X", FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2]));
 
1884
                        BLI_snprintf(col, sizeof(col), "%02X%02X%02X", FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2]));
1604
1885
                        
1605
1886
                        strcpy(bt->poin, col);
1606
1887
                }
1607
 
                else if(bt->str[1]==' ') {
1608
 
                        if(bt->str[0]=='R') {
 
1888
                else if (bt->str[1] == ' ') {
 
1889
                        if (bt->str[0] == 'R') {
1609
1890
                                ui_set_but_val(bt, rgb[0]);
1610
1891
                        }
1611
 
                        else if(bt->str[0]=='G') {
 
1892
                        else if (bt->str[0] == 'G') {
1612
1893
                                ui_set_but_val(bt, rgb[1]);
1613
1894
                        }
1614
 
                        else if(bt->str[0]=='B') {
 
1895
                        else if (bt->str[0] == 'B') {
1615
1896
                                ui_set_but_val(bt, rgb[2]);
1616
1897
                        }
1617
 
                        else if(bt->str[0]=='H') {
 
1898
                        else if (bt->str[0] == 'H') {
1618
1899
                                ui_set_but_val(bt, hsv[0]);
1619
1900
                        }
1620
 
                        else if(bt->str[0]=='S') {
 
1901
                        else if (bt->str[0] == 'S') {
1621
1902
                                ui_set_but_val(bt, hsv[1]);
1622
1903
                        }
1623
 
                        else if(bt->str[0]=='V') {
 
1904
                        else if (bt->str[0] == 'V') {
1624
1905
                                ui_set_but_val(bt, hsv[2]);
1625
1906
                        }
1626
1907
                }               
1629
1910
        }
1630
1911
}
1631
1912
 
1632
 
static void do_picker_rna_cb(bContext *C, void *bt1, void *unused)
 
1913
static void do_picker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
1633
1914
{
1634
 
        uiBut *but= (uiBut *)bt1;
1635
 
        uiPopupBlockHandle *popup= but->block->handle;
 
1915
        uiBut *but = (uiBut *)bt1;
 
1916
        uiPopupBlockHandle *popup = but->block->handle;
1636
1917
        PropertyRNA *prop = but->rnaprop;
1637
1918
        PointerRNA ptr = but->rnapoin;
1638
1919
        float rgb[4];
1639
1920
        
1640
1921
        if (prop) {
1641
1922
                RNA_property_float_get_array(&ptr, prop, rgb);
1642
 
                ui_update_block_buts_rgb(but->block, rgb, NULL);
 
1923
                ui_update_block_buts_rgb(but->block, rgb);
1643
1924
        }
1644
1925
        
1645
 
        if(popup)
1646
 
                popup->menuretval= UI_RETURN_UPDATE;
1647
 
}
1648
 
 
1649
 
static void do_hsv_rna_cb(bContext *C, void *bt1, void *hsv_arg)
1650
 
{
1651
 
        uiBut *but= (uiBut *)bt1;
1652
 
        uiPopupBlockHandle *popup= but->block->handle;
1653
 
        float *hsv = (float *)hsv_arg;
1654
 
        float rgb[3];
1655
 
        
1656
 
        hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
1657
 
        
1658
 
        ui_update_block_buts_rgb(but->block, rgb, hsv);
1659
 
        
1660
 
        if(popup)
1661
 
                popup->menuretval= UI_RETURN_UPDATE;
1662
 
}
1663
 
 
1664
 
static void do_hex_rna_cb(bContext *C, void *bt1, void *hexcl)
1665
 
{
1666
 
        uiBut *but= (uiBut *)bt1;
1667
 
        uiPopupBlockHandle *popup= but->block->handle;
1668
 
        char *hexcol= (char *)hexcl;
1669
 
        float rgb[3];
1670
 
        
1671
 
        hex_to_rgb(hexcol, rgb, rgb+1, rgb+2);
 
1926
        if (popup)
 
1927
                popup->menuretval = UI_RETURN_UPDATE;
 
1928
}
 
1929
 
 
1930
static void do_hsv_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
 
1931
{
 
1932
        uiBut *but = (uiBut *)bt1;
 
1933
        uiPopupBlockHandle *popup = but->block->handle;
 
1934
        float rgb[3];
 
1935
        float *hsv = ui_block_hsv_get(but->block);
 
1936
        
 
1937
        hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2);
 
1938
        
 
1939
        ui_update_block_buts_rgb(but->block, rgb);
 
1940
        
 
1941
        if (popup)
 
1942
                popup->menuretval = UI_RETURN_UPDATE;
 
1943
}
 
1944
 
 
1945
static void do_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexcl)
 
1946
{
 
1947
        uiBut *but = (uiBut *)bt1;
 
1948
        uiPopupBlockHandle *popup = but->block->handle;
 
1949
        char *hexcol = (char *)hexcl;
 
1950
        float rgb[3];
 
1951
        
 
1952
        hex_to_rgb(hexcol, rgb, rgb + 1, rgb + 2);
1672
1953
        
1673
1954
        /* Hex code is assumed to be in sRGB space (coming from other applications, web, etc) */
1674
1955
        if (but->block->color_profile != BLI_PR_NONE) {
1676
1957
                srgb_to_linearrgb_v3_v3(rgb, rgb);
1677
1958
        }
1678
1959
        
1679
 
        ui_update_block_buts_rgb(but->block, rgb, NULL);
 
1960
        ui_update_block_buts_rgb(but->block, rgb);
1680
1961
        
1681
 
        if(popup)
1682
 
                popup->menuretval= UI_RETURN_UPDATE;
 
1962
        if (popup)
 
1963
                popup->menuretval = UI_RETURN_UPDATE;
1683
1964
}
1684
1965
 
1685
 
static void close_popup_cb(bContext *C, void *bt1, void *arg)
 
1966
static void close_popup_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
1686
1967
{
1687
 
        uiBut *but= (uiBut *)bt1;
1688
 
        uiPopupBlockHandle *popup= but->block->handle;
 
1968
        uiBut *but = (uiBut *)bt1;
 
1969
        uiPopupBlockHandle *popup = but->block->handle;
1689
1970
        
1690
 
        if(popup)
1691
 
                popup->menuretval= UI_RETURN_OK;
 
1971
        if (popup)
 
1972
                popup->menuretval = UI_RETURN_OK;
1692
1973
}
1693
1974
 
1694
1975
static void picker_new_hide_reveal(uiBlock *block, short colormode)
1696
1977
        uiBut *bt;
1697
1978
        
1698
1979
        /* tag buttons */
1699
 
        for(bt= block->buttons.first; bt; bt= bt->next) {
 
1980
        for (bt = block->buttons.first; bt; bt = bt->next) {
1700
1981
                
1701
1982
                if (bt->type == LABEL) {
1702
 
                        if( bt->str[1]=='G') {
1703
 
                                if(colormode==2) bt->flag &= ~UI_HIDDEN;
 
1983
                        if (bt->str[1] == 'G') {
 
1984
                                if (colormode == 2) bt->flag &= ~UI_HIDDEN;
1704
1985
                                else bt->flag |= UI_HIDDEN;
1705
1986
                        }
1706
1987
                }
1707
1988
                
1708
 
                if(bt->type==NUMSLI || bt->type==TEX) {
1709
 
                        if( bt->str[1]=='e') {
1710
 
                                if(colormode==2) bt->flag &= ~UI_HIDDEN;
1711
 
                                else bt->flag |= UI_HIDDEN;
1712
 
                        }
1713
 
                        else if( ELEM3(bt->str[0], 'R', 'G', 'B')) {
1714
 
                                if(colormode==0) bt->flag &= ~UI_HIDDEN;
1715
 
                                else bt->flag |= UI_HIDDEN;
1716
 
                        }
1717
 
                        else if( ELEM3(bt->str[0], 'H', 'S', 'V')) {
1718
 
                                if(colormode==1) bt->flag &= ~UI_HIDDEN;
 
1989
                if (bt->type == NUMSLI || bt->type == TEX) {
 
1990
                        if (bt->str[1] == 'e') {
 
1991
                                if (colormode == 2) bt->flag &= ~UI_HIDDEN;
 
1992
                                else bt->flag |= UI_HIDDEN;
 
1993
                        }
 
1994
                        else if (ELEM3(bt->str[0], 'R', 'G', 'B')) {
 
1995
                                if (colormode == 0) bt->flag &= ~UI_HIDDEN;
 
1996
                                else bt->flag |= UI_HIDDEN;
 
1997
                        }
 
1998
                        else if (ELEM3(bt->str[0], 'H', 'S', 'V')) {
 
1999
                                if (colormode == 1) bt->flag &= ~UI_HIDDEN;
1719
2000
                                else bt->flag |= UI_HIDDEN;
1720
2001
                        }
1721
2002
                }
1722
2003
        }
1723
2004
}
1724
2005
 
1725
 
static void do_picker_new_mode_cb(bContext *C, void *bt1, void *colv)
 
2006
static void do_picker_new_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
1726
2007
{
1727
 
        uiBut *bt= bt1;
1728
 
        short colormode= ui_get_but_val(bt);
 
2008
        uiBut *bt = bt1;
 
2009
        short colormode = ui_get_but_val(bt);
1729
2010
        picker_new_hide_reveal(bt->block, colormode);
1730
2011
}
1731
2012
 
1732
2013
/* picker sizes S hsize, F full size, D spacer, B button/pallette height  */
1733
 
#define SPICK1  150.0
1734
 
#define DPICK1  6.0
1735
 
 
1736
 
#define PICKER_H        150
1737
 
#define PICKER_W        150
1738
 
#define PICKER_SPACE    6
1739
 
#define PICKER_BAR              14
1740
 
 
1741
 
#define PICKER_TOTAL_W  (PICKER_W+PICKER_SPACE+PICKER_BAR)
1742
 
 
1743
 
static void circle_picker(uiBlock *block, PointerRNA *ptr, const char *propname)
 
2014
#define SPICK1  150.0
 
2015
#define DPICK1  6.0
 
2016
 
 
2017
#define PICKER_H    150
 
2018
#define PICKER_W    150
 
2019
#define PICKER_SPACE    6
 
2020
#define PICKER_BAR      14
 
2021
 
 
2022
#define PICKER_TOTAL_W  (PICKER_W + PICKER_SPACE + PICKER_BAR)
 
2023
 
 
2024
static void circle_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop)
1744
2025
{
1745
2026
        uiBut *bt;
1746
2027
        
1747
2028
        /* HS circle */
1748
 
        bt= uiDefButR(block, HSVCIRCLE, 0, "",  0, 0, PICKER_H, PICKER_W, ptr, propname, 0, 0.0, 0.0, 0, 0, "Color");
 
2029
        bt = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, 0, 0.0, 0.0, 0, 0, "Color");
1749
2030
        uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
1750
2031
        
1751
2032
        /* value */
1752
 
        bt= uiDefButR(block, HSVCUBE, 0, "", PICKER_W+PICKER_SPACE,0,PICKER_BAR,PICKER_H, ptr, propname, 0, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value");
 
2033
        bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, 0, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value");
1753
2034
        uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
1754
2035
}
1755
2036
 
1756
2037
 
1757
 
static void square_picker(uiBlock *block, PointerRNA *ptr, const char *propname, int type)
 
2038
static void square_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int type)
1758
2039
{
1759
2040
        uiBut *bt;
1760
2041
        int bartype = type + 3;
1761
2042
        
1762
2043
        /* HS square */
1763
 
        bt= uiDefButR(block, HSVCUBE, 0, "",    0, PICKER_BAR+PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, propname, 0, 0.0, 0.0, type, 0, "Color");
 
2044
        bt = uiDefButR_prop(block, HSVCUBE, 0, "",   0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, 0, 0.0, 0.0, type, 0, "Color");
1764
2045
        uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
1765
2046
        
1766
2047
        /* value */
1767
 
        bt= uiDefButR(block, HSVCUBE, 0, "",            0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, propname, 0, 0.0, 0.0, bartype, 0, "Value");
 
2048
        bt = uiDefButR_prop(block, HSVCUBE, 0, "",       0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, 0, 0.0, 0.0, bartype, 0, "Value");
1768
2049
        uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
1769
2050
}
1770
2051
 
1771
2052
 
1772
2053
/* a HS circle, V slider, rgb/hsv/hex sliders */
1773
 
static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyRNA *prop)
 
2054
static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, PropertyRNA *prop)
1774
2055
{
1775
 
        static short colormode= 0;      /* temp? 0=rgb, 1=hsv, 2=hex */
 
2056
        static short colormode = 0;  /* temp? 0=rgb, 1=hsv, 2=hex */
1776
2057
        uiBut *bt;
1777
2058
        int width, butwidth;
1778
2059
        static char tip[50];
1779
 
        static float hsv[3];
1780
2060
        static char hexcol[128];
1781
2061
        float rgb_gamma[3];
1782
2062
        float min, max, step, precision;
1783
 
        const char *propname = RNA_property_identifier(prop);
1784
 
        
1785
 
        width= PICKER_TOTAL_W;
 
2063
        float *hsv = ui_block_hsv_get(block);
 
2064
        
 
2065
        ui_block_hsv_get(block);
 
2066
        
 
2067
        width = PICKER_TOTAL_W;
1786
2068
        butwidth = width - UI_UNIT_X - 10;
1787
2069
        
1788
 
        /* existence of profile means storage is in linear colour space, with display correction */
 
2070
        /* existence of profile means storage is in linear color space, with display correction */
 
2071
        /* XXX That tip message is not use anywhere! */
1789
2072
        if (block->color_profile == BLI_PR_NONE) {
1790
 
                sprintf(tip, "Value in Display Color Space");
1791
 
                copy_v3_v3(rgb_gamma, rgb);
1792
 
        } else {
1793
 
                sprintf(tip, "Value in Linear RGB Color Space");
 
2073
                BLI_strncpy(tip, N_("Value in Display Color Space"), sizeof(tip));
 
2074
                copy_v3_v3(rgb_gamma, rgba);
 
2075
        }
 
2076
        else {
 
2077
                BLI_strncpy(tip, N_("Value in Linear RGB Color Space"), sizeof(tip));
1794
2078
                /* make an sRGB version, for Hex code */
1795
 
                linearrgb_to_srgb_v3_v3(rgb_gamma, rgb);
 
2079
                linearrgb_to_srgb_v3_v3(rgb_gamma, rgba);
1796
2080
        }
1797
2081
        
1798
2082
        /* sneaky way to check for alpha */
1799
 
        rgb[3]= FLT_MAX;
 
2083
        rgba[3] = FLT_MAX;
1800
2084
 
1801
2085
        RNA_property_float_ui_range(ptr, prop, &min, &max, &step, &precision);
1802
 
        RNA_property_float_get_array(ptr, prop, rgb);
1803
 
        rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
 
2086
        RNA_property_float_get_array(ptr, prop, rgba);
1804
2087
 
1805
2088
        switch (U.color_picker_type) {
1806
2089
                case USER_CP_CIRCLE:
1807
 
                        circle_picker(block, ptr, propname);
 
2090
                        circle_picker(block, ptr, prop);
1808
2091
                        break;
1809
2092
                case USER_CP_SQUARE_SV:
1810
 
                        square_picker(block, ptr, propname, UI_GRAD_SV);
 
2093
                        square_picker(block, ptr, prop, UI_GRAD_SV);
1811
2094
                        break;
1812
2095
                case USER_CP_SQUARE_HS:
1813
 
                        square_picker(block, ptr, propname, UI_GRAD_HS);
 
2096
                        square_picker(block, ptr, prop, UI_GRAD_HS);
1814
2097
                        break;
1815
2098
                case USER_CP_SQUARE_HV:
1816
 
                        square_picker(block, ptr, propname, UI_GRAD_HV);
 
2099
                        square_picker(block, ptr, prop, UI_GRAD_HV);
1817
2100
                        break;
1818
2101
        }
1819
2102
        
1820
2103
        /* mode */
1821
2104
        uiBlockBeginAlign(block);
1822
 
        bt= uiDefButS(block, ROW, 0, "RGB",     0, -30, width/3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, "");
1823
 
        uiButSetFunc(bt, do_picker_new_mode_cb, bt, rgb);
1824
 
        bt= uiDefButS(block, ROW, 0, "HSV",     width/3, -30, width/3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
1825
 
        uiButSetFunc(bt, do_picker_new_mode_cb, bt, hsv);
1826
 
        bt= uiDefButS(block, ROW, 0, "Hex",     2*width/3, -30, width/3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, "");
1827
 
        uiButSetFunc(bt, do_picker_new_mode_cb, bt, hexcol);
 
2105
        bt = uiDefButS(block, ROW, 0, IFACE_("RGB"), 0, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, "");
 
2106
        uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
 
2107
        bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
 
2108
        uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
 
2109
        bt = uiDefButS(block, ROW, 0, IFACE_("Hex"), 2 * width / 3, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, "");
 
2110
        uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
1828
2111
        uiBlockEndAlign(block);
1829
2112
 
1830
 
        bt= uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth+10, -60, UI_UNIT_X, UI_UNIT_Y, NULL);
 
2113
        bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, -60, UI_UNIT_X, UI_UNIT_Y, NULL);
1831
2114
        uiButSetFunc(bt, close_popup_cb, bt, NULL);
1832
2115
        
1833
2116
        /* RGB values */
1834
2117
        uiBlockBeginAlign(block);
1835
 
        bt= uiDefButR(block, NUMSLI, 0, "R ",   0, -60, butwidth, UI_UNIT_Y, ptr, propname, 0, 0.0, 0.0, 0, 3, "Red");
1836
 
        uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
1837
 
        bt= uiDefButR(block, NUMSLI, 0, "G ",   0, -80, butwidth, UI_UNIT_Y, ptr, propname, 1, 0.0, 0.0, 0, 3, "Green");
1838
 
        uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
1839
 
        bt= uiDefButR(block, NUMSLI, 0, "B ",   0, -100, butwidth, UI_UNIT_Y, ptr, propname, 2, 0.0, 0.0, 0, 3, "Blue");
 
2118
        bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("R "),  0, -60, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red"));
 
2119
        uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
 
2120
        bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("G "),  0, -80, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green"));
 
2121
        uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
 
2122
        bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("B "),  0, -100, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue"));
1840
2123
        uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
1841
2124
 
1842
 
        // could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", 0);
 
2125
        // could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", ICON_NONE);
1843
2126
        // but need to use uiButSetFunc for updating other fake buttons
1844
2127
        
1845
2128
        /* HSV values */
1846
2129
        uiBlockBeginAlign(block);
1847
 
        bt= uiDefButF(block, NUMSLI, 0, "H ",   0, -60, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, "Hue");
1848
 
        uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
1849
 
        bt= uiDefButF(block, NUMSLI, 0, "S ",   0, -80, butwidth, UI_UNIT_Y, hsv+1, 0.0, 1.0, 10, 3, "Saturation");
1850
 
        uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
1851
 
        bt= uiDefButF(block, NUMSLI, 0, "V ",   0, -100, butwidth, UI_UNIT_Y, hsv+2, 0.0, max, 10, 3, "Value");
 
2130
        bt = uiDefButF(block, NUMSLI, 0, IFACE_("H "),   0, -60, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue"));
 
2131
        uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
 
2132
        bt = uiDefButF(block, NUMSLI, 0, IFACE_("S "),   0, -80, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation"));
 
2133
        uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
 
2134
        bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "),   0, -100, butwidth, UI_UNIT_Y, hsv + 2, 0.0, max, 10, 3, TIP_("Value"));
1852
2135
        uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
1853
2136
        uiBlockEndAlign(block);
1854
2137
 
1855
 
        if(rgb[3] != FLT_MAX) {
1856
 
                bt= uiDefButR(block, NUMSLI, 0, "A ",   0, -120, butwidth, UI_UNIT_Y, ptr, propname, 3, 0.0, 0.0, 0, 0, "Alpha");
 
2138
        if (rgba[3] != FLT_MAX) {
 
2139
                bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("A "),  0, -120, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 0, TIP_("Alpha"));
1857
2140
                uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
1858
2141
        }
1859
2142
        else {
1860
 
                rgb[3]= 1.0f;
 
2143
                rgba[3] = 1.0f;
1861
2144
        }
1862
2145
 
1863
 
        rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
1864
 
 
1865
 
        sprintf(hexcol, "%02X%02X%02X", FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2]));
1866
 
 
1867
 
        bt= uiDefBut(block, TEX, 0, "Hex: ", 0, -60, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, "Hex triplet for color (#RRGGBB)");
 
2146
        BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2]));
 
2147
 
 
2148
        bt = uiDefBut(block, TEX, 0, IFACE_("Hex: "), 0, -60, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)"));
1868
2149
        uiButSetFunc(bt, do_hex_rna_cb, bt, hexcol);
1869
 
        uiDefBut(block, LABEL, 0, "(Gamma Corrected)", 0, -80, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
 
2150
        uiDefBut(block, LABEL, 0, IFACE_("(Gamma Corrected)"), 0, -80, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
 
2151
 
 
2152
        rgb_to_hsv(rgba[0], rgba[1], rgba[2], hsv, hsv + 1, hsv + 2);
1870
2153
 
1871
2154
        picker_new_hide_reveal(block, colormode);
1872
2155
}
1873
2156
 
1874
2157
 
1875
 
static int ui_picker_small_wheel(const bContext *C, uiBlock *block, wmEvent *event)
 
2158
static int ui_picker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, wmEvent *event)
1876
2159
{
1877
 
        float add= 0.0f;
1878
 
        
1879
 
        if(event->type==WHEELUPMOUSE)
1880
 
                add= 0.05f;
1881
 
        else if(event->type==WHEELDOWNMOUSE)
1882
 
                add= -0.05f;
1883
 
        
1884
 
        if(add!=0.0f) {
 
2160
        float add = 0.0f;
 
2161
        
 
2162
        if (event->type == WHEELUPMOUSE)
 
2163
                add = 0.05f;
 
2164
        else if (event->type == WHEELDOWNMOUSE)
 
2165
                add = -0.05f;
 
2166
        
 
2167
        if (add != 0.0f) {
1885
2168
                uiBut *but;
1886
2169
                
1887
 
                for(but= block->buttons.first; but; but= but->next) {
1888
 
                        if(but->type==HSVCUBE && but->active==NULL) {
1889
 
                                uiPopupBlockHandle *popup= block->handle;
 
2170
                for (but = block->buttons.first; but; but = but->next) {
 
2171
                        if (but->type == HSVCUBE && but->active == NULL) {
 
2172
                                uiPopupBlockHandle *popup = block->handle;
1890
2173
                                float col[3];
 
2174
                                float *hsv = ui_block_hsv_get(block);
1891
2175
                                
1892
2176
                                ui_get_but_vectorf(but, col);
1893
2177
                                
1894
 
                                rgb_to_hsv(col[0], col[1], col[2], but->hsv, but->hsv+1, but->hsv+2);
1895
 
                                but->hsv[2]= CLAMPIS(but->hsv[2]+add, 0.0f, 1.0f);
1896
 
                                hsv_to_rgb(but->hsv[0], but->hsv[1], but->hsv[2], col, col+1, col+2);
 
2178
                                rgb_to_hsv_compat(col[0], col[1], col[2], hsv, hsv + 1, hsv + 2);
 
2179
                                hsv[2] = CLAMPIS(hsv[2] + add, 0.0f, 1.0f);
 
2180
                                hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col + 1, col + 2);
1897
2181
 
1898
2182
                                ui_set_but_vectorf(but, col);
1899
2183
                                
1900
 
                                ui_update_block_buts_rgb(block, col, NULL);
1901
 
                                if(popup)
1902
 
                                        popup->menuretval= UI_RETURN_UPDATE;
 
2184
                                ui_update_block_buts_rgb(block, col);
 
2185
                                if (popup)
 
2186
                                        popup->menuretval = UI_RETURN_UPDATE;
1903
2187
                                
1904
2188
                                return 1;
1905
2189
                        }
1910
2194
 
1911
2195
uiBlock *ui_block_func_COL(bContext *C, uiPopupBlockHandle *handle, void *arg_but)
1912
2196
{
1913
 
        uiBut *but= arg_but;
 
2197
        uiBut *but = arg_but;
1914
2198
        uiBlock *block;
1915
2199
        
1916
 
        block= uiBeginBlock(C, handle->region, "colorpicker", UI_EMBOSS);
 
2200
        block = uiBeginBlock(C, handle->region, __func__, UI_EMBOSS);
1917
2201
        
1918
2202
        if (but->rnaprop) {
1919
2203
                if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
1923
2207
        
1924
2208
        uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
1925
2209
        
1926
 
        VECCOPY(handle->retvec, but->editvec);
1927
 
 
 
2210
        copy_v3_v3(handle->retvec, but->editvec);
 
2211
        
1928
2212
        uiBlockPicker(block, handle->retvec, &but->rnapoin, but->rnaprop);
1929
 
        block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN;
 
2213
        
 
2214
        block->flag = UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_KEEP_OPEN | UI_BLOCK_OUT_1;
1930
2215
        uiBoundsBlock(block, 10);
1931
2216
        
1932
 
        block->block_event_func= ui_picker_small_wheel;
 
2217
        block->block_event_func = ui_picker_small_wheel_cb;
1933
2218
        
1934
2219
        /* and lets go */
1935
 
        block->direction= UI_TOP;
 
2220
        block->direction = UI_TOP;
1936
2221
        
1937
2222
        return block;
1938
2223
}
1943
2228
{
1944
2229
        /* sometimes button contains hotkey, sometimes not, strip for proper compare */
1945
2230
        int hash;
1946
 
        char *delimit= strchr(str, '|');
 
2231
        char *delimit = strchr(str, '|');
1947
2232
 
1948
 
        if(delimit) *delimit= 0;
1949
 
        hash= BLI_ghashutil_strhash(str);
1950
 
        if(delimit) *delimit= '|';
 
2233
        if (delimit) *delimit = 0;
 
2234
        hash = BLI_ghashutil_strhash(str);
 
2235
        if (delimit) *delimit = '|';
1951
2236
 
1952
2237
        return hash;
1953
2238
}
1954
2239
 
1955
 
static int ui_popup_menu_hash(char *str)
 
2240
static int ui_popup_menu_hash(const char *str)
1956
2241
{
1957
2242
        return BLI_ghashutil_strhash(str);
1958
2243
}
1960
2245
/* but == NULL read, otherwise set */
1961
2246
uiBut *ui_popup_menu_memory(uiBlock *block, uiBut *but)
1962
2247
{
1963
 
        static int mem[256], first=1;
1964
 
        int hash= block->puphash;
 
2248
        static int mem[256], first = 1;
 
2249
        int hash = block->puphash;
1965
2250
        
1966
 
        if(first) {
 
2251
        if (first) {
1967
2252
                /* init */
1968
2253
                memset(mem, -1, sizeof(mem));
1969
 
                first= 0;
 
2254
                first = 0;
1970
2255
        }
1971
2256
 
1972
 
        if(but) {
 
2257
        if (but) {
1973
2258
                /* set */
1974
 
                mem[hash & 255 ]= ui_popup_string_hash(but->str);
 
2259
                mem[hash & 255] = ui_popup_string_hash(but->str);
1975
2260
                return NULL;
1976
2261
        }
1977
2262
        else {
1978
2263
                /* get */
1979
 
                for(but=block->buttons.first; but; but=but->next)
1980
 
                        if(ui_popup_string_hash(but->str) == mem[hash & 255])
 
2264
                for (but = block->buttons.first; but; but = but->next)
 
2265
                        if (ui_popup_string_hash(but->str) == mem[hash & 255])
1981
2266
                                return but;
1982
2267
 
1983
2268
                return NULL;
2002
2287
{
2003
2288
        uiBlock *block;
2004
2289
        uiBut *bt;
2005
 
        ScrArea *sa;
2006
 
        ARegion *ar;
2007
 
        uiPopupMenu *pup= arg_pup;
 
2290
        uiPopupMenu *pup = arg_pup;
2008
2291
        int offset[2], direction, minwidth, width, height, flip;
2009
2292
 
2010
 
        if(pup->menu_func) {
2011
 
                pup->block->handle= handle;
 
2293
        if (pup->menu_func) {
 
2294
                pup->block->handle = handle;
2012
2295
                pup->menu_func(C, pup->layout, pup->menu_arg);
2013
 
                pup->block->handle= NULL;
 
2296
                pup->block->handle = NULL;
2014
2297
        }
2015
2298
 
2016
 
        if(pup->but) {
 
2299
        if (pup->but) {
2017
2300
                /* minimum width to enforece */
2018
 
                minwidth= pup->but->x2 - pup->but->x1;
 
2301
                minwidth = pup->but->x2 - pup->but->x1;
2019
2302
 
2020
 
                if(pup->but->type == PULLDOWN || pup->but->menu_create_func) {
2021
 
                        direction= UI_DOWN;
2022
 
                        flip= 1;
 
2303
                if (pup->but->type == PULLDOWN || pup->but->menu_create_func) {
 
2304
                        direction = UI_DOWN;
 
2305
                        flip = 1;
2023
2306
                }
2024
2307
                else {
2025
 
                        direction= UI_TOP;
2026
 
                        flip= 0;
 
2308
                        direction = UI_TOP;
 
2309
                        flip = 0;
2027
2310
                }
2028
2311
        }
2029
2312
        else {
2030
 
                minwidth= 50;
2031
 
                direction= UI_DOWN;
2032
 
                flip= 1;
 
2313
                minwidth = 50;
 
2314
                direction = UI_DOWN;
 
2315
                flip = 1;
2033
2316
        }
2034
2317
 
2035
 
        block= pup->block;
 
2318
        block = pup->block;
2036
2319
        
2037
2320
        /* in some cases we create the block before the region,
2038
 
           so we set it delayed here if necessary */
2039
 
        if(BLI_findindex(&handle->region->uiblocks, block) == -1)
 
2321
         * so we set it delayed here if necessary */
 
2322
        if (BLI_findindex(&handle->region->uiblocks, block) == -1)
2040
2323
                uiBlockSetRegion(block, handle->region);
2041
2324
 
2042
 
        block->direction= direction;
 
2325
        block->direction = direction;
2043
2326
 
2044
2327
        uiBlockLayoutResolve(block, &width, &height);
2045
2328
 
2046
2329
        uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
2047
2330
        
2048
 
        if(pup->popup) {
2049
 
                uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_RET_1);
 
2331
        if (pup->popup) {
 
2332
                uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_NUMSELECT | UI_BLOCK_RET_1);
2050
2333
                uiBlockSetDirection(block, direction);
2051
2334
 
2052
2335
                /* offset the mouse position, possibly based on earlier selection */
2053
 
                if((block->flag & UI_BLOCK_POPUP_MEMORY) &&
2054
 
                        (bt= ui_popup_menu_memory(block, NULL))) {
 
2336
                if ((block->flag & UI_BLOCK_POPUP_MEMORY) &&
 
2337
                    (bt = ui_popup_menu_memory(block, NULL)))
 
2338
                {
2055
2339
                        /* position mouse on last clicked item, at 0.8*width of the
2056
 
                           button, so it doesn't overlap the text too much, also note
2057
 
                           the offset is negative because we are inverse moving the
2058
 
                           block to be under the mouse */
2059
 
                        offset[0]= -(bt->x1 + 0.8f*(bt->x2 - bt->x1));
2060
 
                        offset[1]= -(bt->y1 + 0.5f*MENU_BUTTON_HEIGHT);
 
2340
                         * button, so it doesn't overlap the text too much, also note
 
2341
                         * the offset is negative because we are inverse moving the
 
2342
                         * block to be under the mouse */
 
2343
                        offset[0] = -(bt->x1 + 0.8f * (bt->x2 - bt->x1));
 
2344
                        offset[1] = -(bt->y1 + 0.5f * UI_UNIT_Y);
2061
2345
                }
2062
2346
                else {
2063
2347
                        /* position mouse at 0.8*width of the button and below the tile
2064
 
                           on the first item */
2065
 
                        offset[0]= 0;
2066
 
                        for(bt=block->buttons.first; bt; bt=bt->next)
2067
 
                                offset[0]= MIN2(offset[0], -(bt->x1 + 0.8f*(bt->x2 - bt->x1)));
 
2348
                         * on the first item */
 
2349
                        offset[0] = 0;
 
2350
                        for (bt = block->buttons.first; bt; bt = bt->next)
 
2351
                                offset[0] = MIN2(offset[0], -(bt->x1 + 0.8f * (bt->x2 - bt->x1)));
2068
2352
 
2069
 
                        offset[1]= 1.5*MENU_BUTTON_HEIGHT;
 
2353
                        offset[1] = 1.5 * UI_UNIT_Y;
2070
2354
                }
2071
2355
 
2072
 
                block->minbounds= minwidth;
 
2356
                block->minbounds = minwidth;
2073
2357
                uiMenuPopupBoundsBlock(block, 1, offset[0], offset[1]);
2074
2358
        }
2075
2359
        else {
2076
2360
                /* for a header menu we set the direction automatic */
2077
 
                if(!pup->slideout && flip) {
2078
 
                        sa= CTX_wm_area(C);
2079
 
                        ar= CTX_wm_region(C);
2080
 
 
2081
 
                        if(sa && sa->headertype==HEADERDOWN) {
2082
 
                                if(ar && ar->regiontype == RGN_TYPE_HEADER) {
 
2361
                if (!pup->slideout && flip) {
 
2362
                        ScrArea *sa = CTX_wm_area(C);
 
2363
                        if (sa && sa->headertype == HEADERDOWN) {
 
2364
                                ARegion *ar = CTX_wm_region(C);
 
2365
                                if (ar && ar->regiontype == RGN_TYPE_HEADER) {
2083
2366
                                        uiBlockSetDirection(block, UI_TOP);
2084
2367
                                        uiBlockFlipOrder(block);
2085
2368
                                }
2086
2369
                        }
2087
2370
                }
2088
2371
 
2089
 
                block->minbounds= minwidth;
 
2372
                block->minbounds = minwidth;
2090
2373
                uiTextBoundsBlock(block, 50);
2091
2374
        }
2092
2375
 
2093
2376
        /* if menu slides out of other menu, override direction */
2094
 
        if(pup->slideout)
 
2377
        if (pup->slideout)
2095
2378
                uiBlockSetDirection(block, UI_RIGHT);
2096
2379
 
2097
2380
        uiEndBlock(C, block);
2101
2384
 
2102
2385
uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut *but, uiMenuCreateFunc menu_func, void *arg, char *str)
2103
2386
{
2104
 
        wmWindow *window= CTX_wm_window(C);
2105
 
        uiStyle *style= U.uistyles.first;
 
2387
        wmWindow *window = CTX_wm_window(C);
 
2388
        uiStyle *style = UI_GetStyle();
2106
2389
        uiPopupBlockHandle *handle;
2107
2390
        uiPopupMenu *pup;
2108
 
        
2109
 
        pup= MEM_callocN(sizeof(uiPopupMenu), "menu dummy");
2110
 
        pup->block= uiBeginBlock(C, NULL, "ui_button_menu_create", UI_EMBOSSP);
2111
 
        pup->layout= uiBlockLayout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, style);
2112
 
        pup->slideout= (but && (but->block->flag & UI_BLOCK_LOOP));
2113
 
        pup->but= but;
 
2391
        pup = MEM_callocN(sizeof(uiPopupMenu), __func__);
 
2392
        pup->block = uiBeginBlock(C, NULL, __func__, UI_EMBOSSP);
 
2393
        pup->layout = uiBlockLayout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, style);
 
2394
        pup->slideout = (but && (but->block->flag & UI_BLOCK_LOOP));
 
2395
        pup->but = but;
2114
2396
        uiLayoutSetOperatorContext(pup->layout, WM_OP_INVOKE_REGION_WIN);
2115
2397
 
2116
 
        if(!but) {
 
2398
        if (!but) {
2117
2399
                /* no button to start from, means we are a popup */
2118
 
                pup->mx= window->eventstate->x;
2119
 
                pup->my= window->eventstate->y;
2120
 
                pup->popup= 1;
 
2400
                pup->mx = window->eventstate->x;
 
2401
                pup->my = window->eventstate->y;
 
2402
                pup->popup = 1;
2121
2403
                pup->block->flag |= UI_BLOCK_NO_FLIP;
2122
2404
        }
 
2405
        /* some enums reversing is strange, currently we have no good way to
 
2406
         * reverse some enum's but not others, so reverse all so the first menu
 
2407
         * items are always close to the mouse cursor */
 
2408
        else {
 
2409
#if 0
 
2410
                /* if this is an rna button then we can assume its an enum
 
2411
                 * flipping enums is generally not good since the order can be
 
2412
                 * important [#28786] */
 
2413
                if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) {
 
2414
                        pup->block->flag |= UI_BLOCK_NO_FLIP;
 
2415
                }
 
2416
#endif
 
2417
                if (but->context)
 
2418
                        uiLayoutContextCopy(pup->layout, but->context);
 
2419
        }
2123
2420
 
2124
 
        if(str) {
 
2421
        if (str) {
2125
2422
                /* menu is created from a string */
2126
 
                pup->menu_func= ui_block_func_MENUSTR;
2127
 
                pup->menu_arg= str;
 
2423
                pup->menu_func = ui_block_func_MENUSTR;
 
2424
                pup->menu_arg = str;
2128
2425
        }
2129
2426
        else {
2130
2427
                /* menu is created from a callback */
2131
 
                pup->menu_func= menu_func;
2132
 
                pup->menu_arg= arg;
 
2428
                pup->menu_func = menu_func;
 
2429
                pup->menu_arg = arg;
2133
2430
        }
2134
2431
        
2135
 
        handle= ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup);
 
2432
        handle = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup);
2136
2433
 
2137
 
        if(!but) {
2138
 
                handle->popup= 1;
 
2434
        if (!but) {
 
2435
                handle->popup = 1;
2139
2436
 
2140
2437
                UI_add_popup_handlers(C, &window->modalhandlers, handle);
2141
2438
                WM_event_add_mousemove(C);
2151
2448
/* only return handler, and set optional title */
2152
2449
uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon)
2153
2450
{
2154
 
        uiStyle *style= U.uistyles.first;
2155
 
        uiPopupMenu *pup= MEM_callocN(sizeof(uiPopupMenu), "popup menu");
 
2451
        uiStyle *style = UI_GetStyle();
 
2452
        uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu");
2156
2453
        uiBut *but;
2157
2454
        
2158
 
        pup->block= uiBeginBlock(C, NULL, "uiPupMenuBegin", UI_EMBOSSP);
 
2455
        pup->block = uiBeginBlock(C, NULL, __func__, UI_EMBOSSP);
2159
2456
        pup->block->flag |= UI_BLOCK_POPUP_MEMORY;
2160
 
        pup->block->puphash= ui_popup_menu_hash((char*)title);
2161
 
        pup->layout= uiBlockLayout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, style);
 
2457
        pup->block->puphash = ui_popup_menu_hash(title);
 
2458
        pup->layout = uiBlockLayout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, style);
2162
2459
        uiLayoutSetOperatorContext(pup->layout, WM_OP_EXEC_REGION_WIN);
2163
2460
 
2164
2461
        /* create in advance so we can let buttons point to retval already */
2165
 
        pup->block->handle= MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
 
2462
        pup->block->handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
2166
2463
        
2167
2464
        /* create title button */
2168
 
        if(title && title[0]) {
 
2465
        if (title && title[0]) {
2169
2466
                char titlestr[256];
2170
2467
                
2171
 
                if(icon) {
2172
 
                        sprintf(titlestr, " %s", title);
2173
 
                        uiDefIconTextBut(pup->block, LABEL, 0, icon, titlestr, 0, 0, 200, MENU_BUTTON_HEIGHT, NULL, 0.0, 0.0, 0, 0, "");
 
2468
                if (icon) {
 
2469
                        BLI_snprintf(titlestr, sizeof(titlestr), " %s", title);
 
2470
                        uiDefIconTextBut(pup->block, LABEL, 0, icon, titlestr, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
2174
2471
                }
2175
2472
                else {
2176
 
                        but= uiDefBut(pup->block, LABEL, 0, (char*)title, 0, 0, 200, MENU_BUTTON_HEIGHT, NULL, 0.0, 0.0, 0, 0, "");
2177
 
                        but->flag= UI_TEXT_LEFT;
 
2473
                        but = uiDefBut(pup->block, LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
 
2474
                        but->flag = UI_TEXT_LEFT;
2178
2475
                }
2179
2476
        }
2180
2477
 
2184
2481
/* set the whole structure to work */
2185
2482
void uiPupMenuEnd(bContext *C, uiPopupMenu *pup)
2186
2483
{
2187
 
        wmWindow *window= CTX_wm_window(C);
 
2484
        wmWindow *window = CTX_wm_window(C);
2188
2485
        uiPopupBlockHandle *menu;
2189
2486
        
2190
 
        pup->popup= 1;
2191
 
        pup->mx= window->eventstate->x;
2192
 
        pup->my= window->eventstate->y;
 
2487
        pup->popup = 1;
 
2488
        pup->mx = window->eventstate->x;
 
2489
        pup->my = window->eventstate->y;
2193
2490
        
2194
 
        menu= ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_POPUP, pup);
2195
 
        menu->popup= 1;
 
2491
        menu = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_POPUP, pup);
 
2492
        menu->popup = 1;
2196
2493
        
2197
2494
        UI_add_popup_handlers(C, &window->modalhandlers, menu);
2198
2495
        WM_event_add_mousemove(C);
2209
2506
 
2210
2507
static void operator_name_cb(bContext *C, void *arg, int retval)
2211
2508
{
2212
 
        const char *opname= arg;
 
2509
        const char *opname = arg;
2213
2510
 
2214
 
        if(opname && retval > 0)
 
2511
        if (opname && retval > 0)
2215
2512
                WM_operator_name_call(C, opname, WM_OP_EXEC_DEFAULT, NULL);
2216
2513
}
2217
2514
 
2218
2515
static void operator_cb(bContext *C, void *arg, int retval)
2219
2516
{
2220
 
        wmOperator *op= arg;
 
2517
        wmOperator *op = arg;
2221
2518
        
2222
 
        if(op && retval > 0)
 
2519
        if (op && retval > 0)
2223
2520
                WM_operator_call(C, op);
2224
2521
        else
2225
2522
                WM_operator_free(op);
2230
2527
        WM_operator_free(opv);
2231
2528
}
2232
2529
 
2233
 
static void vconfirm_opname(bContext *C, char *opname, char *title, char *itemfmt, va_list ap)
2234
 
{
2235
 
        uiPopupBlockHandle *handle;
2236
 
        char *s, buf[512];
2237
 
 
2238
 
        s= buf;
2239
 
        if (title) s+= sprintf(s, "%s%%t|", title);
2240
 
        vsprintf(s, itemfmt, ap);
2241
 
 
2242
 
        handle= ui_popup_menu_create(C, NULL, NULL, NULL, NULL, buf);
2243
 
 
2244
 
        handle->popup_func= operator_name_cb;
2245
 
        handle->popup_arg= opname;
2246
 
}
2247
 
 
2248
 
static void confirm_operator(bContext *C, wmOperator *op, char *title, char *item)
2249
 
{
2250
 
        uiPopupBlockHandle *handle;
2251
 
        char *s, buf[512];
2252
 
        
2253
 
        s= buf;
2254
 
        if (title) s+= sprintf(s, "%s%%t|%s", title, item);
2255
 
        
2256
 
        handle= ui_popup_menu_create(C, NULL, NULL, NULL, NULL, buf);
2257
 
 
2258
 
        handle->popup_func= operator_cb;
2259
 
        handle->popup_arg= op;
2260
 
        handle->cancel_func= confirm_cancel_operator;
2261
 
}
2262
 
 
2263
 
void uiPupMenuOkee(bContext *C, char *opname, char *str, ...)
 
2530
static void vconfirm_opname(bContext *C, const char *opname, const char *title, const char *itemfmt, va_list ap)
 
2531
{
 
2532
        uiPopupBlockHandle *handle;
 
2533
        char *s, buf[512];
 
2534
 
 
2535
        s = buf;
 
2536
        if (title) s += sprintf(s, "%s%%t|", title);
 
2537
        vsnprintf(s, sizeof(buf) - (s - buf), itemfmt, ap);
 
2538
        buf[sizeof(buf) - 1] = '\0';
 
2539
 
 
2540
        handle = ui_popup_menu_create(C, NULL, NULL, NULL, NULL, buf);
 
2541
 
 
2542
        handle->popup_func = operator_name_cb;
 
2543
        handle->popup_arg = (void *)opname;
 
2544
}
 
2545
 
 
2546
static void confirm_operator(bContext *C, wmOperator *op, const char *title, const char *item)
 
2547
{
 
2548
        uiPopupBlockHandle *handle;
 
2549
        char *s, buf[512];
 
2550
        
 
2551
        s = buf;
 
2552
        if (title) s += BLI_snprintf(s, sizeof(buf), "%s%%t|%s", title, item);
 
2553
        (void)s;
 
2554
        
 
2555
        handle = ui_popup_menu_create(C, NULL, NULL, NULL, NULL, buf);
 
2556
 
 
2557
        handle->popup_func = operator_cb;
 
2558
        handle->popup_arg = op;
 
2559
        handle->cancel_func = confirm_cancel_operator;
 
2560
}
 
2561
 
 
2562
void uiPupMenuOkee(bContext *C, const char *opname, const char *str, ...)
2264
2563
{
2265
2564
        va_list ap;
2266
2565
        char titlestr[256];
2267
2566
 
2268
 
        sprintf(titlestr, "OK? %%i%d", ICON_QUESTION);
 
2567
        BLI_snprintf(titlestr, sizeof(titlestr), "OK? %%i%d", ICON_QUESTION);
2269
2568
 
2270
2569
        va_start(ap, str);
2271
2570
        vconfirm_opname(C, opname, titlestr, str, ap);
2272
2571
        va_end(ap);
2273
2572
}
2274
2573
 
2275
 
void uiPupMenuSaveOver(bContext *C, wmOperator *op, char *filename)
 
2574
/* note, only call this is the file exists,
 
2575
 * the case where the file does not exist so can be saved without a
 
2576
 * popup must be checked for already, since saving from here
 
2577
 * will free the operator which will break invoke().
 
2578
 * The operator state for this is implicitly OPERATOR_RUNNING_MODAL */
 
2579
void uiPupMenuSaveOver(bContext *C, wmOperator *op, const char *filename)
2276
2580
{
2277
 
        size_t len= strlen(filename);
2278
 
 
2279
 
        if(len==0)
2280
 
                return;
2281
 
 
2282
 
        if(filename[len-1]=='/' || filename[len-1]=='\\') {
2283
 
                uiPupMenuError(C, "Cannot overwrite a directory");
2284
 
                WM_operator_free(op);
2285
 
                return;
2286
 
        }
2287
 
        if(BLI_exists(filename)==0)
2288
 
                operator_cb(C, op, 1);
2289
 
        else
2290
 
                confirm_operator(C, op, "Save Over", filename);
 
2581
        confirm_operator(C, op, "Save Over", filename);
2291
2582
}
2292
2583
 
2293
 
void uiPupMenuNotice(bContext *C, char *str, ...)
 
2584
void uiPupMenuNotice(bContext *C, const char *str, ...)
2294
2585
{
2295
2586
        va_list ap;
2296
2587
 
2299
2590
        va_end(ap);
2300
2591
}
2301
2592
 
2302
 
void uiPupMenuError(bContext *C, char *str, ...)
 
2593
void uiPupMenuError(bContext *C, const char *str, ...)
2303
2594
{
2304
2595
        va_list ap;
2305
2596
        char nfmt[256];
2306
2597
        char titlestr[256];
2307
2598
 
2308
 
        sprintf(titlestr, "Error %%i%d", ICON_ERROR);
 
2599
        BLI_snprintf(titlestr, sizeof(titlestr), "Error %%i%d", ICON_ERROR);
2309
2600
 
2310
 
        sprintf(nfmt, "%s", str);
 
2601
        BLI_strncpy(nfmt, str, sizeof(nfmt));
2311
2602
 
2312
2603
        va_start(ap, str);
2313
2604
        vconfirm_opname(C, NULL, titlestr, nfmt, ap);
2320
2611
        DynStr *ds;
2321
2612
        char *str;
2322
2613
 
2323
 
        if(!reports || !reports->list.first)
2324
 
                return;
2325
 
        if(!CTX_wm_window(C))
2326
 
                return;
2327
 
 
2328
 
        ds= BLI_dynstr_new();
2329
 
 
2330
 
        for(report=reports->list.first; report; report=report->next) {
2331
 
                if(report->type < reports->printlevel)
2332
 
                        ; /* pass */
2333
 
                else if(report->type >= RPT_ERROR)
 
2614
        if (!reports || !reports->list.first)
 
2615
                return;
 
2616
        if (!CTX_wm_window(C))
 
2617
                return;
 
2618
 
 
2619
        ds = BLI_dynstr_new();
 
2620
 
 
2621
        for (report = reports->list.first; report; report = report->next) {
 
2622
                if (report->type < reports->printlevel)
 
2623
                        ;  /* pass */
 
2624
                else if (report->type >= RPT_ERROR)
2334
2625
                        BLI_dynstr_appendf(ds, "Error %%i%d%%t|%s", ICON_ERROR, report->message);
2335
 
                else if(report->type >= RPT_WARNING)
 
2626
                else if (report->type >= RPT_WARNING)
2336
2627
                        BLI_dynstr_appendf(ds, "Warning %%i%d%%t|%s", ICON_ERROR, report->message);
2337
 
                else if(report->type >= RPT_INFO)
 
2628
                else if (report->type >= RPT_INFO)
2338
2629
                        BLI_dynstr_appendf(ds, "Info %%i%d%%t|%s", ICON_INFO, report->message);
2339
2630
        }
2340
2631
 
2341
 
        str= BLI_dynstr_get_cstring(ds);
2342
 
        if(str[0] != '\0')
 
2632
        str = BLI_dynstr_get_cstring(ds);
 
2633
        if (str[0] != '\0')
2343
2634
                ui_popup_menu_create(C, NULL, NULL, NULL, NULL, str);
2344
2635
        MEM_freeN(str);
2345
2636
 
2351
2642
        uiPopupMenu *pup;
2352
2643
        uiLayout *layout;
2353
2644
        Menu menu;
2354
 
        MenuType *mt= WM_menutype_find(idname, TRUE);
 
2645
        MenuType *mt = WM_menutype_find(idname, TRUE);
2355
2646
 
2356
 
        if(mt==NULL) {
2357
 
                printf("uiPupMenuInvoke: named menu \"%s\" not found\n", idname);
 
2647
        if (mt == NULL) {
 
2648
                printf("%s: named menu \"%s\" not found\n", __func__, idname);
2358
2649
                return;
2359
2650
        }
2360
2651
 
2361
 
        if(mt->poll && mt->poll(C, mt)==0)
 
2652
        if (mt->poll && mt->poll(C, mt) == 0)
2362
2653
                return;
2363
2654
 
2364
 
        pup= uiPupMenuBegin(C, mt->label, 0);
2365
 
        layout= uiPupMenuLayout(pup);
 
2655
        pup = uiPupMenuBegin(C, IFACE_(mt->label), ICON_NONE);
 
2656
        layout = uiPupMenuLayout(pup);
2366
2657
 
2367
 
        menu.layout= layout;
2368
 
        menu.type= mt;
 
2658
        menu.layout = layout;
 
2659
        menu.type = mt;
2369
2660
 
2370
2661
        mt->draw(C, &menu);
2371
2662
 
2375
2666
 
2376
2667
/*************************** Popup Block API **************************/
2377
2668
 
2378
 
void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, char *opname, int opcontext)
 
2669
void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext)
2379
2670
{
2380
 
        wmWindow *window= CTX_wm_window(C);
 
2671
        wmWindow *window = CTX_wm_window(C);
2381
2672
        uiPopupBlockHandle *handle;
2382
2673
        
2383
 
        handle= ui_popup_block_create(C, NULL, NULL, func, NULL, arg);
2384
 
        handle->popup= 1;
2385
 
        handle->optype= (opname)? WM_operatortype_find(opname, 0): NULL;
2386
 
        handle->opcontext= opcontext;
 
2674
        handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg);
 
2675
        handle->popup = 1;
 
2676
        handle->optype = (opname) ? WM_operatortype_find(opname, 0) : NULL;
 
2677
        handle->opcontext = opcontext;
2387
2678
        
2388
2679
        UI_add_popup_handlers(C, &window->modalhandlers, handle);
2389
2680
        WM_event_add_mousemove(C);
2394
2685
        uiPupBlockO(C, func, arg, NULL, 0);
2395
2686
}
2396
2687
 
 
2688
void uiPupBlockEx(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg)
 
2689
{
 
2690
        wmWindow *window = CTX_wm_window(C);
 
2691
        uiPopupBlockHandle *handle;
 
2692
        
 
2693
        handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg);
 
2694
        handle->popup = 1;
 
2695
        handle->retvalue = 1;
 
2696
 
 
2697
        handle->popup_arg = arg;
 
2698
        handle->popup_func = popup_func;
 
2699
        handle->cancel_func = cancel_func;
 
2700
        // handle->opcontext= opcontext;
 
2701
        
 
2702
        UI_add_popup_handlers(C, &window->modalhandlers, handle);
 
2703
        WM_event_add_mousemove(C);
 
2704
}
 
2705
 
 
2706
#if 0 /* UNUSED */
2397
2707
void uiPupBlockOperator(bContext *C, uiBlockCreateFunc func, wmOperator *op, int opcontext)
2398
2708
{
2399
 
        wmWindow *window= CTX_wm_window(C);
 
2709
        wmWindow *window = CTX_wm_window(C);
2400
2710
        uiPopupBlockHandle *handle;
2401
2711
        
2402
 
        handle= ui_popup_block_create(C, NULL, NULL, func, NULL, op);
2403
 
        handle->popup= 1;
2404
 
        handle->retvalue= 1;
 
2712
        handle = ui_popup_block_create(C, NULL, NULL, func, NULL, op);
 
2713
        handle->popup = 1;
 
2714
        handle->retvalue = 1;
2405
2715
 
2406
 
        handle->popup_arg= op;
2407
 
        handle->popup_func= operator_cb;
2408
 
        handle->cancel_func= confirm_cancel_operator;
2409
 
        handle->opcontext= opcontext;
 
2716
        handle->popup_arg = op;
 
2717
        handle->popup_func = operator_cb;
 
2718
        handle->cancel_func = confirm_cancel_operator;
 
2719
        handle->opcontext = opcontext;
2410
2720
        
2411
2721
        UI_add_popup_handlers(C, &window->modalhandlers, handle);
2412
2722
        WM_event_add_mousemove(C);
2413
2723
}
 
2724
#endif
2414
2725
 
2415
2726
void uiPupBlockClose(bContext *C, uiBlock *block)
2416
2727
{
2417
 
        if(block->handle) {
2418
 
                UI_remove_popup_handlers(&CTX_wm_window(C)->modalhandlers, block->handle);
2419
 
                ui_popup_block_free(C, block->handle);
 
2728
        if (block->handle) {
 
2729
                wmWindow *win = CTX_wm_window(C);
 
2730
 
 
2731
                /* if loading new .blend while popup is open, window will be NULL */
 
2732
                if (win) {
 
2733
                        UI_remove_popup_handlers(&win->modalhandlers, block->handle);
 
2734
                        ui_popup_block_free(C, block->handle);
 
2735
                }
2420
2736
        }
2421
2737
}
2422
2738
 
 
2739
float *ui_block_hsv_get(uiBlock *block)
 
2740
{
 
2741
        return block->_hsv;
 
2742
}