Cleanup of scroller drawing in 2D windows.

Before:
http://download.blender.org/institute/rt11.jpg
After:
http://download.blender.org/institute/rt12.jpg

Will add 'zoom' widget circles later, as mockupped here:
http://www.reynish.com/files/blender25/fcurve_scrollbar.png

Also note the scale values are inside scroller; drawing it
on top conflicts with current frame item and markers.

Currently scroller disappear entirely when view is total.

For Joshua:
To make sliders behave nicely, the boundbox (v2d->tot) has to
be refreshed on each change. I've added it in graph drawing
now, but it could be notifier based I guess... not sure what
the correct anim api call would be. Can discuss tomorrow!

On todo:
Layout config hints so people can make scroller positions swap.
This commit is contained in:
Ton Roosendaal 2009-07-02 18:12:46 +00:00
parent aefa7b626a
commit 5a0896e1a3
13 changed files with 219 additions and 234 deletions

@ -78,6 +78,11 @@ float BLF_height(char *str);
float BLF_width_default(char *str);
float BLF_height_default(char *str);
/*
* set rotation for default font
*/
void BLF_default_rotation(float angle);
/*
* By default, rotation and clipping are disable and
* have to be enable/disable using BLF_enable/disable.

@ -321,6 +321,19 @@ void BLF_draw_default(float x, float y, float z, char *str)
}
}
void BLF_default_rotation(float angle)
{
if (global_font_default>=0) {
global_font[global_font_default]->angle= angle;
if(angle)
global_font[global_font_default]->flags |= BLF_ROTATION;
else
global_font[global_font_default]->flags &= ~BLF_ROTATION;
}
}
void BLF_draw(char *str)
{
FontBLF *font;

@ -165,7 +165,7 @@ void ANIM_draw_cfra (const bContext *C, View2D *v2d, short flag)
glLineWidth(2.0);
glBegin(GL_LINE_STRIP);
vec[1]= v2d->cur.ymin;
vec[1]= v2d->cur.ymin-500.0f; /* XXX arbitrary... want it go to bottom */
glVertex2fv(vec);
vec[1]= v2d->cur.ymax;

@ -97,9 +97,9 @@ enum {
/* ------ Defines for Scrollers ----- */
/* scroller thickness */
#define V2D_SCROLL_HEIGHT 16
#define V2D_SCROLL_WIDTH 16
/* scroller area */
#define V2D_SCROLL_HEIGHT 17
#define V2D_SCROLL_WIDTH 17
/* half the size (in pixels) of scroller 'handles' */
#define V2D_SCROLLER_HANDLE_SIZE 5

@ -420,6 +420,7 @@ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y
void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect);
void ui_draw_search_back(struct uiStyle *style, uiBlock *block, rcti *rect);
void ui_draw_link_bezier(rcti *rect);
void widget_scroll_draw(struct uiWidgetColors *wcol, rcti *rect, rcti *slider, int state);
extern void ui_draw_but(const struct bContext *C, ARegion *ar, struct uiStyle *style, uiBut *but, rcti *rect);
/* theme color init */

@ -106,7 +106,7 @@ static int panel_aligned(ScrArea *sa, ARegion *ar)
}
else if(sa->spacetype==SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS)
return BUT_VERTICAL;
else if(ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS))
else if(ELEM3(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS))
return BUT_VERTICAL;
return 0;

