diff options
author | Ton Roosendaal <ton@blender.org> | 2009-03-25 19:58:42 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2009-03-25 19:58:42 +0300 |
commit | 2e48c4059acf7405c6beb366df63ae563802e0ff (patch) | |
tree | 439c95e5d584d7fc6e9486bf5bd83c44d5bc3cce /source/blender/editors | |
parent | a26a3f423fd6503dc2fbcd5f105c766ac3288515 (diff) |
2.5
WIP commit for new system to draw widgets and use themes or styles.
Not really interesting stuff to see in code now, the current
structure will change quite a lot, this to make it hook up well
to the existing system.
What works quite well is a new full opengl vector method to draw
scalable and pixel-aligned anti-aliased buttons.
http://download.blender.org/institute/rt3.jpg
http://download.blender.org/institute/rt4.jpg
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 1 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_draw.c | 27 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 5 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_layout.c | 3 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 1046 | ||||
-rw-r--r-- | source/blender/editors/space_buttons/space_buttons.c | 5 |
6 files changed, 1072 insertions, 15 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index d13714eb88c..a93a0f1341d 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -86,6 +86,7 @@ typedef struct uiPopupBlockHandle uiPopupBlockHandle; #define UI_BLOCK_MOVEMOUSE_QUIT 128 #define UI_BLOCK_KEEP_OPEN 256 #define UI_BLOCK_POPUP 512 +#define UI_BLOCK_2_50 1024 /* XXX 2.5 migration flag */ /* uiPopupBlockHandle->menuretval */ #define UI_RETURN_CANCEL 1 /* cancel all menus cascading */ diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 25b93861733..a01f0ee5152 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -450,8 +450,8 @@ void uiRoundRectFakeAA(float minx, float miny, float maxx, float maxy, float rad /* get the colour and divide up the alpha */ glGetFloatv(GL_CURRENT_COLOR, color); - alpha = color[3]; - color[3]= alpha/(float)passes; + alpha = 1; //color[3]; + color[3]= 0.5*alpha/(float)passes; glColor4fv(color); /* set the 'jitter amount' */ @@ -630,7 +630,7 @@ void uiEmboss(float x1, float y1, float x2, float y2, int sel) /* icons have been standardized... and this call draws in untransformed coordinates */ #define ICON_HEIGHT 16.0f -static void ui_draw_icon(uiBut *but, BIFIconID icon, int blend) +void ui_draw_icon(uiBut *but, BIFIconID icon, int blend) { float xs=0, ys=0, aspect, height; @@ -929,8 +929,8 @@ static void round_button_flat(int colorid, float asp, float x1, float y1, float int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0; /* emboss */ - glColor4f(1.0f, 1.0f, 1.0f, 0.08f); - uiRoundRectFakeAA(x1+1, y1-1, x2, y2-1, rad, asp); + //glColor4f(1.0f, 1.0f, 1.0f, 0.08f); + //uiRoundRectFakeAA(x1+1, y1-1, x2, y2-1, rad, asp); /* colour shading */ if(flag & UI_SELECT) { @@ -2205,7 +2205,7 @@ static void ui_draw_pulldown_round(int type, int colorid, float asp, float x1, f #define BUT_TEXT_NORMAL 0 #define BUT_TEXT_SUNKEN 1 -static void ui_draw_text(uiBut *but, float x, float y, int sunken) +void ui_draw_text(uiBut *but, float x, float y, int sunken) { int alpha_offs= (but->flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0; int transopts; @@ -2270,7 +2270,7 @@ static void ui_draw_text(uiBut *but, float x, float y, int sunken) } /* draws text and icons for buttons */ -static void ui_draw_text_icon(uiBut *but) +void ui_draw_text_icon(uiBut *but) { float x, y; short t, pos, ch; @@ -3242,13 +3242,14 @@ void ui_draw_but(ARegion *ar, uiBut *but) int type; if(but==NULL) return; + + if(but->block->flag & UI_BLOCK_2_50) { + extern void ui_draw_but_new(ARegion *ar, uiBut *but); // XXX + + ui_draw_but_new(ar, but); + return; + } - /* XXX 2.50 no frontbuffer drawing allowed */ -#if 0 - /* signal for frontbuf flush buttons and menus, not when normal drawing */ - if(but->block->in_use) ui_block_set_flush(but->block, but); -#endif - switch (but->type) { case NUMSLI: diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 8e1e8fad4ce..4067efb119e 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -55,7 +55,7 @@ struct wmWindow; #define UI_MOUSE_OVER 2 #define UI_ACTIVE 4 #define UI_HAS_ICON 8 -/* warn: rest of uiBut->flag in BIF_interface.c */ +/* warn: rest of uiBut->flag in UI_interface.h */ /* internal panel drawing defines */ #define PNL_GRID 4 @@ -334,6 +334,9 @@ extern void gl_round_box(int mode, float minx, float miny, float maxx, float max extern void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown); extern void gl_round_box_vertical_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight); +void ui_draw_icon(uiBut *but, BIFIconID icon, int blend); +void ui_draw_text(uiBut *but, float x, float y, int sunken); + /* interface_handlers.c */ extern void ui_button_active_cancel(const struct bContext *C, uiBut *but); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 7b891e87493..0abf952a8a4 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -846,6 +846,9 @@ void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, if(x) *x= layout->x; if(y) *y= layout->y; + + /* XXX temp, migration flag for drawing code */ + uiBlockSetFlag(block, UI_BLOCK_2_50); } void ui_layout_free(uiLayout *layout) diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c new file mode 100644 index 00000000000..d16903e008b --- /dev/null +++ b/source/blender/editors/interface/interface_widgets.c @@ -0,0 +1,1046 @@ +/** +* ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <limits.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_ID.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_windowmanager_types.h" + +#include "BLI_arithb.h" +#include "BLI_listbase.h" +#include "BLI_rect.h" + +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_idprop.h" +#include "BKE_utildefines.h" + +#include "RNA_access.h" + +#include "BIF_gl.h" + +#include "UI_interface.h" +#include "UI_interface_icons.h" +#include "UI_resources.h" +#include "UI_text.h" +#include "UI_view2d.h" + +#include "ED_util.h" +#include "ED_types.h" +#include "ED_screen.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "BMF_Api.h" +#ifdef INTERNATIONAL +#include "FTF_Api.h" +#endif + +#include "interface_intern.h" + +/* ************** widget base functions ************** */ +/* + - in: roundbox codes for corner types and radius + - return: array of [size][2][x,y] points, the edges of the roundbox, + UV coords + + - draw black box with alpha 0 on exact button boundbox + - for ever AA step: + - draw the inner part for a round filled box, with color blend codes or texture coords + - draw outline in outline color + - draw outer part, bottom half, extruded 1 pixel to bottom, for emboss shadow + - draw extra decorations + - draw background color box with alpha 1 on exact button boundbox + + */ + +/* fill this struct with polygon info to draw AA'ed */ +/* it has outline, back, and two optional tria meshes */ + +typedef struct uiWidgetTrias { + int tot; + + float vec[32][2]; + int (*index)[3]; + +} uiWidgetTrias; + +typedef struct uiWidgetColors { + float outline[3]; + float inner[3]; + float inner_sel[3]; + float item[3]; + float text[3]; + float text_sel[3]; + short shaded; + float shadetop, shadedown; + +} uiWidgetColors; + +typedef struct uiWidgetBase { + + int totvert, halfwayvert; + float outer_v[64][2]; + float inner_v[64][2]; + float inner_uv[64][2]; + + uiWidgetTrias tria1; + uiWidgetTrias tria2; + +} uiWidgetBase; + + +static float cornervec[9][2]= {{0.0, 0.0}, {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, +{0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}, {1.0, 1.0}}; + +static float jit[8][2]= {{0.468813 , -0.481430}, {-0.155755 , -0.352820}, +{0.219306 , -0.238501}, {-0.393286 , -0.110949}, {-0.024699 , 0.013908}, +{0.343805 , 0.147431}, {-0.272855 , 0.269918}, {0.095909 , 0.388710}}; + +static float num_tria_vert[19][2]= { +{0.382684, 0.923879}, {0.000001, 1.000000}, {-0.382683, 0.923880}, {-0.707107, 0.707107}, +{-0.923879, 0.382684}, {-1.000000, 0.000000}, {-0.923880, -0.382684}, {-0.707107, -0.707107}, +{-0.382683, -0.923880}, {0.000000, -1.000000}, {0.382684, -0.923880}, {0.707107, -0.707107}, +{0.923880, -0.382684}, {1.000000, -0.000000}, {0.923880, 0.382683}, {0.707107, 0.707107}, +{-0.352077, 0.532607}, {-0.352077, -0.549313}, {0.729843, -0.008353}}; + +static int num_tria_face[19][3]= { +{13, 14, 18}, {17, 5, 6}, {12, 13, 18}, {17, 6, 7}, {15, 18, 14}, {16, 4, 5}, {16, 5, 17}, {18, 11, 12}, +{18, 17, 10}, {18, 10, 11}, {17, 9, 10}, {15, 0, 18}, {18, 0, 16}, {3, 4, 16}, {8, 9, 17}, {8, 17, 7}, +{2, 3, 16}, {1, 2, 16}, {16, 0, 1}}; + +static float menu_tria_vert[6][2]= { +{-0.41, 0.16}, {0.41, 0.16}, {0, 0.82}, +{0, -0.82}, {-0.41, -0.16}, {0.41, -0.16}}; + +static int menu_tria_face[2][3]= {{2, 0, 1}, {3, 5, 4}}; + +static float check_tria_vert[6][2]= { +{-0.578579, 0.253369}, {-0.392773, 0.412794}, {-0.004241, -0.328551}, +{-0.003001, 0.034320}, {1.055313, 0.864744}, {0.866408, 1.026895}}; + +static int check_tria_face[4][3]= { +{3, 2, 4}, {3, 4, 5}, {1, 0, 3}, {0, 2, 3}}; + + + +static void widget_init(uiWidgetBase *wt) +{ + wt->totvert= wt->halfwayvert= 0; + wt->tria1.tot= 0; + wt->tria2.tot= 0; +} + + +static void round_box_edges(uiWidgetBase *wt, int roundboxtype, rcti *rect, float rad) +{ + float vec[9][2], veci[9][2]; + float minx= rect->xmin, miny= rect->ymin, maxx= rect->xmax, maxy= rect->ymax; + float radi= rad - 1.0f; /* rad inner */ + float minxi= minx + 1.0f; /* boundbox inner */ + float maxxi= maxx - 1.0f; + float minyi= miny + 1.0f; + float maxyi= maxy - 1.0f; + float facxi= 1.0f/(maxxi-minxi); /* for uv */ + float facyi= 1.0f/(maxyi-minyi); + int a, tot= 0; + + /* mult */ + for(a=0; a<9; a++) { + veci[a][0]= radi*cornervec[a][0]; + veci[a][1]= radi*cornervec[a][1]; + vec[a][0]= rad*cornervec[a][0]; + vec[a][1]= rad*cornervec[a][1]; + } + + /* corner left-bottom */ + if(roundboxtype & 8) { + + for(a=0; a<9; a++, tot++) { + wt->inner_v[tot][0]= minxi+veci[a][1]; + wt->inner_v[tot][1]= minyi+radi-veci[a][0]; + + wt->outer_v[tot][0]= minx+vec[a][1]; + wt->outer_v[tot][1]= miny+rad-vec[a][0]; + + wt->inner_uv[tot][0]= facxi*(wt->inner_v[tot][0] - minxi); + wt->inner_uv[tot][1]= facyi*(wt->inner_v[tot][1] - minyi); + } + } + else { + wt->inner_v[tot][0]= minxi; + wt->inner_v[tot][1]= minyi; + + wt->outer_v[tot][0]= minx; + wt->outer_v[tot][1]= miny; + + wt->inner_uv[tot][0]= 0.0f; + wt->inner_uv[tot][1]= 0.0f; + + tot++; + } + + /* corner right-bottom */ + if(roundboxtype & 4) { + + for(a=0; a<9; a++, tot++) { + wt->inner_v[tot][0]= maxxi-radi+veci[a][0]; + wt->inner_v[tot][1]= minyi+veci[a][1]; + + wt->outer_v[tot][0]= maxx-rad+vec[a][0]; + wt->outer_v[tot][1]= miny+vec[a][1]; + + wt->inner_uv[tot][0]= facxi*(wt->inner_v[tot][0] - minxi); + wt->inner_uv[tot][1]= facyi*(wt->inner_v[tot][1] - minyi); + } + } + else { + wt->inner_v[tot][0]= maxxi; + wt->inner_v[tot][1]= minyi; + + wt->outer_v[tot][0]= maxx; + wt->outer_v[tot][1]= miny; + + wt->inner_uv[tot][0]= 1.0f; + wt->inner_uv[tot][1]= 0.0f; + + tot++; + } + + wt->halfwayvert= tot; + + /* corner right-top */ + if(roundboxtype & 2) { + + for(a=0; a<9; a++, tot++) { + wt->inner_v[tot][0]= maxxi-veci[a][1]; + wt->inner_v[tot][1]= maxyi-radi+veci[a][0]; + + wt->outer_v[tot][0]= maxx-vec[a][1]; + wt->outer_v[tot][1]= maxy-rad+vec[a][0]; + + wt->inner_uv[tot][0]= facxi*(wt->inner_v[tot][0] - minxi); + wt->inner_uv[tot][1]= facyi*(wt->inner_v[tot][1] - minyi); + } + } + else { + wt->inner_v[tot][0]= maxxi; + wt->inner_v[tot][1]= maxyi; + + wt->outer_v[tot][0]= maxx; + wt->outer_v[tot][1]= maxy; + + wt->inner_uv[tot][0]= 1.0f; + wt->inner_uv[tot][1]= 1.0f; + + tot++; + } + + /* corner left-top */ + if(roundboxtype & 1) { + + for(a=0; a<9; a++, tot++) { + wt->inner_v[tot][0]= minxi+radi-veci[a][0]; + wt->inner_v[tot][1]= maxyi-veci[a][1]; + + wt->outer_v[tot][0]= minx+rad-vec[a][0]; + wt->outer_v[tot][1]= maxy-vec[a][1]; + + wt->inner_uv[tot][0]= facxi*(wt->inner_v[tot][0] - minxi); + wt->inner_uv[tot][1]= facyi*(wt->inner_v[tot][1] - minyi); + } + + } + else { + + wt->inner_v[tot][0]= minxi; + wt->inner_v[tot][1]= maxyi; + + wt->outer_v[tot][0]= minx; + wt->outer_v[tot][1]= maxy; + + wt->inner_uv[tot][0]= 0.0f; + wt->inner_uv[tot][1]= 1.0f; + + tot++; + } + + wt->totvert= tot; +} + +/* based on button rect, return scaled array of triangles */ +static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, char where) +{ + float centx, centy, size; + int a; + + /* center position and size */ + centx= (float)rect->xmin + 0.5f*(rect->ymax-rect->ymin); + centy= (float)rect->ymin + 0.5f*(rect->ymax-rect->ymin); + size= 0.5f*triasize*(rect->ymax-rect->ymin); + + if(where=='r') { + centx= (float)rect->xmax - 0.5f*(rect->ymax-rect->ymin); + size= -size; + } + + for(a=0; a<19; a++) { + tria->vec[a][0]= size*num_tria_vert[a][0] + centx; + tria->vec[a][1]= size*num_tria_vert[a][1] + centy; + } + + tria->tot= 19; + tria->index= num_tria_face; +} + +static void widget_trias_draw(uiWidgetTrias *tria) +{ + int a; + + glBegin(GL_TRIANGLES); + for(a=0; a<tria->tot; a++) { + glVertex2fv(tria->vec[ tria->index[a][0] ]); + glVertex2fv(tria->vec[ tria->index[a][1] ]); + glVertex2fv(tria->vec[ tria->index[a][2] ]); + } + glEnd(); + +} + +static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect) +{ + float centx, centy, size; + int a; + + /* center position and size */ + centx= rect->xmax - 0.5f*(rect->ymax-rect->ymin); + centy= rect->ymin + 0.5f*(rect->ymax-rect->ymin); + size= 0.4f*(rect->ymax-rect->ymin); + + for(a=0; a<6; a++) { + tria->vec[a][0]= size*menu_tria_vert[a][0] + centx; + tria->vec[a][1]= size*menu_tria_vert[a][1] + centy; + } + + tria->tot= 2; + tria->index= menu_tria_face; +} + +static void widget_check_trias(uiWidgetTrias *tria, rcti *rect) +{ + float centx, centy, size; + int a; + + /* center position and size */ + centx= rect->xmin + 0.5f*(rect->ymax-rect->ymin); + centy= rect->ymin + 0.5f*(rect->ymax-rect->ymin); + size= 0.5f*(rect->ymax-rect->ymin); + + for(a=0; a<6; a++) { + tria->vec[a][0]= size*check_tria_vert[a][0] + centx; + tria->vec[a][1]= size*check_tria_vert[a][1] + centy; + } + + tria->tot= 4; + tria->index= check_tria_face; +} + + +/* prepares shade colors */ +static void shadecolors(float *coltop, float *coldown, float *color, float shadetop, float shadedown) +{ + float hue, sat, val, valshade; + + rgb_to_hsv(color[0], color[1], color[2], &hue, &sat, &val); + + valshade= CLAMPIS(val+shadetop, 0.0f, 1.0f); + hsv_to_rgb(hue, sat, valshade, coltop, coltop+1, coltop+2); + + valshade= CLAMPIS(val+shadedown, 0.0f, 1.0f); + hsv_to_rgb(hue, sat, valshade, coldown, coldown+1, coldown+2); +} + +static void round_box_shade_col(float *col1, float *col2, float fac) +{ + float col[4]; + + col[0]= (fac*col1[0] + (1.0-fac)*col2[0]); + col[1]= (fac*col1[1] + (1.0-fac)*col2[1]); + col[2]= (fac*col1[2] + (1.0-fac)*col2[2]); + col[3]= 1; + + glColor4fv(col); +} + +static void widget_draw(uiWidgetBase *wt, uiWidgetColors *wcol, int state) +{ + float *inner= wcol->inner; + int j, a; + + if(state & UI_SELECT) + inner= wcol->inner_sel; + + glEnable(GL_BLEND); + + /* backdrop non AA */ + if(wcol->shaded==0) { + /* filled center, solid */ + glColor3fv(inner); + glBegin(GL_POLYGON); + for(a=0; a<wt->totvert; a++) + glVertex2fv(wt->inner_v[a]); + glEnd(); + } + else { + float col1[3], col2[3]; + + shadecolors(col1, col2, inner, wcol->shadetop, wcol->shadedown); + + glShadeModel(GL_SMOOTH); + glBegin(GL_POLYGON); + for(a=0; a<wt->totvert; a++) { + round_box_shade_col(col1, col2, wt->inner_uv[a][1]); + glVertex2fv(wt->inner_v[a]); + } + glEnd(); + glShadeModel(GL_FLAT); + } + + /* for each AA step */ + for(j=0; j<8; j++) { + glTranslatef(1.0*jit[j][0], 1.0*jit[j][1], 0.0f); + + /* outline */ + glColor4f(wcol->outline[0], wcol->outline[1], wcol->outline[0], 0.125); + glBegin(GL_QUAD_STRIP); + for(a=0; a<wt->totvert; a++) { + glVertex2fv(wt->outer_v[a]); + glVertex2fv(wt->inner_v[a]); + } + glVertex2fv(wt->outer_v[0]); + glVertex2fv(wt->inner_v[0]); + glEnd(); + + /* emboss bottom shadow */ + glColor4f(1.0f, 1.0f, 1.0f, 0.02f); + glBegin(GL_QUAD_STRIP); + for(a=0; a<wt->halfwayvert; a++) { + glVertex2fv(wt->outer_v[a]); + glVertex2f(wt->outer_v[a][0], wt->outer_v[a][1]-1.0f); + } + glEnd(); + + glTranslatef(-1.0*jit[j][0], -1.0*jit[j][1], 0.0f); + } + + /* decoration */ + if(wt->tria1.tot || wt->tria2.tot) { + /* for each AA step */ + for(j=0; j<8; j++) { + glTranslatef(1.0*jit[j][0], 1.0*jit[j][1], 0.0f); + + if(wt->tria1.tot) { + glColor4f(wcol->item[0], wcol->item[1], wcol->item[2], 0.125); + widget_trias_draw(&wt->tria1); + } + if(wt->tria2.tot) { + glColor4f(wcol->item[0], wcol->item[1], wcol->item[2], 0.125); + widget_trias_draw(&wt->tria2); + } + + glTranslatef(-1.0*jit[j][0], -1.0*jit[j][1], 0.0f); + } + } + + glDisable(GL_BLEND); + +} + +/* *********************** text/icon ************************************** */ + +static void widget_draw_text(uiBut *but, float x, float y) +{ + int transopts; + int len; + char *cpoin; + + ui_rasterpos_safe(x, y, but->aspect); + if(but->type==IDPOIN) transopts= 0; // no translation, of course! + else transopts= ui_translate_buttons(); + + /* cut string in 2 parts */ + cpoin= strchr(but->drawstr, '|'); + if(cpoin) *cpoin= 0; + +#ifdef INTERNATIONAL + if (but->type == FTPREVIEW) + FTF_DrawNewFontString (but->drawstr+but->ofs, FTF_INPUT_UTF8); + else + UI_DrawString(but->font, but->drawstr+but->ofs, transopts); +#else + UI_DrawString(but->font, but->drawstr+but->ofs, transopts); +#endif + + /* part text right aligned */ + if(cpoin) { + len= UI_GetStringWidth(but->font, cpoin+1, ui_translate_buttons()); + ui_rasterpos_safe( but->x2 - len*but->aspect-3, y, but->aspect); + UI_DrawString(but->font, cpoin+1, ui_translate_buttons()); + *cpoin= '|'; + } +} + +/* draws text and icons for buttons */ +static void widget_draw_text_icon(uiBut *but, rcti *rect, float *col) +{ + float x, y; + short t, pos, ch; + short selsta_tmp, selend_tmp, selsta_draw, selwidth_draw; + + if(but==NULL) return; + + /* check for button text label */ + if (but->type == ICONTEXTROW) { + ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 0); + } + else { + + /* text button selection and cursor */ + if(but->editstr && but->pos != -1) { + + if ((but->selend - but->selsta) > 0) { + /* text button selection */ + selsta_tmp = but->selsta + strlen(but->str); + selend_tmp = but->selend + strlen(but->str); + + if(but->drawstr[0]!=0) { + ch= but->drawstr[selsta_tmp]; + but->drawstr[selsta_tmp]= 0; + + selsta_draw = but->aspect*UI_GetStringWidth(but->font, but->drawstr+but->ofs, ui_translate_buttons()) + 3; + + but->drawstr[selsta_tmp]= ch; + + + ch= but->drawstr[selend_tmp]; + but->drawstr[selend_tmp]= 0; + + selwidth_draw = but->aspect*UI_GetStringWidth(but->font, but->drawstr+but->ofs, ui_translate_buttons()) + 3; + + but->drawstr[selend_tmp]= ch; + + UI_ThemeColor(TH_BUT_TEXTFIELD_HI); + glRects(rect->xmin+selsta_draw+1, rect->ymin+2, rect->xmin+selwidth_draw+1, rect->ymax-2); + } + } else { + /* text cursor */ + pos= but->pos+strlen(but->str); + if(pos >= but->ofs) { + if(but->drawstr[0]!=0) { + ch= but->drawstr[pos]; + but->drawstr[pos]= 0; + + t= but->aspect*UI_GetStringWidth(but->font, but->drawstr+but->ofs, ui_translate_buttons()) + 3; + + but->drawstr[pos]= ch; + } + else t= 3; + + glColor3ub(255,0,0); + glRects(rect->xmin+t, rect->ymin+2, rect->xmin+t+2, rect->ymax-2); + } + } + } + + if(but->type==BUT_TOGDUAL) { + int dualset= 0; + if(but->pointype==SHO) + dualset= BTST( *(((short *)but->poin)+1), but->bitnr); + else if(but->pointype==INT) + dualset= BTST( *(((int *)but->poin)+1), but->bitnr); + + ui_draw_icon(but, ICON_DOT, dualset?0:-100); + } + + if(but->drawstr[0]!=0) { + + /* If there's an icon too (made with uiDefIconTextBut) then draw the icon + and offset the text label to accomodate it */ + + if ( (but->flag & UI_HAS_ICON) && (but->flag & UI_ICON_LEFT) ) + { + ui_draw_icon(but, but->icon, 0); + + if(but->editstr || (but->flag & UI_TEXT_LEFT)) x= rect->xmin + but->aspect*UI_icon_get_width(but->icon)+5.0; + else x= (rect->xmin+rect->xmax-but->strwidth+1)/2.0; + } + else + { + if(but->editstr || (but->flag & UI_TEXT_LEFT)) + x= rect->xmin+4.0; + else if ELEM3(but->type, TOG, TOGN, TOG3) + x= rect->xmin+28.0; /* offset for checkmark */ + else + x= (rect->xmin+rect->xmax-but->strwidth+1)/2.0; + } + + /* position and draw */ + y = (rect->ymin+rect->ymax- 9.0)/2.0; + + glColor3fv(col); + widget_draw_text(but, x, y); + + } + /* if there's no text label, then check to see if there's an icon only and draw it */ + else if( but->flag & UI_HAS_ICON ) { + ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 0); + } + } +} + + + +/* *********************** widget types ************************************* */ + +/* + float outline[3]; + float inner[3]; + float select[3]; + float item[3]; + short shaded; + float shadetop, shadedown; +*/ + +static struct uiWidgetColors wcol_num= { + {0.1f, 0.1f, 0.1f}, + {0.7f, 0.7f, 0.7f}, + {0.6f, 0.6f, 0.6f}, + {0.35f, 0.35f, 0.35f}, + + {0.0f, 0.0f, 0.0f}, + {1.0f, 1.0f, 1.0f}, + + 1, + -0.08f, 0.0f +}; + +static struct uiWidgetColors wcol_text= { + {0.1f, 0.1f, 0.1f}, + {0.6f, 0.6f, 0.6f}, + {0.6f, 0.6f, 0.6f}, + {0.35f, 0.35f, 0.35f}, + + {0.0f, 0.0f, 0.0f}, + {1.0f, 1.0f, 1.0f}, + + 1, + 0.0f, 0.1f +}; + +static struct uiWidgetColors wcol_menu= { + {0.0f, 0.0f, 0.0f}, + {0.25f, 0.25f, 0.25f}, + {0.25f, 0.25f, 0.25f}, + {1.0f, 1.0f, 1.0f}, + + {1.0f, 1.0f, 1.0f}, + {0.0f, 0.0f, 0.0f}, + + 1, + 0.1f, -0.08f +}; + +static struct uiWidgetColors wcol_row= { + {0.0f, 0.0f, 0.0f}, + {0.25f, 0.25f, 0.25f}, + {0.34f, 0.5f, 0.76f}, + {1.0f, 1.0f, 1.0f}, + + {1.0f, 1.0f, 1.0f}, + {0.0f, 0.0f, 0.0f}, + + 1, + 0.1f, -0.1f +}; + +static struct uiWidgetColors wcol_regular= { + {0.1f, 0.1f, 0.1f}, + {0.6f, 0.6f, 0.6f}, + {0.4f, 0.4f, 0.4f}, + {0.1f, 0.1f, 0.1f}, + + {0.0f, 0.0f, 0.0f}, + {1.0f, 1.0f, 1.0f}, + + 0, + 0.0f, 0.0f +}; + +static struct uiWidgetColors wcol_regular2= { + {0.1f, 0.1f, 0.1f}, + {0.6f, 0.6f, 0.6f}, + {0.4f, 0.4f, 0.4f}, + {0.1f, 0.1f, 0.1f}, + + {0.0f, 0.0f, 0.0f}, + {1.0f, 1.0f, 1.0f}, + + 1, + 0.1f, -0.1f +}; + + +static void widget_numbut(uiBut *but, rcti *rect, int state, int roundboxtype) +{ + uiWidgetBase wt; + + widget_init(&wt); + + /* fully rounded */ + round_box_edges(&wt, roundboxtype, rect, 0.5f*(rect->ymax - rect->ymin)); + + /* decoration */ + widget_num_tria(&wt.tria1, rect, 0.6f, 0); + widget_num_tria(&wt.tria2, rect, 0.6f, 'r'); + + widget_draw(&wt, &wcol_num, state); + + if(state & UI_SELECT) + widget_draw_text_icon(but, rect, wcol_num.text_sel); + else + widget_draw_text_icon(but, rect, wcol_num.text); +} + +static void widget_textbut(uiBut *but, rcti *rect, int state, int roundboxtype) +{ + uiWidgetBase wt; + + widget_init(&wt); + + /* half rounded */ + round_box_edges(&wt, roundboxtype, rect, 4.0f); + + /* XXX button state */ + widget_draw(&wt, &wcol_text, state); + + widget_draw_text_icon(but, rect, wcol_text.text); +} + + +static void widget_menubut(uiBut *but, rcti *rect, int state, int roundboxtype) +{ + uiWidgetBase wt; + + widget_init(&wt); + + /* half rounded */ + round_box_edges(&wt, roundboxtype, rect, 4.0f); + + /* XXX button state */ + + /* decoration */ + widget_menu_trias(&wt.tria1, rect); + + widget_draw(&wt, &wcol_menu, state); + + widget_draw_text_icon(but, rect, wcol_menu.text); +} + +static void widget_togbut(uiBut *but, rcti *rect, int state, int roundboxtype) +{ + uiWidgetBase wt; + rcti recttemp= *rect; + int delta; + + widget_init(&wt); + + /* square */ + recttemp.xmax= recttemp.xmin + (recttemp.ymax-recttemp.ymin); + + /* smaller */ + delta= 1 + (recttemp.ymax-recttemp.ymin)/8; + recttemp.xmin+= delta; + recttemp.ymin+= delta; + recttemp.xmax-= delta; + recttemp.ymax-= delta; + + /* half rounded */ + round_box_edges(&wt, roundboxtype, &recttemp, 4.0f); + + /* button state */ + + /* decoration */ + if(state & UI_SELECT) { + widget_check_trias(&wt.tria1, &recttemp); + } + + widget_draw(&wt, &wcol_menu, state); + + if(state & UI_SELECT) + widget_draw_text_icon(but, rect, wcol_menu.text); + else + widget_draw_text_icon(but, rect, wcol_menu.text_sel); +} + + +static void widget_rowbut(uiBut *but, rcti *rect, int state, int roundboxtype) +{ + uiWidgetBase wt; + + widget_init(&wt); + + /* half rounded */ + round_box_edges(&wt, roundboxtype, rect, 4.0f); + + widget_draw(&wt, &wcol_row, state); + + widget_draw_text_icon(but, rect, wcol_row.text); +} + +static void widget_but(uiBut *but, rcti *rect, int state, int roundboxtype) +{ + uiWidgetBase wt; + + widget_init(&wt); + + /* half rounded */ + round_box_edges(&wt, roundboxtype, rect, 4.0f); + + widget_draw(&wt, &wcol_regular, state); + + widget_draw_text_icon(but, rect, wcol_regular.text); +} + +static void widget_roundbut(uiBut *but, rcti *rect, int state, int roundboxtype) +{ + uiWidgetBase wt; + + widget_init(&wt); + + /* fully rounded */ + round_box_edges(&wt, roundboxtype, rect, 0.5f*(rect->ymax - rect->ymin)); + + widget_num_tria(&wt.tria1, rect, 0.6f, 0); + + widget_draw(&wt, &wcol_regular2, state); + + widget_draw_text_icon(but, rect, wcol_regular2.text); + +} + +/* test function only */ +void drawnewstuff() +{ + rcti rect; + + rect.xmin= 10; rect.xmax= 10+100; + rect.ymin= -30; rect.ymax= -30+18; + widget_numbut(NULL, &rect, 0, 15); + + rect.xmin= 120; rect.xmax= 120+100; + rect.ymin= -30; rect.ymax= -30+20; + widget_numbut(NULL, &rect, 0, 15); + + rect.xmin= 10; rect.xmax= 10+100; + rect.ymin= -60; rect.ymax= -60+20; + widget_menubut(NULL, &rect, 0, 15); + + rect.xmin= 120; rect.xmax= 120+100; + widget_but(NULL, &rect, 0, 15); + + rect.xmin= 10; rect.xmax= 10+100; + rect.ymin= -90; rect.ymax= -90+20; + widget_rowbut(NULL, &rect, 1, 9); + + rect.xmin= 109; rect.xmax= 110+100; + rect.ymin= -90; rect.ymax= -90+20; + widget_rowbut(NULL, &rect, 0, 6); + + rect.xmin= 240; rect.xmax= 240+30; + rect.ymin= -90; rect.ymax= -90+30; + widget_roundbut(NULL, &rect, 0, 15); +} + +/* ************ new color and style definition ********************* */ +/* + +- minimum width definition? + +- Types + * Icon toggle button + * Row button (exclusive "enum" values) + * Option button (also "bit flags") + * Tool/Operator button + * Number button + * Number slider + + * Text string button (to rename data) + * File name button (separate design?) + * Linkage "Library" button (Object, Material, Parent, etc) + * Linkage data name button (Bone, Vgroup) + + * Popup settings button, with optional text, icon or both. + * Popup linkage button (Materials, Bones, etc) + * Pulldown menu button (to invoke pulldown) + * Pulldown menu item (and menu backdrop + title) + + * Button-less icons (open-close triangle, delete cross, ...) + * Color picker Swatch + * Color picker fields + * Normal button (rotatable sphere) + +*/ + +static int widget_roundbox_set(uiBut *but, rcti *rect) +{ + /* alignment */ + if(but->flag & UI_BUT_ALIGN) { + + if(but->flag & UI_BUT_ALIGN_TOP) + rect->ymax+= 1; + if(but->flag & UI_BUT_ALIGN_LEFT) + rect->xmin-= 1; + + switch(but->flag & UI_BUT_ALIGN) { + case UI_BUT_ALIGN_TOP: + return (12); + break; + case UI_BUT_ALIGN_DOWN: + return (3); + break; + case UI_BUT_ALIGN_LEFT: + return (6); + break; + case UI_BUT_ALIGN_RIGHT: + return (9); + break; + + case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT: + return (1); + break; + case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT: + return (2); + break; + case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT: + return (8); + break; + case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT: + return (4); + break; + + default: + return (0); + break; + } + } + return 15; +} + + +/* widget classification + +- state: + UI_MOUSE_OVER: on mouse over + UI_ACTIVE: while using it + UI_SELECT: internal state (toggle, row) + +- drawtype + CUSTOM: no widget class, entirely free within rect + WIDGET: part of the standard widget set + +- text placement, split? + +- widget color style hint + - outline + - interior col + - interior slider color? + - shade factors + - decoration color + - text colors + +- callbacks + - widget_draw() + - widget_text_icon() + - + +*/ + + +void ui_draw_but_new(ARegion *ar, uiBut *but) +{ + rcti rect; + int roundboxtype, state; + + /* XXX project later */ + rect.xmin= but->x1; + rect.xmax= but->x2; + rect.ymin= but->y1; + rect.ymax= but->y2; + + roundboxtype= widget_roundbox_set(but, &rect); + state= but->flag; + + switch (but->type) { + case LABEL: + widget_draw_text_icon(but, &rect, wcol_regular2.text); + break; + case NUM: + widget_numbut(but, &rect, state, roundboxtype); + break; + case ROW: + widget_rowbut(but, &rect, state, roundboxtype); + break; + case TEX: + widget_textbut(but, &rect, state, roundboxtype); + break; + case TOG: + case TOGN: + case TOG3: + if (!(state & UI_HAS_ICON)) + widget_togbut(but, &rect, state, roundboxtype); + else + widget_but(but, &rect, state, roundboxtype); + break; + case MENU: + case BLOCK: + widget_menubut(but, &rect, state, roundboxtype); + break; + + default: + widget_but(but, &rect, state, roundboxtype); + } + +} + + + + diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 1bc57b38abe..3205fea2a15 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -146,6 +146,7 @@ static void buttons_main_area_init(wmWindowManager *wm, ARegion *ar) { ListBase *keymap; +// ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy); /* own keymap */ @@ -171,13 +172,15 @@ static void buttons_main_area_draw(const bContext *C, ARegion *ar) /* swapbuffers indicator */ fac= BLI_frand(); glColor3f(fac, fac, fac); - glRecti(20, 2, 30, 12); + glRecti(20, v2d->cur.ymin+2, 30, v2d->cur.ymin+12); /* panels */ if(sbuts->mainb == CONTEXT_SCENE) buttons_scene(C, ar); else if(sbuts->mainb == CONTEXT_OBJECT) buttons_object(C, ar); + else + drawnewstuff(); if(sbuts->align) if(sbuts->re_align || sbuts->mainbo!=sbuts->mainb || sbuts->tabo!=sbuts->tab[sbuts->mainb]) |