Browse Source

Implement new Fl_Panzoomer widget, for panning and zooming around a thumbnail instead of scrollbars.

tags/v1.3.1000
Jonathan Moore Liles 12 years ago
parent
commit
ff7f8bdc4d
4 changed files with 1309 additions and 966 deletions
  1. +105
    -0
      FL/Fl_Panzoomer.H
  2. +244
    -0
      src/Fl_Panzoomer.cxx
  3. +1
    -0
      src/Makefile
  4. +959
    -966
      src/makedepend

+ 105
- 0
FL/Fl_Panzoomer.H View File

@@ -0,0 +1,105 @@

/*******************************************************************************/
/* Copyright (C) 2012 Jonathan Moore Liles */
/* */
/* 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; see the file COPYING. If not,write to the Free Software */
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*******************************************************************************/

#ifndef Fl_Panzoomer_H
#define Fl_Panzoomer_H

#include <FL/Fl_Valuator.H>

class FL_EXPORT Fl_Panzoomer : public Fl_Valuator
{
protected:

typedef void (draw_thumbnail_view_callback_t)( int X,int Y,int W,int H,void *v );

draw_thumbnail_view_callback_t *_draw_thumbnail_view_callback;
void *_draw_thumbnail_view_userdata;

int _zoom;
bool _zoom_changed;
int _zoom_min;
int _zoom_max;

double _ymin, _ymax, _xmin, _xmax;
double _xpos, _ypos;

/* size of the window vertically and horizontally as a value
* between 0-1. */
double _ysize, _xsize;

public:

Fl_Panzoomer ( int X, int Y, int W, int H, const char *L=0 );
virtual ~Fl_Panzoomer ( ) { }

virtual void draw ( void );
virtual int handle ( int m );

/* these behave like Fl_Scrollbar::value() */
/* first and total are the bounds, size is the size of the window,
* and pos is the leftmost edge. */
int x_value ( int pos, int size, int first, int total )
{
_xmin = first;
_xmax = total;
_xpos = pos;
_xsize = size;

redraw();

return pos;
}

int y_value ( int pos, int size, int first, int total )
{
_ymin = first;
_ymax = total;
_ypos = pos;
_ysize = size;

redraw();

return pos;
}

double x_value ( void ) const { return _xpos; }
double y_value ( void ) const { return _ypos; }
void x_value ( double v );
void y_value ( double v );

void cursor_bounds ( int &cx, int &cy, int &cw, int &ch ) const;

bool zoom_changed ( void ) const { return _zoom_changed; }
double zoom ( void ) const { return _zoom; }
void zoom ( int v );

void zoom_range ( int zmin, int zmax ) { _zoom_min = zmin; _zoom_max = zmax; }

void zoom_in ( void ) { int z = _zoom; zoom( _zoom + 1 ); if ( z != _zoom ) do_callback(); }
void zoom_out ( void ) { int z = _zoom; zoom( _zoom - 1 ); if ( z != _zoom ) do_callback(); }

/* set this callback if you want to display a thumbnail view of the canvas being scrolled */
void draw_thumbnail_view_callback( draw_thumbnail_view_callback_t *cb, void *v )
{
_draw_thumbnail_view_callback = cb;
_draw_thumbnail_view_userdata = v;
}
};

#endif

+ 244
- 0
src/Fl_Panzoomer.cxx View File

@@ -0,0 +1,244 @@

/*******************************************************************************/
/* Copyright (C) 2012 Jonathan Moore Liles */
/* */
/* 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; see the file COPYING. If not,write to the Free Software */
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*******************************************************************************/

#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Panzoomer.H>

Fl_Panzoomer::Fl_Panzoomer ( int X, int Y, int W, int H, const char *L ) :
Fl_Valuator( X,Y,W,H,L )
{
_zoom = 1;
_zoom_min = 0;
_zoom_max = 4;
_zoom_changed = false;

_ymin = _ymax = _xmin = _xmax = _ysize = _xsize =
_xpos = _ypos = 0;

step( 1 );
}

void
Fl_Panzoomer::x_value ( double v ) {
if ( _xpos == v )
return;

_xpos = v;
if ( _xpos < _xmin )
_xpos = _xmin;
else if ( _xpos > _xmax - _xsize)
_xpos = _xmax - _xsize;

damage( FL_DAMAGE_USER1 );
}

void
Fl_Panzoomer::y_value ( double v ) {
if ( _ypos == v )
return;

_ypos = v;
if ( _ypos < _ymin )
_ypos = _ymin;
else if ( _ypos > _ymax - _ysize )
_ypos = _ymax - _ysize;

damage( FL_DAMAGE_USER1 );
}

