|
-
- /*******************************************************************************/
- /* Copyright (C) 2010 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. */
- /*******************************************************************************/
-
- /* Scrolling group suitable for containing a single child (a
- * pack). When the Fl_Packscroller is resized, the child will be resized
- * too. No scrollbars are displayed, but the widget responds to
- * FL_MOUSEWHEEL events. */
-
- #pragma once
-
- #include <FL/Fl_Group.H>
- #include <FL/fl_draw.H>
- #include <FL/Fl.H>
-
- /* FIXME: Optimize scroll */
-
- class Fl_Packscroller : public Fl_Group
- {
- int _increment;
- int _yposition;
- static const int sbh = 15; /* scroll button height */
-
- public:
-
- Fl_Packscroller ( int X, int Y, int W, int H, const char *L = 0 ) : Fl_Group( X, Y, W, H, L )
- {
- _increment = 30;
- _yposition = 0;
- // color( FL_WHITE );
- }
-
- int increment ( void ) const { return _increment; }
- void increment ( int v ) { _increment = v; }
-
- void yposition ( int v )
- {
- if ( ! children() )
- return;
-
- int Y = v;
-
- if ( Y > 0 )
- Y = 0;
-
- const int H = h();
- // - (sbh * 2);
-
- Fl_Widget *o = child( 0 );
-
- if ( o->h() > H &&
- Y + o->h() < H )
- Y = H - o->h();
- else if ( o->h() < H )
- Y = 0;
-
- if ( _yposition != Y )
- {
- _yposition = Y;
-
- damage( FL_DAMAGE_SCROLL );
- }
- }
-
- int yposition ( void ) const
- {
- if ( children() )
- return child( 0 )->y() - (y() + sbh);
-
- return 0;
- }
-
- void bbox ( int &X, int &Y, int &W, int &H )
- {
- X = x();
- Y = y() + ( sbh * top_sb_visible() );
- W = w();
- H = h() - ( sbh * ( top_sb_visible() + bottom_sb_visible() ) );
- }
-
- int top_sb_visible ( void )
- {
- return children() && child(0)->y() != y() ? 1 : 0;
- }
-
- int bottom_sb_visible ( void )
- {
- if ( children() )
- {
- Fl_Widget *o = child( 0 );
-
- if ( o->h() > h() && o->y() + o->h() != y() + h() )
- return 1;
- }
-
- return 0;
- }
-
- virtual void
- draw ( void )
- {
- if ( damage() & FL_DAMAGE_ALL )
- {
- fl_rectf( x(), y(), w(), h(), color() );
- }
-
- if ( ! children() )
- return;
-
- Fl_Widget *o = child( 0 );
-
- o->position( x(), y() + _yposition );
-
- const int top_sb = top_sb_visible();
- const int bottom_sb = bottom_sb_visible();
-
- fl_push_clip( x(), y() + ( sbh * top_sb ), w(), h() - (sbh * (top_sb + bottom_sb) ));
-
- draw_children();
-
- fl_pop_clip();
-
- fl_font( FL_HELVETICA, 12 );
-
- if ( top_sb )
- {
- fl_draw_box( box(), x(), y(), w(), sbh, color() );
- fl_color( fl_contrast( FL_FOREGROUND_COLOR, color() ) );
- fl_draw( "@2<", x(), y(), w(), sbh, FL_ALIGN_CENTER );
- }
-
- if ( bottom_sb )
- {
- fl_draw_box( box(), x(), y() + h() - sbh, w(), sbh, color() );
- fl_color( fl_contrast( FL_FOREGROUND_COLOR, color() ) );
- fl_draw( "@2>", x(), y() + h() - sbh, w(), sbh, FL_ALIGN_CENTER );
- }
- }
-
- virtual int
- handle ( int m )
- {
- switch ( m )
- {
- case FL_PUSH:
- if ( top_sb_visible() &&
- Fl::event_inside( x(), y(), w(), sbh ) )
- {
- return 1;
- }
- else if ( bottom_sb_visible() &&
- Fl::event_inside( x(), y() + h() - sbh, w(), sbh ) )
- {
- return 1;
- }
- break;
- case FL_RELEASE:
- {
- if ( top_sb_visible() &&
- Fl::event_inside( x(), y(), w(), sbh ) )
- {
- yposition( yposition() + ( h() / 4 ) );
- return 1;
- }
- else if ( bottom_sb_visible() &&
- Fl::event_inside( x(), y() + h() - sbh, w(), sbh ) )
- {
- yposition( yposition() - (h() / 4 ) );
- return 1;
- }
- break;
- }
- case FL_KEYBOARD:
- {
- if ( Fl::event_key() == FL_Up )
- {
- yposition( yposition() + ( h() / 4 ) );
- return 1;
- }
- else if ( Fl::event_key() == FL_Down )
- {
- yposition( yposition() - (h() / 4 ) );
- return 1;
- }
- break;
- }
- case FL_MOUSEWHEEL:
- {
- yposition( yposition() - ( Fl::event_dy() * _increment ) );
-
- return 1;
- }
- }
-
- return Fl_Group::handle( m );
- }
- };
|