@ -527,7 +527,7 @@ static void shadecolors4(char *coltop, char *coldown, char *color, short shadeto
coldown[0]= CLAMPIS(color[0]+shadedown, 0, 255);
coldown[1]= CLAMPIS(color[1]+shadedown, 0, 255);
coldown[2]= CLAMPIS(color[2]+shadedown, 0, 255);
coldown[3]= color[3];
coldown[3]= color[3];
}
static void round_box_shade_col4(char *col1, char *col2, float fac)
@ -1106,16 +1106,16 @@ static struct uiWidgetColors wcol_toggle= {
};
static struct uiWidgetColors wcol_scroll= {
{25, 25, 25, 255},
{50, 50, 50, 180},
{80, 80, 80, 180},
{100, 100, 100, 180},
{180, 180, 180, 255},
{153, 153, 153, 255},
{90, 90, 90, 255},
{0, 0, 0, 255},
{255, 255, 255, 255},
1,
0, -20
10, -20
};
/* free wcol struct to play with */
@ -1206,6 +1206,10 @@ static void widget_state_label(uiWidgetType *wt, int state)
}
static void widget_state_nothing(uiWidgetType *wt, int state)
{
wt->wcol= *(wt->wcol_theme);
}
/* special case, button that calls pulldown */
static void widget_state_pulldown(uiWidgetType *wt, int state)
@ -1634,44 +1638,64 @@ void ui_draw_link_bezier(rcti *rect)
}
}
static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
/* function in use for buttons and for view2d sliders */
void widget_scroll_draw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int state)
{
uiWidgetBase wtb;
rcti rect1;
double value;
char inner[3];
float fac, size, rad;
float rad;
int horizontal;
widget_init(&wtb);
/* determine horizontal/vertical */
horizontal= (rect->xmax - rect->xmin > rect->ymax - rect->ymin);
if(horizontal)
rad= 0.5f*(rect->ymax - rect->ymin);
else
rad= 0.5f*(rect->xmax - rect->xmin);
widget_init(&wtb);
wtb.shadedir= (horizontal)? 1: 0;
/* draw back part, colors swapped and shading inverted */
VECCOPY(inner, wcol->inner);
VECCOPY(wcol->inner, wcol->item);
if(horizontal)
SWAP(short, wcol->shadetop, wcol->shadedown);
if(state & UI_SELECT)
SWAP(short, wcol->shadetop, wcol->shadedown);
round_box_edges(&wtb, roundboxalign, rect, rad); /* XXX vertical gradient is wrong */
round_box_edges(&wtb, 15, rect, rad);
widgetbase_draw(&wtb, wcol);
VECCOPY(wcol->inner, inner);
if(horizontal)
SWAP(short, wcol->shadetop, wcol->shadedown);
if(state & UI_SELECT)
SWAP(short, wcol->shadetop, wcol->shadedown);
/* front part */
/* slider */
if(slider->xmax-slider->xmin<2 || slider->ymax-slider->ymin<2);
else {
SWAP(short, wcol->shadetop, wcol->shadedown);
QUATCOPY(wcol->inner, wcol->item);
if(wcol->shadetop>wcol->shadedown)
wcol->shadetop+= 20; /* XXX violates themes... */
else wcol->shadedown+= 20;
if(state & UI_SELECT)
SWAP(short, wcol->shadetop, wcol->shadedown);
/* draw */
wtb.emboss= 0; /* only emboss once */
round_box_edges(&wtb, 15, slider, rad);
widgetbase_draw(&wtb, wcol);
}
}
static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
rcti rect1;
double value;
float fac, size;
int horizontal;
/* calculate slider part */
value= ui_get_but_val(but);
size= (but->softmax + but->a1 - but->softmin);
@ -1680,6 +1704,9 @@ static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
/* position */
rect1= *rect;
/* determine horizontal/vertical */
horizontal= (rect->xmax - rect->xmin > rect->ymax - rect->ymin);
if(horizontal) {
fac= (rect->xmax - rect->xmin)/(size);
rect1.xmin= rect1.xmin + ceil(fac*(value - but->softmin));
@ -1691,17 +1718,8 @@ static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
rect1.ymin= rect1.ymax - ceil(fac*(but->a1 - but->softmin));
}
/* draw */
wtb.emboss= 0; /* only emboss once */
widget_scroll_draw(wcol, rect, &rect1, state);
if(!horizontal)
SWAP(short, wcol->shadetop, wcol->shadedown);
round_box_edges(&wtb, roundboxalign, &rect1, rad); /* XXX vertical gradient is wrong */
widgetbase_draw(&wtb, wcol);
if(!horizontal)
SWAP(short, wcol->shadetop, wcol->shadedown);
}
static void widget_link(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
@ -2103,6 +2121,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
case UI_WTYPE_SCROLL:
wt.wcol_theme= &btheme->tui.wcol_scroll;
wt.state= widget_state_nothing;
wt.custom= widget_scroll;
break;
}