void
Fl_Panzoomer::zoom ( int v )
{
int z = _zoom;

_zoom = v;

if ( _zoom > _zoom_max )
_zoom = _zoom_max;
else
if ( _zoom < _zoom_min )
_zoom = _zoom_min;

if ( z != _zoom )
{
_zoom_changed = true;
do_callback();
_zoom_changed = false;
}
}

void
Fl_Panzoomer::draw ( void )
{
type( FL_HORIZONTAL );

fl_draw_box( box(), x(),y(),w(),h(), color());
// fl_rectf( x(),y(),w(),h(), color() );

fl_push_clip( x(), y(), w(), h());

int X,Y,W,H;
X = x() + Fl::box_dx( box() );
Y = y() + Fl::box_dy( box() );
W = w() - Fl::box_dw( box() );
H = h() - Fl::box_dh( box() );
if ( _draw_thumbnail_view_callback )
_draw_thumbnail_view_callback( X,Y,W,H, _draw_thumbnail_view_userdata );

int cx,cy,cw,ch;

cursor_bounds( cx,cy,cw,ch );

fl_rectf( cx,cy,cw,ch,
fl_color_add_alpha( FL_WHITE, 50 ));

fl_rect( cx,cy,cw,ch,
fl_color_add_alpha( FL_WHITE, 80 ));
fl_pop_clip();

draw_label();
}

void
Fl_Panzoomer::cursor_bounds ( int &cx, int &cy, int &cw, int &ch ) const
{
int X,Y,W,H;
X = x() + Fl::box_dx( box() );
Y = y() + Fl::box_dy( box() );
W = w() - Fl::box_dw( box() );
H = h() - Fl::box_dh( box() );

double hval;
if ( _xmin == _xmax )
hval = 0.5;
else
{
hval = (_xpos-_xmin)/(_xmax-_xmin);

if (hval > 1.0) hval = 1.0;
else if (hval < 0.0) hval = 0.0;
}

double vval;
if ( _ymin == _ymax )
vval = 0.5;
else
{
vval = (_ypos-_ymin)/(_ymax-_ymin);

if (vval > 1.0) vval = 1.0;
else if (vval < 0.0) vval = 0.0;
}

cx = X + (hval) * W + .5;
cy = _ymax ? Y + (vval) * H + .5 : Y;
cw = W * (_xsize/_xmax);
ch = _ymax ? H * (_ysize/_ymax) : H;
}

int
Fl_Panzoomer::handle ( int m )
{
static int xoffset;
static int yoffset;
static bool drag;

switch ( m )
{
case FL_ENTER:
case FL_LEAVE:
return 1;
case FL_PUSH:
{
int cx,cy,cw,ch;

cursor_bounds( cx,cy,cw,ch );

xoffset = Fl::event_x() - cx;
yoffset = Fl::event_y() - cy;

if ( Fl::event_inside( cx,cy,cw,ch ) &&
Fl::event_button1() )
drag = true;

return 1;
}
case FL_DRAG:
{
int cx,cy,cw,ch;
cursor_bounds( cx,cy,cw,ch );
if ( drag )
{
x_value((((double)Fl::event_x() - x() - xoffset) / w()) * _xmax);
y_value( (((double)Fl::event_y() - y() - yoffset) / h()) * _ymax );
if ( when() & FL_WHEN_CHANGED )
do_callback();
}
return 1;
break;
}
case FL_MOUSEWHEEL:
{
int d = Fl::event_dy();

if ( Fl::event_ctrl() )
{
zoom( _zoom + d );
return 1;
}
else if (!Fl::event_alt() && !Fl::event_shift())
{
y_value( _ypos + ( (double)d*5 / h() ) * _ymax );
if ( when() & FL_WHEN_CHANGED )
do_callback();

return 1;
}
return 0;
break;
}
case FL_RELEASE:
{
if ( drag )
{
drag = false;

if ( when() & FL_WHEN_RELEASE )
do_callback();
}
return 1;
}
}

return 0;
}


+ 1
- 0
src/Makefile View File

@@ -69,6 +69,7 @@ CPPFILES = \
Fl_Overlay_Window.cxx \
Fl_Pack.cxx \
Fl_Paged_Device.cxx \
Fl_Panzoomer.cxx \
Fl_Pixmap.cxx \
Fl_Positioner.cxx \
Fl_Preferences.cxx \


+ 959
- 966
src/makedepend
File diff suppressed because it is too large
View File


Loading…
Cancel
Save