diff options
Diffstat (limited to 'source/blender/editors/interface/view2d.c')
-rw-r--r-- | source/blender/editors/interface/view2d.c | 178 |
1 files changed, 79 insertions, 99 deletions
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index 6cc344b891e..2bdf1ea4c88 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -15,7 +15,7 @@ * * 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. + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2008 Blender Foundation. * All rights reserved. @@ -25,6 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include <float.h> #include <limits.h> #include <math.h> #include <string.h> @@ -50,6 +51,7 @@ #include "BLF_api.h" +#include "ED_anim_api.h" #include "ED_screen.h" #include "UI_interface.h" @@ -60,7 +62,12 @@ /* *********************************************************************** */ -/* helper to allow scrollbars to dynamically hide */ +/* helper to allow scrollbars to dynamically hide + * - returns a copy of the scrollbar settings with the flags to display + * horizontal/vertical scrollbars removed + * - input scroll value is the v2d->scroll var + * - hide flags are set per region at drawtime + */ static int view2d_scroll_mapped(int scroll) { if(scroll & V2D_SCROLL_HORIZONTAL_HIDE) @@ -268,7 +275,9 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) v2d->keeptot= V2D_KEEPTOT_BOUNDS; v2d->scroll |= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM); - + v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE; + v2d->scroll &= ~V2D_SCROLL_VERTICAL_HIDE; + v2d->tot.xmin= 0.0f; v2d->tot.xmax= winx; @@ -280,8 +289,7 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) v2d->cur.xmax= (winx - V2D_SCROLL_WIDTH)*panelzoom; v2d->cur.ymax= 0.0f; - /* bad workaround for keeping zoom level with scrollers */ - v2d->cur.ymin= (-winy + V2D_SCROLL_HEIGHT)*panelzoom; + v2d->cur.ymin= (-winy)*panelzoom; } break; @@ -347,11 +355,14 @@ void UI_view2d_curRect_validate_resize(View2D *v2d, int resize) if (v2d->keepzoom & V2D_LOCKZOOM_Y) height= winy; - /* values used to divide, so make it safe */ - if(width<1) width= 1; - if(height<1) height= 1; - if(winx<1) winx= 1; - if(winy<1) winy= 1; + /* values used to divide, so make it safe + * NOTE: width and height must use FLT_MIN instead of 1, otherwise it is impossible to + * get enough resolution in Graph Editor for editing some curves + */ + if(width < FLT_MIN) width= 1; + if(height < FLT_MIN) height= 1; + if(winx < 1) winx= 1; + if(winy < 1) winy= 1; /* V2D_LIMITZOOM indicates that zoom level should be preserved when the window size changes */ if (resize && (v2d->keepzoom & V2D_KEEPZOOM)) { @@ -838,7 +849,8 @@ void UI_view2d_totRect_set_resize (View2D *v2d, int width, int height, int resiz height -= V2D_SCROLL_HEIGHT; if (ELEM3(0, v2d, width, height)) { - printf("Error: View2D totRect set exiting: v2d=%p width=%d height=%d \n", v2d, width, height); // XXX temp debug info + if (G.f & G_DEBUG) + printf("Error: View2D totRect set exiting: v2d=%p width=%d height=%d \n", v2d, width, height); // XXX temp debug info return; } @@ -984,7 +996,7 @@ void UI_view2d_view_ortho(const bContext *C, View2D *v2d) wmOrtho2(curmasked.xmin-xofs, curmasked.xmax-xofs, curmasked.ymin-yofs, curmasked.ymax-yofs); /* XXX is this necessary? */ - wmLoadIdentity(); + glLoadIdentity(); } /* Set view matrices to only use one axis of 'cur' only @@ -1013,7 +1025,7 @@ void UI_view2d_view_orthoSpecial(const bContext *C, View2D *v2d, short xaxis) wmOrtho2(-xofs, ar->winx-xofs, curmasked.ymin-yofs, curmasked.ymax-yofs); /* XXX is this necessary? */ - wmLoadIdentity(); + glLoadIdentity(); } @@ -1025,7 +1037,7 @@ void UI_view2d_view_restore(const bContext *C) int height= ar->winrct.ymax-ar->winrct.ymin+1; wmOrtho2(0.0f, (float)width, 0.0f, (float)height); - wmLoadIdentity(); + glLoadIdentity(); // ED_region_pixelspace(CTX_wm_region(C)); } @@ -1033,9 +1045,6 @@ void UI_view2d_view_restore(const bContext *C) /* *********************************************************************** */ /* Gridlines */ -/* minimum pixels per gridstep */ -#define MINGRIDSTEP 35 - /* View2DGrid is typedef'd in UI_view2d.h */ struct View2DGrid { float dx, dy; /* stepsize (in pixels) between gridlines */ @@ -1126,7 +1135,7 @@ View2DGrid *UI_view2d_grid_calc(const bContext *C, View2D *v2d, short xunits, sh space= v2d->cur.xmax - v2d->cur.xmin; pixels= (float)(v2d->mask.xmax - v2d->mask.xmin); - grid->dx= (MINGRIDSTEP * space) / (seconddiv * pixels); + grid->dx= (U.v2d_min_gridsize * space) / (seconddiv * pixels); step_to_grid(&grid->dx, &grid->powerx, xunits); grid->dx *= seconddiv; @@ -1142,7 +1151,7 @@ View2DGrid *UI_view2d_grid_calc(const bContext *C, View2D *v2d, short xunits, sh space= v2d->cur.ymax - v2d->cur.ymin; pixels= (float)winy; - grid->dy= MINGRIDSTEP * space / pixels; + grid->dy= U.v2d_min_gridsize * space / pixels; step_to_grid(&grid->dy, &grid->powery, yunits); if (yclamp == V2D_GRID_CLAMP) { @@ -1187,7 +1196,7 @@ void UI_view2d_grid_draw(const bContext *C, View2D *v2d, View2DGrid *grid, int f vec2[1]= v2d->cur.ymax; /* minor gridlines */ - step= (v2d->mask.xmax - v2d->mask.xmin + 1) / MINGRIDSTEP; + step= (v2d->mask.xmax - v2d->mask.xmin + 1) / U.v2d_min_gridsize; UI_ThemeColor(TH_GRID); for (a=0; a<step; a++) { @@ -1221,7 +1230,7 @@ void UI_view2d_grid_draw(const bContext *C, View2D *v2d, View2DGrid *grid, int f vec1[0]= grid->startx; vec2[0]= v2d->cur.xmax; - step= (v2d->mask.ymax - v2d->mask.ymin + 1) / MINGRIDSTEP; + step= (v2d->mask.ymax - v2d->mask.ymin + 1) / U.v2d_min_gridsize; UI_ThemeColor(TH_GRID); for (a=0; a<=step; a++) { @@ -1367,6 +1376,9 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short vert.ymin+=4; vert.ymax-=4; + CLAMP(vert.ymin, vert.ymin, vert.ymax-V2D_SCROLLER_HANDLE_SIZE); + CLAMP(hor.xmin, hor.xmin, hor.xmax-V2D_SCROLLER_HANDLE_SIZE); + /* store in scrollers, used for drawing */ scrollers->vert= vert; scrollers->hor= hor; @@ -1405,10 +1417,14 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short CLAMP(scrollers->hor_min, hor.xmin, hor.xmax-V2D_SCROLLER_HANDLE_SIZE); } - /* check whether sliders can disappear */ + /* check whether sliders can disappear due to the full-range being used */ if(v2d->keeptot) { - if(fac1 <= 0.0f && fac2 >= 1.0f) + if ((fac1 <= 0.0f) && (fac2 >= 1.0f)) { + v2d->scroll |= V2D_SCROLL_HORIZONTAL_FULLR; scrollers->horfull= 1; + } + else + v2d->scroll &= ~V2D_SCROLL_HORIZONTAL_FULLR; } } @@ -1442,10 +1458,14 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short CLAMP(scrollers->vert_min, vert.ymin, vert.ymax-V2D_SCROLLER_HANDLE_SIZE); } - /* check whether sliders can disappear */ + /* check whether sliders can disappear due to the full-range being used */ if(v2d->keeptot) { - if(fac1 <= 0.0f && fac2 >= 1.0f) + if ((fac1 <= 0.0f) && (fac2 >= 1.0f)) { + v2d->scroll |= V2D_SCROLL_VERTICAL_FULLR; scrollers->vertfull= 1; + } + else + v2d->scroll &= ~V2D_SCROLL_VERTICAL_FULLR; } } @@ -1483,72 +1503,7 @@ static void scroll_printstr(View2DScrollers *scrollers, Scene *scene, float x, f } /* get string to print */ - if (unit == V2D_UNIT_SECONDS) { - /* Timecode: - * - In general, minutes and seconds should be shown, as most clips will be - * within this length. Hours will only be included if relevant. - * - Only show frames when zoomed in enough for them to be relevant - * (using separator of '!' for frames). - * When showing frames, use slightly different display to avoid confusion with mm:ss format - * TODO: factor into reusable function. - * Meanwhile keep in sync: - * source/blender/editors/animation/anim_draw.c - * source/blender/editors/interface/view2d.c - */ - int hours=0, minutes=0, seconds=0, frames=0; - char neg[2]= ""; - - /* get values */ - if (val < 0) { - /* correction for negative values */ - sprintf(neg, "-"); - val = -val; - } - if (val >= 3600) { - /* hours */ - /* XXX should we only display a single digit for hours since clips are - * VERY UNLIKELY to be more than 1-2 hours max? However, that would - * go against conventions... - */ - hours= (int)val / 3600; - val= (float)fmod(val, 3600); - } - if (val >= 60) { - /* minutes */ - minutes= (int)val / 60; - val= (float)fmod(val, 60); - } - if (power <= 0) { - /* seconds + frames - * Frames are derived from 'fraction' of second. We need to perform some additional rounding - * to cope with 'half' frames, etc., which should be fine in most cases - */ - seconds= (int)val; - frames= (int)floor( ((val - seconds) * FPS) + 0.5f ); - } - else { - /* seconds (with pixel offset) */ - seconds= (int)floor(val + 0.375f); - } - - /* print timecode to temp string buffer */ - if (power <= 0) { - /* include "frames" in display */ - if (hours) sprintf(str, "%s%02d:%02d:%02d!%02d", neg, hours, minutes, seconds, frames); - else if (minutes) sprintf(str, "%s%02d:%02d!%02d", neg, minutes, seconds, frames); - else sprintf(str, "%s%d!%02d", neg, seconds, frames); - } - else { - /* don't include 'frames' in display */ - if (hours) sprintf(str, "%s%02d:%02d:%02d", neg, hours, minutes, seconds); - else sprintf(str, "%s%02d:%02d", neg, minutes, seconds); - } - } - else { - /* round to whole numbers if power is >= 1 (i.e. scale is coarse) */ - if (power <= 0) sprintf(str, "%.*f", 1-power, val); - else sprintf(str, "%d", (int)floor(val + 0.375f)); - } + ANIM_timecode_string_from_frame(str, scene, power, (unit == V2D_UNIT_SECONDS), val); /* get length of string, and adjust printing location to fit it into the horizontal scrollbar */ len= strlen(str); @@ -1597,10 +1552,20 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v state= (v2d->scroll_ui & V2D_SCROLL_H_ACTIVE)?UI_SCROLL_PRESSED:0; - // TODO: disable this for button regions... - if (!(v2d->keepzoom & V2D_LOCKZOOM_X)) + /* show zoom handles if: + * - zooming on x-axis is allowed (no scroll otherwise) + * - slider bubble is large enough (no overdraw confusion) + * - scale is shown on the scroller + * (workaround to make sure that button windows don't show these, + * and only the time-grids with their zoomability can do so) + */ + if ((v2d->keepzoom & V2D_LOCKZOOM_X)==0 && + (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) && + (slider.xmax - slider.xmin > V2D_SCROLLER_HANDLE_SIZE)) + { state |= UI_SCROLL_ARROWS; - + } + uiWidgetScrollDraw(&wcol, &hor, &slider, state); } @@ -1695,9 +1660,19 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v state= (v2d->scroll_ui & V2D_SCROLL_V_ACTIVE)?UI_SCROLL_PRESSED:0; - // TODO: disable this for button regions... - if (!(v2d->keepzoom & V2D_LOCKZOOM_Y)) + /* show zoom handles if: + * - zooming on y-axis is allowed (no scroll otherwise) + * - slider bubble is large enough (no overdraw confusion) + * - scale is shown on the scroller + * (workaround to make sure that button windows don't show these, + * and only the time-grids with their zoomability can do so) + */ + if ((v2d->keepzoom & V2D_LOCKZOOM_Y)==0 && + (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) && + (slider.ymax - slider.ymin > V2D_SCROLLER_HANDLE_SIZE)) + { state |= UI_SCROLL_ARROWS; + } uiWidgetScrollDraw(&wcol, &vert, &slider, state); } @@ -1725,7 +1700,6 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v val= grid->starty; /* if vertical clamping (to whole numbers) is used (i.e. in Sequencer), apply correction */ - // XXX only relevant to Sequencer, so need to review this when we port that code if (vs->yclamp == V2D_GRID_CLAMP) fac += 0.5f * dfac; @@ -2067,7 +2041,10 @@ void UI_view2d_text_cache_draw(ARegion *ar) { View2DString *v2s; - // wmPushMatrix(); + // glMatrixMode(GL_PROJECTION); + // glPushMatrix(); + // glMatrixMode(GL_MODELVIEW); + // glPushMatrix(); ED_region_pixelspace(ar); for(v2s= strings.first; v2s; v2s= v2s->next) { @@ -2089,7 +2066,10 @@ void UI_view2d_text_cache_draw(ARegion *ar) } } - // wmPopMatrix(); + // glMatrixMode(GL_PROJECTION); + // glPopMatrix(); + // glMatrixMode(GL_MODELVIEW); + // glPopMatrix(); if(strings.first) BLI_freelistN(&strings); |