@ -34,6 +34,7 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
#include "DNA_view2d_types.h"
#include "BLI_blenlib.h"
@ -901,7 +902,14 @@ void UI_view2d_view_orthoSpecial(const bContext *C, View2D *v2d, short xaxis)
/* Restore view matrices after drawing */
void UI_view2d_view_restore(const bContext *C)
{
ED_region_pixelspace(CTX_wm_region(C));
ARegion *ar= CTX_wm_region(C);
int width= ar->winrct.xmax-ar->winrct.xmin+1;
int height= ar->winrct.ymax-ar->winrct.ymin+1;
wmOrtho2(0.0f, (float)width, 0.0f, (float)height);
wmLoadIdentity();
// ED_region_pixelspace(CTX_wm_region(C));
}
/* *********************************************************************** */
@ -1198,7 +1206,10 @@ void UI_view2d_grid_free(View2DGrid *grid)
* WARNING: the start of this struct must not change, as view2d_ops.c uses this too.
* For now, we don't need to have a separate (internal) header for structs like this...
*/
struct View2DScrollers {
struct View2DScrollers {
rcti hor, vert; /* exact size of slider backdrop */
int horfull, vertfull; /* set if sliders are full, we don't draw them */
/* focus bubbles */
int vert_min, vert_max; /* vertical scrollbar */
int hor_min, hor_max; /* horizontal scrollbar */
@ -1214,14 +1225,33 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short
{
View2DScrollers *scrollers;
rcti vert, hor;
float fac, totsize, scrollsize;
float fac1, fac2, totsize, scrollsize;
int scroll= view2d_scroll_mapped(v2d->scroll);
/* scrollers is allocated here... */
scrollers= MEM_callocN(sizeof(View2DScrollers), "View2DScrollers");
vert= v2d->vert;
hor= v2d->hor;
/* scrollers is allocated here... */
scrollers= MEM_callocN(sizeof(View2DScrollers), "View2DScrollers");
/* slider rects smaller than region */
hor.xmin+=4;
hor.xmax-=4;
if (scroll & V2D_SCROLL_BOTTOM)
hor.ymin+=4;
else
hor.ymax-=4;
if (scroll & V2D_SCROLL_LEFT)
vert.xmin+=4;
else
vert.xmax-=4;
vert.ymin+=4;
vert.ymax-=4;
/* store in scrollers, used for drawing */
scrollers->vert= vert;
scrollers->hor= hor;
/* scroller 'buttons':
* - These should always remain within the visible region of the scrollbar
@ -1234,14 +1264,23 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short
totsize= v2d->tot.xmax - v2d->tot.xmin;
scrollsize= (float)(hor.xmax - hor.xmin);
fac= (v2d->cur.xmin - v2d->tot.xmin) / totsize;
scrollers->hor_min= (int)(hor.xmin + (fac * scrollsize));
fac1= (v2d->cur.xmin - v2d->tot.xmin) / totsize;
if(fac1<=0.0f)
scrollers->hor_min= hor.xmin;
else
scrollers->hor_min= (int)(hor.xmin + (fac1 * scrollsize));
fac= (v2d->cur.xmax - v2d->tot.xmin) / totsize;
scrollers->hor_max= (int)(hor.xmin + (fac * scrollsize));
fac2= (v2d->cur.xmax - v2d->tot.xmin) / totsize;
if(fac2>=1.0f)
scrollers->hor_max= hor.xmax;
else
scrollers->hor_max= (int)(hor.xmin + (fac2 * scrollsize));
if (scrollers->hor_min > scrollers->hor_max)
scrollers->hor_min= scrollers->hor_max;
if(fac1 <= 0.0f && fac2 >= 1.0f)
scrollers->horfull= 1;
}
/* vertical scrollers */
@ -1250,14 +1289,23 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short
totsize= v2d->tot.ymax - v2d->tot.ymin;
scrollsize= (float)(vert.ymax - vert.ymin);
fac= (v2d->cur.ymin- v2d->tot.ymin) / totsize;
scrollers->vert_min= (int)(vert.ymin + (fac * scrollsize));
fac1= (v2d->cur.ymin- v2d->tot.ymin) / totsize;
if(fac1<=0.0f)
scrollers->vert_min= vert.ymin;
else
scrollers->vert_min= (int)(vert.ymin + (fac1 * scrollsize));
fac= (v2d->cur.ymax - v2d->tot.ymin) / totsize;
scrollers->vert_max= (int)(vert.ymin + (fac * scrollsize));
fac2= (v2d->cur.ymax - v2d->tot.ymin) / totsize;
if(fac2>=1.0f)
scrollers->vert_max= vert.ymax;
else
scrollers->vert_max= (int)(vert.ymin + (fac2 * scrollsize));
if (scrollers->vert_min > scrollers->vert_max)
scrollers->vert_min= scrollers->vert_max;
if(fac1 <= 0.0f && fac2 >= 1.0f)
scrollers->vertfull= 1;
}
/* grid markings on scrollbars */
@ -1287,7 +1335,7 @@ static void scroll_printstr(View2DScrollers *scrollers, Scene *scene, float x, f
* rotation values (hence 'degrees') are divided by 10 to
* be able to show the curves at the same time
*/
if ELEM(unit, V2D_UNIT_DEGREES, V2D_UNIT_TIME) {
if (ELEM(unit, V2D_UNIT_DEGREES, V2D_UNIT_TIME)) {
power += 1;
val *= 10;
}
@ -1393,81 +1441,27 @@ static void scroll_printstr(View2DScrollers *scrollers, Scene *scene, float x, f
void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *vs)
{
Scene *scene= CTX_data_scene(C);
const short darker= -50, dark= -10, light= 20, lighter= 50;
rcti vert, hor, corner;
rcti vert, hor;
int scroll= view2d_scroll_mapped(v2d->scroll);
/* make copies of rects for less typing */
vert= v2d->vert;
hor= v2d->hor;
vert= vs->vert;
hor= vs->hor;
/* horizontal scrollbar */
if (scroll & V2D_SCROLL_HORIZONTAL) {
/* scroller backdrop */
UI_ThemeColorShade(TH_SHADE1, light);
glRecti(hor.xmin, hor.ymin, hor.xmax, hor.ymax);
/* scroller 'button'
* - if view is zoomable in x, draw handles too
* - handles are drawn darker
* - no slider when view is > total for non-zoomable views
* (otherwise, zoomable ones tend to flicker)
*/
if ( (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) ||
((v2d->tot.xmax - v2d->tot.xmin) > (v2d->cur.xmax - v2d->cur.xmin)) )
{
if (v2d->keepzoom & V2D_LOCKZOOM_X) {
/* draw base bar as rounded shape */
UI_ThemeColorShade(TH_SHADE1, dark);
uiSetRoundBox(15);
/* check that box is large enough for round drawing */
if ((vs->hor_max - vs->hor_min) < (V2D_SCROLLCAP_RAD * 2)) {
/* Rounded box still gets drawn at the minimum size limit
* This doesn't represent extreme scaling well, but looks nicer...
*/
float mid= 0.5f * (vs->hor_max + vs->hor_min);
gl_round_box_shade(GL_POLYGON,
mid-V2D_SCROLLCAP_RAD, (float)hor.ymin+2,
mid+V2D_SCROLLCAP_RAD, (float)hor.ymax-2,
V2D_SCROLLCAP_RAD, V2D_SCROLLBAR_SHADE, -V2D_SCROLLBAR_SHADE);
}
else {
/* draw rounded box as per normal */
gl_round_box_shade(GL_POLYGON,
(float)vs->hor_min, (float)hor.ymin+2,
(float)vs->hor_max, (float)hor.ymax-2,
V2D_SCROLLCAP_RAD, V2D_SCROLLBAR_SHADE, -V2D_SCROLLBAR_SHADE);
}
}
else {
/* base bar drawn as shaded rect */
UI_ThemeColorShade(TH_SHADE1, dark);
uiSetRoundBox(0);
gl_round_box_shade(GL_POLYGON,
(float)vs->hor_min, (float)hor.ymin+2,
(float)vs->hor_max, (float)hor.ymax-2,
V2D_SCROLLCAP_RAD, V2D_SCROLLBAR_SHADE, -V2D_SCROLLBAR_SHADE);
/* 'minimum' handle */
uiSetRoundBox(9);
UI_ThemeColorShade(TH_SHADE1, darker);
gl_round_box_shade(GL_POLYGON,
(float)vs->hor_min-V2D_SCROLLER_HANDLE_SIZE, (float)hor.ymin+2,
(float)vs->hor_min+V2D_SCROLLER_HANDLE_SIZE, (float)hor.ymax-2,
V2D_SCROLLCAP_RAD, V2D_SCROLLCAP_SHADE, -V2D_SCROLLCAP_SHADE);
/* maximum handle */
uiSetRoundBox(6);
UI_ThemeColorShade(TH_SHADE1, darker);
gl_round_box_shade(GL_POLYGON,
(float)vs->hor_max-V2D_SCROLLER_HANDLE_SIZE, (float)hor.ymin+2,
(float)vs->hor_max+V2D_SCROLLER_HANDLE_SIZE, (float)hor.ymax-2,
V2D_SCROLLCAP_RAD, V2D_SCROLLCAP_SHADE, -V2D_SCROLLCAP_SHADE);
}
if(vs->horfull==0) {
bTheme *btheme= U.themes.first;
uiWidgetColors wcol= btheme->tui.wcol_scroll;
rcti slider;
slider.xmin= vs->hor_min;
slider.xmax= vs->hor_max;
slider.ymin= hor.ymin;
slider.ymax= hor.ymax;
widget_scroll_draw(&wcol, &hor, &slider, (v2d->scroll_ui & V2D_SCROLL_H_ACTIVE)?UI_SELECT:0);
}
/* scale indicators */
@ -1502,19 +1496,26 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* draw numbers in the appropriate range */
if (dfac > 0.0f) {
for (; fac < hor.xmax; fac+=dfac, val+=grid->dx) {
float h= 2.0f+(float)(hor.ymin);
for (; fac < hor.xmax-10; fac+=dfac, val+=grid->dx) {
/* make prints look nicer for scrollers */
if(fac < hor.xmin+10)
continue;
switch (vs->xunits) {
case V2D_UNIT_FRAMES: /* frames (as whole numbers)*/
scroll_printstr(vs, scene, fac, 3.0f+(float)(hor.ymin), val, grid->powerx, V2D_UNIT_FRAMES, 'h');
scroll_printstr(vs, scene, fac, h, val, grid->powerx, V2D_UNIT_FRAMES, 'h');
break;
case V2D_UNIT_FRAMESCALE: /* frames (not always as whole numbers) */
scroll_printstr(vs, scene, fac, 3.0f+(float)(hor.ymin), val, grid->powerx, V2D_UNIT_FRAMESCALE, 'h');
scroll_printstr(vs, scene, fac, h, val, grid->powerx, V2D_UNIT_FRAMESCALE, 'h');
break;
case V2D_UNIT_SECONDS: /* seconds */
fac2= val/(float)FPS;
scroll_printstr(vs, scene, fac, 3.0f+(float)(hor.ymin), fac2, grid->powerx, V2D_UNIT_SECONDS, 'h');
scroll_printstr(vs, scene, fac, h, fac2, grid->powerx, V2D_UNIT_SECONDS, 'h');
break;
case V2D_UNIT_SECONDSSEQ: /* seconds with special calculations (only used for sequencer only) */
@ -1525,96 +1526,37 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
time= (float)floor(fac2);
fac2= fac2-time;
scroll_printstr(vs, scene, fac, 3.0f+(float)(hor.ymin), time+(float)FPS*fac2/100.0f, grid->powerx, V2D_UNIT_SECONDSSEQ, 'h');
scroll_printstr(vs, scene, fac, h, time+(float)FPS*fac2/100.0f, grid->powerx, V2D_UNIT_SECONDSSEQ, 'h');
}
break;
case V2D_UNIT_DEGREES: /* Graph Editor for rotation Drivers */
/* HACK: although we're drawing horizontal, we make this draw as 'vertical', just to get degree signs */
scroll_printstr(vs, scene, fac, 3.0f+(float)(hor.ymin), val, grid->powerx, V2D_UNIT_DEGREES, 'v');
scroll_printstr(vs, scene, fac, h, val, grid->powerx, V2D_UNIT_DEGREES, 'v');
break;
}
}
}
}
/* decoration outer bevel line */
UI_ThemeColorShade(TH_SHADE1, lighter);
if (scroll & (V2D_SCROLL_BOTTOM|V2D_SCROLL_BOTTOM_O))
sdrawline(hor.xmin, hor.ymax, hor.xmax, hor.ymax);
else if (scroll & V2D_SCROLL_TOP)
sdrawline(hor.xmin, hor.ymin, hor.xmax, hor.ymin);
}
/* vertical scrollbar */
if (scroll & V2D_SCROLL_VERTICAL) {
/* scroller backdrop */
UI_ThemeColorShade(TH_SHADE1, light);
glRecti(vert.xmin, vert.ymin, vert.xmax, vert.ymax);
/* scroller 'button'
* - if view is zoomable in y, draw handles too
* - handles are drawn darker
* - no slider when view is > total for non-zoomable views
* (otherwise, zoomable ones tend to flicker)
*/
if ( (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) ||
((v2d->tot.ymax - v2d->tot.ymin) > (v2d->cur.ymax - v2d->cur.ymin)) )
{
if (v2d->keepzoom & V2D_LOCKZOOM_Y) {
/* draw base bar as rounded shape */
UI_ThemeColorShade(TH_SHADE1, dark);
uiSetRoundBox(15);
/* check that box is large enough for round drawing */
if ((vs->vert_max - vs->vert_min) < (V2D_SCROLLCAP_RAD * 2)) {
/* Rounded box still gets drawn at the minimum size limit
* This doesn't represent extreme scaling well, but looks nicer...
*/
float mid= 0.5f * (vs->vert_max + vs->vert_min);
gl_round_box_vertical_shade(GL_POLYGON,
(float)vert.xmin+2, mid-V2D_SCROLLCAP_RAD,
(float)vert.xmax-2, mid+V2D_SCROLLCAP_RAD,
V2D_SCROLLCAP_RAD, V2D_SCROLLBAR_SHADE, -V2D_SCROLLBAR_SHADE);
}
else {
/* draw rounded box as per normal */
gl_round_box_vertical_shade(GL_POLYGON,
(float)vert.xmin+2, (float)vs->vert_min,
(float)vert.xmax-2, (float)vs->vert_max,
V2D_SCROLLCAP_RAD, V2D_SCROLLBAR_SHADE, -V2D_SCROLLBAR_SHADE);
}
}
else {
/* base bar drawn as shaded rect */
UI_ThemeColorShade(TH_SHADE1, dark);
uiSetRoundBox(0);
gl_round_box_vertical_shade(GL_POLYGON,
(float)vert.xmin+2, (float)vs->vert_min,
(float)vert.xmax-2, (float)vs->vert_max,
V2D_SCROLLCAP_RAD, V2D_SCROLLBAR_SHADE, -V2D_SCROLLBAR_SHADE);
/* 'minimum' handle */
UI_ThemeColorShade(TH_SHADE1, darker);
uiSetRoundBox(12);
gl_round_box_vertical_shade(GL_POLYGON,
(float)vert.xmin+2, (float)vs->vert_min-V2D_SCROLLER_HANDLE_SIZE,
(float)vert.xmax-2, (float)vs->vert_min+V2D_SCROLLER_HANDLE_SIZE,
V2D_SCROLLCAP_RAD, V2D_SCROLLCAP_SHADE, -V2D_SCROLLCAP_SHADE);
/* maximum handle */
UI_ThemeColorShade(TH_SHADE1, darker);
uiSetRoundBox(3);
gl_round_box_vertical_shade(GL_POLYGON,
(float)vert.xmin+2, (float)vs->vert_max-V2D_SCROLLER_HANDLE_SIZE,
(float)vert.xmax-2, (float)vs->vert_max+V2D_SCROLLER_HANDLE_SIZE,
V2D_SCROLLCAP_RAD, V2D_SCROLLCAP_SHADE, -V2D_SCROLLCAP_SHADE);
}
if(vs->vertfull==0) {
bTheme *btheme= U.themes.first;
uiWidgetColors wcol= btheme->tui.wcol_scroll;
rcti slider;
slider.xmin= vert.xmin;
slider.xmax= vert.xmax;
slider.ymin= vs->vert_min;
slider.ymax= vs->vert_max;
widget_scroll_draw(&wcol, &vert, &slider, (v2d->scroll_ui & V2D_SCROLL_V_ACTIVE)?UI_SELECT:0);
}
/* scale indiators */
// XXX will need to update the font drawing when the new stuff comes in
if ((scroll & V2D_SCROLL_SCALE_VERTICAL) && (vs->grid)) {
@ -1644,42 +1586,23 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* draw vertical steps */
if (dfac > 0.0f) {
for (; fac < vert.ymax; fac+= dfac, val += grid->dy) {
scroll_printstr(vs, scene, (float)(vert.xmax)-14.0f, fac, val, grid->powery, vs->yunits, 'v');
BLF_default_rotation(90.0f);
for (; fac < vert.ymax-10; fac+= dfac, val += grid->dy) {
/* make prints look nicer for scrollers */
if(fac < vert.ymin+10)
continue;
scroll_printstr(vs, scene, (float)(vert.xmax)-2.0f, fac, val, grid->powery, vs->yunits, 'v');
}
BLF_default_rotation(0.0f);
}
}
/* decoration outer bevel line */
UI_ThemeColorShade(TH_SHADE1, lighter);
if (scroll & V2D_SCROLL_RIGHT)
sdrawline(vert.xmin, vert.ymin, vert.xmin, vert.ymax);
else if (scroll & V2D_SCROLL_LEFT)
sdrawline(vert.xmax, vert.ymin, vert.xmax, vert.ymax);
}
/* draw a 'sunken square' to cover up any overlapping corners resulting from intersection of overflowing scroller data */
if ((scroll & V2D_SCROLL_VERTICAL) && (scroll & V2D_SCROLL_HORIZONTAL)) {
/* set bounds (these should be right) */
corner.xmin= vert.xmin;
corner.xmax= vert.xmax;
corner.ymin= hor.ymin;
corner.ymax= hor.ymax;
/* firstly, draw using background color to cover up any overlapping junk */
UI_ThemeColor(TH_SHADE1);
glRecti(corner.xmin, corner.ymin, corner.xmax, corner.ymax);
/* now, draw suggestive highlighting... */
/* first, dark lines on top to suggest scrollers overlap box */
UI_ThemeColorShade(TH_SHADE1, darker);
sdrawline(corner.xmin, corner.ymin, corner.xmin, corner.ymax);
sdrawline(corner.xmin, corner.ymax, corner.xmax, corner.ymax);
/* now, light lines on bottom to show box is sunken in */
UI_ThemeColorShade(TH_SHADE1, lighter);
sdrawline(corner.xmax, corner.ymin, corner.xmax, corner.ymax);
sdrawline(corner.xmin, corner.ymin, corner.xmax, corner.ymin);
}
}
/* free temporary memory used for drawing scrollers */

@ -1095,15 +1095,23 @@ static void scroller_activate_init(bContext *C, wmOperator *op, wmEvent *event,
vsm->zone= mouse_in_scroller_handle(y, v2d->vert.ymin, v2d->vert.ymax, scrollers->vert_min, scrollers->vert_max);
}
}
UI_view2d_scrollers_free(scrollers);
ED_region_tag_redraw(ar);
}
/* cleanup temp customdata */
static void scroller_activate_exit(bContext *C, wmOperator *op)
{
if (op->customdata) {
v2dScrollerMove *vsm= op->customdata;
vsm->v2d->scroll_ui &= ~(V2D_SCROLL_H_ACTIVE|V2D_SCROLL_V_ACTIVE);
MEM_freeN(op->customdata);
op->customdata= NULL;
op->customdata= NULL;
ED_region_tag_redraw(CTX_wm_region(C));
}
}
@ -1240,6 +1248,11 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
if(vsm->scroller=='h')
v2d->scroll_ui |= V2D_SCROLL_H_ACTIVE;
else
v2d->scroll_ui |= V2D_SCROLL_V_ACTIVE;
/* still ok, so can add */
WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
return OPERATOR_RUNNING_MODAL;

@ -94,14 +94,15 @@
/* *************************** Calculate Range ************************** */
/* Get the min/max keyframes*/
static void get_graph_keyframe_extents (bAnimContext *ac, float *xmin, float *xmax, float *ymin, float *ymax)
/* note: it should return total boundbox, filter for selection only can be argument... */
void get_graph_keyframe_extents (bAnimContext *ac, float *xmin, float *xmax, float *ymin, float *ymax)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
/* get data to filter, from Dopesheet */
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* set large values to try to override */

@ -82,6 +82,8 @@ enum {
/* ***************************************** */
/* graph_edit.c */
void get_graph_keyframe_extents (struct bAnimContext *ac, float *xmin, float *xmax, float *ymin, float *ymax);
void GRAPHEDIT_OT_previewrange_set(struct wmOperatorType *ot);
void GRAPHEDIT_OT_view_all(struct wmOperatorType *ot);

@ -243,6 +243,10 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar)
/* draw curves twice - unselected, then selected, so that the are fewer occlusion problems */
graph_draw_curves(&ac, sipo, ar, grid, 0);
graph_draw_curves(&ac, sipo, ar, grid, 1);
/* XXX the slow way to set tot rect... but for nice sliders needed (ton) */
get_graph_keyframe_extents(&ac, &v2d->tot.xmin, &v2d->tot.xmax, &v2d->tot.ymin, &v2d->tot.ymax);
}
/* only free grid after drawing data, as we need to use it to determine sampling rate */

@ -118,6 +118,10 @@ typedef struct View2D {
#define V2D_SCROLL_VERTICAL_HIDE (1<<7)
#define V2D_SCROLL_HORIZONTAL_HIDE (1<<8)
/* scroll_ui, activate flag for drawing */
#define V2D_SCROLL_H_ACTIVE (1<<0)
#define V2D_SCROLL_V_ACTIVE (1<<1)
/* alignment flags for totrect, flags use 'shading-out' convention (v2d->align) */
/* all quadrants free */
#define V2D_ALIGN_FREE 0