Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

gadget_Scroller.c

Go to the documentation of this file.
00001 /*
00002  *    gui - [gega user interface] the flexible solution for user interface problems
00003  *    Copyright (C) 2002  Gergely Gati
00004  *
00005  *    This program is free software; you can redistribute it and/or modify
00006  *    it under the terms of the GNU General Public License as published by
00007  *    the Free Software Foundation; version 2 of the License.
00008  *
00009  *    This program is distributed in the hope that it will be useful,
00010  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *    GNU General Public License for more details.
00013  *
00014  *    You should have received a copy of the GNU General Public License
00015  *    along with this program; if not, write to the Free Software
00016  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  *
00018  *    Gergely Gati
00019  *      email:           g.gati@freemail.hu
00020  *      AIM screenname:  GatiGergely
00021  *      ICQ number:      93131690
00022  *
00023  */
00024 #include <stdlib.h>
00025 
00026 #include "debug.h"
00027 #include "classes.h"
00028 #include "Bases.h"
00029 #include "Module.h"
00030 #include "Gadget.h"
00031 #include "gadgets/gadget_Scroller.h"
00032 #include "Window.h"
00033 #include "Common.h"
00034 
00035 
00036 struct _scroller
00037 {
00038   Gadget_t gadget;
00039   int total;
00040   int visible;
00041   int position;
00042   int othersize;
00043   int orientation;
00044   int poshandleknob;
00045   int gad_left;
00046   int gad_top;
00047   Rect_t knob_rect;
00048 };
00049 
00050 
00051 static u32 scroller_set_property(Gadget_t *this_gadget, tag *taglist);
00052 static u32 scroller_get_property(Gadget_t *this_gadget, tag *taglist);
00053 
00054 
00055 static bases_Modules_t *api;
00056 VERSION("Scroller.gadget",1,0,"Gergely Gati","g.gati@freemail.hu");
00057 
00058 
00059 static gadget_Method_t methods[]=
00060 {
00061   {"scroller_set_property",scroller_set_property,0L},
00062   {"scroller_get_property",scroller_get_property,0L},
00063   GADGET_METHOD_DONE
00064 };
00065 
00066 
00067 static gadget_Binding_t binding[]=
00068 {
00069   {"orientation",TAG_SCR_ORIENTATION,GADGET_SELECT,"vertical|horizontal"},
00070   {"total",TAG_SCR_TOTAL,GADGET_INT,NULL},
00071   {"visible",TAG_SCR_VISIBLE,GADGET_INT,NULL},
00072   {"position",TAG_SCR_POSITION,GADGET_INT,NULL},
00073   {"othersize",TAG_SCR_OTHERSIZE,GADGET_INT,NULL},
00074   GADGET_BINDING_DONE
00075 };
00076 
00077 static char *custom_names[]=
00078 {
00079   "knob_up",
00080   "knob_down",
00081   NULL
00082 };
00083 
00084 
00085 static u32 scroller_set_property(Gadget_t *this_gadget, tag *taglist)
00086 {
00087   scroller *gad=(scroller *)this_gadget;
00088 
00089   debug_Begin();
00090 
00091   gad->total=(int)tag_GetTagData(taglist,TAG_SCR_TOTAL,(u32)gad->total);
00092   gad->visible=(int)tag_GetTagData(taglist,TAG_SCR_VISIBLE,(u32)gad->visible);
00093   gad->position=(int)tag_GetTagData(taglist,TAG_SCR_POSITION,(u32)gad->position);
00094   api->gadget_Call(GADGET_REFRESH,TAG_GADGET_OBJECT,this_gadget,TAG_DONE);
00095 
00096   debug_End();
00097   return(0L);
00098 }
00099 
00100 static u32 scroller_get_property(Gadget_t *this_gadget, tag *taglist)
00101 {
00102   scroller *gad=(scroller *)this_gadget;
00103   int *retval;
00104   int trash;
00105 
00106   debug_Begin();
00107 
00108   retval=(int *)tag_GetTagData(taglist,TAG_SCR_TOTAL,(u32)&trash);
00109   *retval=gad->total;
00110   retval=(int *)tag_GetTagData(taglist,TAG_SCR_VISIBLE,(u32)&trash);
00111   *retval=gad->visible;
00112   retval=(int *)tag_GetTagData(taglist,TAG_SCR_POSITION,(u32)&trash);
00113   *retval=gad->position;
00114   retval=(int *)tag_GetTagData(taglist,TAG_SCR_OTHERSIZE,(u32)&trash);
00115   *retval=gad->othersize;
00116   retval=(int *)tag_GetTagData(taglist,TAG_SCR_ORIENTATION,(u32)&trash);
00117   *retval=gad->orientation;
00118 
00119   debug_End();
00120   return(0L);
00121 }
00122 
00123 
00124 /*
00125  *  This function is always called after the Gadget_t has been created and
00126  *  attached to the Gadget_t tree, but before the call to scroller_layout(). It may be
00127  *  called more than once. It must fill in the Gadget_t's minimum and maximum
00128  *  sizes into the supplied extent structures.
00129  */
00130 static void scroller_get_extent(Gadget_t *this, Extent_t *min, Extent_t *max)
00131 {
00132   scroller *gad=(scroller *)this;
00133 
00134   debug_Begin();
00135 
00136   if(gad->othersize==0) gad->othersize=api->glw_Call(GLW_GETFONTSIZE,TAG_GLW_FONT,api->gadget_Call(GADGET_GET_FONT,TAG_GADGET_OBJECT,this,TAG_DONE),TAG_DONE);
00137   min->width=(gad->orientation==SCR_VERTICAL?gad->othersize:10);
00138   min->height=(gad->orientation==SCR_VERTICAL?10:gad->othersize);
00139   max->width=(gad->orientation==SCR_VERTICAL?gad->othersize:GADGET_MAXIMUM_SIZE);
00140   max->height=(gad->orientation==SCR_VERTICAL?GADGET_MAXIMUM_SIZE:gad->othersize);
00141 
00142   debug_End();
00143 }
00144 
00145 
00146 /*
00147  *  This function is called always after scroller_get_extent() has been called at
00148  *  least once. It receives a position and an extent which determine the
00149  *  position and the size of the Gadget_t on the screen. This 4 is always
00150  *  between the minimum and maximum sizes which were returned by
00151  *  scroller_get_extent() of the same gadget. After this call the Gadget_t is made
00152  *  visible.
00153  */
00154 static void scroller_layout(Gadget_t *this, Rect_t *rect)
00155 {
00156   scroller *gad=(scroller *)this;
00157   int knob_size,knob_pos,gad_size;
00158 
00159   debug_Begin();
00160 
00161   gad->gad_left=rect->left;
00162   gad->gad_top=rect->top;
00163   gad_size=(gad->orientation==SCR_VERTICAL?(rect->height):(rect->width));
00164   knob_size=(gad->visible*gad_size)/gad->total;
00165   knob_pos=(gad_size*gad->position)/gad->total;
00166   if(knob_size<4) knob_size=4;
00167   if(knob_pos+knob_size>gad_size) knob_pos--;
00168   gad->knob_rect.left=(gad->orientation==SCR_VERTICAL?rect->left:rect->left+knob_pos);
00169   gad->knob_rect.top=(gad->orientation==SCR_VERTICAL?rect->top+knob_pos:rect->top);
00170   gad->knob_rect.width=(gad->orientation==SCR_VERTICAL?rect->width:knob_size);
00171   gad->knob_rect.height=(gad->orientation==SCR_VERTICAL?knob_size:rect->height);
00172   api->gadget_Call(GADGET_RENDER_CUSTOM,TAG_GADGET_OBJECT,this,TAG_GADGET_RECT,&gad->knob_rect,TAG_GADGET_CUSTOM,(api->gadget_Call(GADGET_GET_STATE,TAG_GADGET_OBJECT,this,TAG_DONE)==GADST_NORMAL?SCR_CUS_KNOBUP:SCR_CUS_KNOBDOWN),TAG_GADGET_FLAGS,0,TAG_DONE);
00173 
00174   debug_End();
00175 }
00176 
00177 
00178 static int scroller_input_event_handler(Gadget_t *gad, struct glw_Event *event)
00179 {
00180   int ret=0,gad_size,knob_begin,new_pos,pos;
00181   scroller *this=(scroller *)gad;
00182 
00183   debug_Begin();
00184 
00185   switch(event->event)
00186   {
00187     case GLWEV_MOUSEMOVE:
00188     {
00189       if(api->gadget_Call(GADGET_GET_STATE,TAG_GADGET_OBJECT,gad,TAG_DONE)!=GADST_NORMAL)
00190       {
00191         knob_begin=(this->orientation==SCR_VERTICAL?event->mousey:event->mousex)-this->poshandleknob;
00192         knob_begin-=(this->orientation==SCR_VERTICAL?this->gad_top:this->gad_left);
00193         gad_size=(this->orientation==SCR_VERTICAL?(gad->rect.height):(gad->rect.width));
00194         new_pos=(knob_begin*this->total)/gad_size;
00195         if(new_pos<0) new_pos=0;
00196         else if(new_pos>(this->total-this->visible)) new_pos=(this->total-this->visible);
00197         if(new_pos!=this->position) ret=api->gadget_Call(GADGET_CALLBACK,TAG_GADGET_OBJECT,gad,TAG_GADGET_EVENT,CBK_GADGET_MOVE,TAG_GADGET_EVENT_DATA,new_pos,TAG_DONE);
00198         this->position=new_pos;
00199         api->gadget_Call(GADGET_REFRESH,TAG_GADGET_OBJECT,gad,TAG_DONE);
00200       }
00201       break;
00202     }
00203     case GLWEV_MOUSEBUTTONS:
00204     {
00205       switch(event->data)
00206       {
00207         case GLWEVD_LEFTDOWN:
00208         {
00209           if(api->gui_Call(GUI_ISINSIDE,TAG_GUI_RECT,&this->knob_rect,TAG_GUI_X,event->mousex,TAG_GUI_Y,event->mousey,TAG_DONE))
00210           {
00211             this->poshandleknob=(this->orientation==SCR_VERTICAL?event->mousey-this->knob_rect.top:event->mousex-this->knob_rect.left)-4;
00212             api->gadget_Call(GADGET_SET_STATE,TAG_GADGET_OBJECT,gad,TAG_GADGET_STATE,GADST_PRESSED,TAG_GADGET_VISUAL,1,TAG_DONE);
00213             ret=api->gadget_Call(GADGET_CALLBACK,TAG_GADGET_OBJECT,gad,TAG_GADGET_EVENT,CBK_GADGET_DOWN,TAG_GADGET_EVENT_DATA,0L,TAG_DONE);
00214             api->window_Call(WINDOW_SETACTIVE,TAG_WIN_OBJECT,gad->window,TAG_WIN_GADGET,gad,TAG_DONE);
00215           }
00216           else
00217           {
00218             pos=(this->orientation==SCR_VERTICAL?event->mousey-this->knob_rect.top:event->mousex-this->knob_rect.left);
00219             new_pos=this->position+(pos>0?this->visible:-this->visible);
00220             if(new_pos<0) new_pos=0;
00221             else if(new_pos>(this->total-this->visible)) new_pos=(this->total-this->visible);
00222             if(new_pos!=this->position) ret=api->gadget_Call(GADGET_CALLBACK,TAG_GADGET_OBJECT,gad,TAG_GADGET_EVENT,CBK_GADGET_MOVE,TAG_GADGET_EVENT_DATA,new_pos,TAG_DONE);
00223             this->position=new_pos;
00224             api->gadget_Call(GADGET_REFRESH,TAG_GADGET_OBJECT,gad,TAG_DONE);
00225           }
00226           break;
00227         }
00228         case GLWEVD_LEFTUP:
00229         {
00230           if(api->gadget_Call(GADGET_GET_STATE,TAG_GADGET_OBJECT,gad,TAG_DONE)==GADST_PRESSED)
00231           {
00232             api->gadget_Call(GADGET_SET_STATE,TAG_GADGET_OBJECT,gad,TAG_GADGET_STATE,GADST_NORMAL,TAG_GADGET_VISUAL,1,TAG_DONE);
00233             api->window_Call(WINDOW_SETACTIVE,TAG_WIN_OBJECT,gad->window,TAG_WIN_GADGET,NULL,TAG_DONE);
00234             ret=api->gadget_Call(GADGET_CALLBACK,TAG_GADGET_OBJECT,gad,TAG_GADGET_EVENT,CBK_GADGET_UP,TAG_GADGET_EVENT_DATA,0L,TAG_DONE);
00235           }
00236           break;
00237         }
00238       }
00239       break;
00240     }
00241   }
00242 
00243   debug_End();
00244 
00245   return(ret);
00246 }
00247 
00248 
00249 int scroller_init_gadget(Gadget_t *this, tag *taglist)
00250 {
00251   scroller *gad=(scroller *)this;
00252 
00253   debug_Begin();
00254 
00255   gad->total=(int)tag_GetTagData(taglist,TAG_SCR_TOTAL,1L);
00256   gad->visible=(int)tag_GetTagData(taglist,TAG_SCR_VISIBLE,1L);
00257   gad->position=(int)tag_GetTagData(taglist,TAG_SCR_POSITION,0L);
00258   gad->othersize=(int)tag_GetTagData(taglist,TAG_SCR_OTHERSIZE,0L);
00259   gad->orientation=(int)tag_GetTagData(taglist,TAG_SCR_ORIENTATION,0L);
00260   if(gad->total<1) gad->total=1;
00261   if(gad->position<0) gad->position=0;
00262   if(gad->visible<1) gad->visible=1;
00263   if(gad->visible>gad->total) gad->visible=gad->total;
00264   if(gad->position>(gad->total-gad->visible)) gad->position=gad->total-gad->visible;
00265 
00266   debug_End();
00267 
00268   return(0);
00269 }
00270 
00271 
00272 static int scroller_gadget_event_handler(Gadget_t *this, int event, tag *taglist)
00273 {
00274   int ret=-1;
00275 
00276   debug_Begin();
00277 
00278   if(this!=NULL&&event>=0)
00279   {
00280     switch(event)
00281     {
00282       case GADEV_INIT_GADGET:
00283       {
00284         ret=scroller_init_gadget(this,taglist);
00285         break;
00286       }
00287       case GADEV_DELETE_GADGET:
00288       {
00289         ret=0;
00290         break;
00291       }
00292       case GADEV_GET_EXTENT:
00293       {
00294         Extent_t *min,*max,n,x;
00295         min=(Extent_t *)tag_GetTagData(taglist,TAG_GAD_EXTMIN,(u32)&n);
00296         max=(Extent_t *)tag_GetTagData(taglist,TAG_GAD_EXTMAX,(u32)&x);
00297         scroller_get_extent(this,min,max);
00298         ret=0;
00299         break;
00300       }
00301       case GADEV_LAYOUT:
00302       case GADEV_DAMAGE:
00303       {
00304         Rect_t *rect,r;
00305         rect=(Rect_t *)tag_GetTagData(taglist,TAG_GAD_RECT,(u32)&r);
00306         scroller_layout(this,rect);
00307         ret=0;
00308         break;
00309       }
00310       case GADEV_SAVE:
00311       {
00312         u8 **mem;
00313         int *size;
00314         mem=(u8 **)tag_GetTagData(taglist,TAG_GADGET_MEM,0L);
00315         size=(int *)tag_GetTagData(taglist,TAG_GADGET_SIZE,0L);
00316         break;
00317       }
00318       case GADEV_RESTORE:
00319       {
00320         u8 *mem;
00321         int size;
00322         mem=(u8 *)tag_GetTagData(taglist,TAG_GADGET_MEM,0L);
00323         size=(int)tag_GetTagData(taglist,TAG_GADGET_SIZE,0L);
00324         break;
00325       }
00326     }
00327   }
00328 
00329   debug_End();
00330 
00331   return(ret);
00332 }
00333 
00334 
00335 static void init_scroller_class(u32 module)
00336 {
00337   api->gadget_Call(GADGET_REGISTER_CLASS,
00338                             TAG_GADGET_CLASS_ID,CLASS_SCROLLER_ID,
00339                             TAG_GADGET_NAME,CLASS_SCROLLER_NAME,
00340                 TAG_GADGET_BINDING,binding,
00341                 TAG_GADGET_COLOR_NAMES,NULL,
00342                 TAG_GADGET_CUSTOM_NAMES,custom_names,
00343                 TAG_GADGET_STATE_MASK,GADSTF_NORMAL|GADSTF_PRESSED,
00344                 TAG_GADGET_MODULE,module,
00345                 TAG_GADGET_GADGET_SIZE,sizeof(scroller),
00346                 TAG_GADGET_METHODS,methods,
00347                 TAG_GADGET_INPUT_EVENT_HANDLER,scroller_input_event_handler,
00348                 TAG_GADGET_EVENT_HANDLER,NULL,
00349                 TAG_GADGET_GADGET_EVENT_HANDLER,scroller_gadget_event_handler,
00350                 TAG_DONE);
00351 }
00352 
00353 
00354 EXPORT int module_Init(u32 module, bases_Modules_t *bases)
00355 {
00356     api=bases;
00357     init_scroller_class(module);  return(0);
00358 }

Generated on Tue Jan 7 12:11:20 2003 for THEGUI by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002