Update NTK.
[nondaw.git] / FL / Fl_Packscroller.H
blob3e67858851e0bc5037aa493c3e867d0398a2cfee
2 /*******************************************************************************/
3 /* Copyright (C) 2010 Jonathan Moore Liles                                     */
4 /*                                                                             */
5 /* This program is free software; you can redistribute it and/or modify it     */
6 /* under the terms of the GNU General Public License as published by the       */
7 /* Free Software Foundation; either version 2 of the License, or (at your      */
8 /* option) any later version.                                                  */
9 /*                                                                             */
10 /* This program is distributed in the hope that it will be useful, but WITHOUT */
11 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       */
12 /* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for   */
13 /* more details.                                                               */
14 /*                                                                             */
15 /* You should have received a copy of the GNU General Public License along     */
16 /* with This program; see the file COPYING.  If not,write to the Free Software */
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18 /*******************************************************************************/
20 /* Scrolling group suitable for containing a single child (a
21  * pack). When the Fl_Packscroller is resized, the child will be resized
22  * too. No scrollbars are displayed, but the widget responds to
23  * FL_MOUSEWHEEL events. */
25 #pragma once
27 #include <FL/Fl_Group.H>
28 #include <FL/fl_draw.H>
29 #include <FL/Fl.H>
31 /* FIXME: Optimize scroll */
33 class Fl_Packscroller : public Fl_Group
36     int _increment;
37     int _yposition;
38     static const int sbh = 15;                                  /* scroll button height */
40 public:
42     Fl_Packscroller ( int X, int Y, int W, int H, const char *L = 0 ) : Fl_Group( X, Y, W, H, L )
43         {
44             _increment = 30;
45             _yposition = 0;
47 //            color( FL_WHITE );
48         }
50     int increment ( void ) const { return _increment; }
51     void increment ( int v ) { _increment = v; }
53     void yposition ( int v )
54         {
55             if ( ! children() )
56                 return;
58             int Y = v;
60             if ( Y > 0 )
61                 Y = 0;
63             const int H = h() - (sbh * 2);
65             Fl_Widget *o = child( 0 );
67             if ( o->h() > H &&
68                  Y + o->h() < H )
69                 Y = H - o->h();
70             else if ( o->h() < H )
71                 Y = 0;
73             if ( _yposition != Y )
74             {
75                 _yposition = Y;
77                 damage( FL_DAMAGE_SCROLL );
78             }
79         }
81     int yposition ( void ) const
82         {
83             if ( children() )
84                 return child( 0 )->y() - (y() + sbh);
86             return 0;
87         }
89     void bbox ( int &X, int &Y, int &W, int &H )
90         {
91             X = x();
92             Y = y() + sbh;
93             W = w();
94             H = h() - (sbh * 2);
95         }
97     virtual void
98     draw ( void )
99         {
100             if ( ! children() )
101                 return;
103             if ( ! fl_not_clipped( x(), y(), w(), h() ) )
104                 return;
106 //            draw_box();
108             Fl_Widget *o = child( 0 );
110             o->position( x(), y() + sbh + _yposition );
112             if ( damage() != FL_DAMAGE_CHILD )
113             {
114                 fl_rectf( x(), y(), w(), h(), color() );
116                 fl_font( FL_HELVETICA, 12 );
118                 if ( o->y() != y() + sbh )
119                 {
120                     fl_draw_box( box(), x(), y(), w(), sbh, color() );
121                     fl_color( FL_BLACK );
122                     fl_draw( "@2<", x(), y(), w(), sbh, FL_ALIGN_CENTER );
123                 }
125                 if ( o->h() > h() - (sbh * 2) && o->y() + o->h() != y() + h() - sbh )
126                 {
127                     fl_draw_box( box(), x(), y() + h() - sbh, w(), sbh, color() );
128                     fl_color( FL_BLACK );
129                     fl_draw( "@2>", x(), y() + h() - sbh, w(), sbh, FL_ALIGN_CENTER );
130                 }
132             }
134             fl_push_clip( x(), y() + sbh, w(), h() - (sbh * 2 ) );
136             draw_children();
138             fl_pop_clip();
139         }
141     virtual int
142     handle ( int m )
143         {
144             if ( Fl_Group::handle( m ) )
145                 return 1;
147             switch ( m )
148             {
149                 case FL_PUSH:
150                 {
151                     if ( Fl::event_button1() )
152                     {
153                         if ( Fl::event_inside( x(), y(), w(), sbh ) )
154                         {
155                             yposition( yposition() + ( h() / 4 ) );
156                             return 1;
157                         }
158                         else if ( Fl::event_inside(  x(), y() + h() - sbh, w(), sbh ) )
159                         {
160                             yposition( yposition() - (h() / 4 ) );
161                             return 1;
162                         }
164                         return 0;
165                     }
166                 }
167                 return 0;
168                 case FL_ENTER:
169                 case FL_LEAVE:
170                     return 1;
171                 case FL_FOCUS:
172                 case FL_UNFOCUS:
173                     return 1;
174                 case FL_KEYBOARD:
175                 {
176                     if ( Fl::event_key() == FL_Up )
177                     {
178                         yposition( yposition() + ( h() / 4 ) );
179                         return 1;
180                     }
181                     else if ( Fl::event_key() == FL_Down )
182                     {
183                         yposition( yposition() - (h() / 4 ) );
184                         return 1;
185                     }
186                     return 0;
187                 }
188                 case FL_MOUSEWHEEL:
189                 {
190                     yposition( yposition() - ( Fl::event_dy() * _increment ) );
192                     return 1;
193                 }
194             }
196             return 0;
197         }