scrollbar.c

Go to the documentation of this file.
00001 
00002 /*  $Id: scrollbar.c 355 2005-01-11 22:48:55Z andreradke $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #include "frontierconfig.h"
00032 #include "memory.h"
00033 #include "shell.rsrc.h"
00034 #include "scrollbar.h"
00035 #include "quickdraw.h"
00036 #include "threads.h"
00037 
00038 
00039 #ifdef MACVERSION
00040 #define scrollbarpopclip() popclip()
00041 #endif
00042 #ifdef WIN95VERSION
00043 #define scrollbarpopclip()
00044 #endif
00045 
00046 static boolean flmacproportionalthumbs = false; /*7.0b18 PBS*/
00047 
00048 static boolean scrollbarpushclip (hdlscrollbar hscrollbar) {
00049 #ifdef MACVERSION   
00050     /*
00051     11/19/90 DW: patch things up for the table displayer, and perhaps others in
00052     the future.  if the scrollbar is of trivial height, we disable the drawing
00053     that's about to happen.  we were getting one-pixel high scrollbars being
00054     drawn.
00055     
00056     2/28/91 dmb: now that pushclip does true clip nesting, we use superpushclip 
00057     to ensure that the scrollbar gets drawn
00058     */
00059     
00060     //Code change by Timothy Paustian Friday, May 5, 2000 10:10:47 PM
00061     //Changed to Opaque call for Carbon
00062     Rect r;
00063     #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
00064     GetControlBounds(hscrollbar, &r);
00065     #else
00066     r = (**hscrollbar).contrlRect;
00067     #endif
00068     
00069     if ((r.bottom - r.top) == 1)
00070         r.bottom = r.top;
00071         
00072     return (superpushclip (r));
00073 #endif
00074 
00075 #ifdef WIN95VERSION
00076     return (true);
00077 #endif
00078     } /*scrollbarpushclip*/
00079     
00080     
00081 void validscrollbar (hdlscrollbar hscrollbar) {
00082 #ifdef MACVERSION
00083     register hdlscrollbar h = hscrollbar;
00084     //Code change by Timothy Paustian Friday, May 5, 2000 10:13:48 PM
00085     //Changed to Opaque call for Carbon
00086     
00087     #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
00088     CGrafPtr    contrlOwner = (CGrafPtr) GetControlOwner(h);
00089     Rect        contrlRect;
00090     
00091     //assert (h == nil || GetQDGlobalsThePort() == contrlOwner);
00092     if ((h != nil) && (GetQDGlobalsThePort() == contrlOwner)) 
00093     {
00094         GetControlBounds(h, &contrlRect);
00095         validrect (contrlRect);
00096     }
00097     #else
00098     assert (h == nil || qd.thePort == (**h).contrlOwner);
00099     if (h != nil) 
00100         validrect ((**h).contrlRect);
00101     #endif
00102         
00103     
00104 #endif
00105     } /*validscrollbar*/
00106     
00107     
00108 boolean pointinscrollbar (Point pt, hdlscrollbar hscrollbar) {
00109 #ifdef MACVERSION
00110     register hdlscrollbar h = hscrollbar;
00111     Rect contrlRect;
00112     
00113     if (h == nil) /*defensive driving*/
00114         return (false);
00115     //Code change by Timothy Paustian Friday, May 5, 2000 10:18:27 PM
00116     //Changed to Opaque call for Carbon
00117     //This routine is never called in the PPC OT version.
00118     #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
00119     GetControlBounds(h, &contrlRect);   
00120     #else
00121     contrlRect = (**h).contrlRect;
00122     #endif
00123     return (pointinrect (pt, contrlRect));
00124     
00125 #endif
00126 #ifdef WIN95VERSION
00127     return (false);
00128 #endif
00129     } /*pointinscrollbar*/
00130     
00131     
00132 void enablescrollbar (hdlscrollbar hscrollbar) {
00133     
00134     if (hscrollbar == nil) /*defensive driving*/
00135         return;
00136 
00137 #ifdef MACVERSION
00138     scrollbarpushclip (hscrollbar);
00139         
00140     HiliteControl (hscrollbar, 0);
00141     
00142     validscrollbar (hscrollbar);
00143     
00144     scrollbarpopclip ();
00145 #endif
00146 #ifdef WIN95VERSION
00147     EnableScrollBar ((*hscrollbar)->hWnd, (*hscrollbar)->item, ESB_ENABLE_BOTH);    
00148 #endif
00149     } /*enablescrollbar*/
00150     
00151     
00152 void disablescrollbar (hdlscrollbar hscrollbar) {
00153     
00154     if (hscrollbar == nil) /*defensive driving*/
00155         return;
00156         
00157 #ifdef MACVERSION
00158 
00159     #if TARGET_API_MAC_CARBON == 1
00160         
00161         DeactivateControl (hscrollbar);
00162 
00163     #else   
00164         scrollbarpushclip (hscrollbar);
00165             
00166         HiliteControl (hscrollbar, -1);
00167         
00168         validscrollbar (hscrollbar);
00169         
00170         scrollbarpopclip ();
00171         
00172     #endif
00173     
00174 #endif
00175 #ifdef WIN95VERSION
00176     EnableScrollBar ((*hscrollbar)->hWnd, (*hscrollbar)->item, ESB_DISABLE_BOTH);   
00177 #endif
00178     } /*disablescrollbar*/
00179     
00180     
00181 void getscrollbarinfo (hdlscrollbar hscrollbar, tyscrollinfo *scrollinfo) {
00182     
00183     register hdlscrollbar h = hscrollbar;
00184 #ifdef WIN95VERSION
00185     SCROLLINFO si;
00186 #endif
00187     
00188     if (h == nil) { /*defensive driving*/
00189         
00190         clearbytes (scrollinfo, sizeof (tyscrollinfo));
00191         
00192         return;
00193         }
00194 #ifdef MACVERSION   
00195     (*scrollinfo).min = GetControlMinimum (h);
00196     
00197     (*scrollinfo).max = GetControlMaximum (h);
00198     
00199     (*scrollinfo).cur = GetControlValue (h);
00200 
00201     (*scrollinfo).pag = 0;
00202 #endif
00203 #ifdef WIN95VERSION
00204     si.cbSize = sizeof(SCROLLINFO);
00205     si.fMask = SIF_ALL;
00206 
00207     if (GetScrollInfo ((*hscrollbar)->hWnd, (*hscrollbar)->item, &si)) {
00208         (*scrollinfo).cur = si.nPos;
00209         (*scrollinfo).min = si.nMin;
00210         (*scrollinfo).max = si.nMax - si.nPage + 1;
00211         (*scrollinfo).pag = si.nPage;
00212         }
00213     else  {
00214         clearbytes (scrollinfo, sizeof (tyscrollinfo));
00215         }
00216 #endif
00217     } /*getscrollbarinfo*/
00218     
00219     
00220 long getscrollbarcurrent (hdlscrollbar hscrollbar) {
00221     
00222     tyscrollinfo scrollinfo;
00223     
00224     getscrollbarinfo (hscrollbar, &scrollinfo);
00225     
00226     return (scrollinfo.cur);
00227     } /*getscrollbarcurrent*/
00228     
00229     
00230 void showscrollbar (hdlscrollbar hscrollbar) {
00231 
00232     if (hscrollbar == nil) /*defensive driving*/
00233         return;
00234         
00235 #ifdef MACVERSION   
00236     scrollbarpushclip (hscrollbar);
00237         
00238     ShowControl (hscrollbar); /*no effect if scrollbar is already visible, according to IM-1*/
00239     
00240     scrollbarpopclip ();
00241     
00242     /*don't validate the scrollbar rect, ShowControl might not draw it...*/
00243 #endif
00244 #ifdef WIN95VERSION
00245     releasethreadglobals ();
00246 
00247     ShowScrollBar ((*hscrollbar)->hWnd, (*hscrollbar)->item, TRUE); 
00248     
00249     grabthreadglobals ();
00250 #endif
00251     } /*showscrollbar*/
00252     
00253     
00254 void hidescrollbar (hdlscrollbar hscrollbar) {
00255 
00256     if (hscrollbar == nil) /*defensive driving*/
00257         return;
00258         
00259     #ifdef MACVERSION   
00260 
00261         {
00262         Rect contrlRect;
00263         scrollbarpushclip (hscrollbar);
00264             
00265         releasethreadglobals ();
00266 
00267         HideControl (hscrollbar);
00268         
00269         grabthreadglobals ();
00270         
00271         scrollbarpopclip ();
00272         
00273         /*Code change by Timothy Paustian Sunday, May 21, 2000 9:06:31 PM
00274         Changed to Opaque call for Carbon
00275         This routine is never called in the PPC OT version*/
00276 
00277         #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
00278             GetControlBounds(hscrollbar, &contrlRect);  
00279         #else
00280             contrlRect = (**hscrollbar).contrlRect;
00281         #endif
00282         
00283         invalrect (contrlRect);
00284             }
00285 
00286     #endif
00287 
00288     #ifdef WIN95VERSION
00289 
00290         releasethreadglobals ();
00291 
00292         ShowScrollBar ((*hscrollbar)->hWnd, (*hscrollbar)->item, FALSE);    
00293         
00294         grabthreadglobals ();
00295 
00296     #endif
00297     } /*hidescrollbar*/
00298     
00299 
00300 void drawscrollbar (hdlscrollbar hscrollbar) {
00301 
00302     /*
00303     7.0b20 PBS: Now works for Windows too. Fixes display glitch.
00304     */
00305 
00306     register hdlscrollbar h = hscrollbar;
00307     
00308     if (h == nil) /*defensive driving*/
00309         return;
00310 
00311 #ifdef MACVERSION   
00312         
00313     scrollbarpushclip (h);
00314     
00315     Draw1Control (h);
00316     
00317     scrollbarpopclip ();
00318     
00319     validscrollbar (h);
00320 #endif
00321 
00322 #ifdef WIN95VERSION
00323 
00324     releasethreadglobals (); /*7.0b20 PBS: release and grab thread globals*/
00325 
00326     SendMessage ((**hscrollbar).hWnd, WM_NCPAINT, 1, 0);
00327 
00328     grabthreadglobals ();
00329 
00330 #endif
00331     } /*drawscrollbar*/
00332     
00333     
00334 void displayscrollbar (hdlscrollbar hscrollbar) {
00335     /*
00336     the caller is saying that we should enable it if there is enough 
00337     material to enable scrolling.
00338 
00339     7.0b17 PBS: Scroll if min < max, not if min <= max.
00340     */
00341     
00342     register hdlscrollbar h = hscrollbar;
00343     tyscrollinfo scrollinfo;
00344     
00345     if (h == nil) /*defensive driving*/
00346         return;
00347         
00348     getscrollbarinfo (h, &scrollinfo);
00349     
00350     //if (scrollinfo.min <= scrollinfo.max) /*there's something to scroll to*/
00351 
00352     /*7.0b17 PBS: scroll if min < max, not if min <= max.*/
00353 
00354     if (scrollinfo.min < scrollinfo.max) /*there's something to scroll to*/
00355         enablescrollbar (h);
00356     else
00357         disablescrollbar (h);
00358         
00359     drawscrollbar (h);
00360     } /*displayscrollbar*/
00361     
00362     
00363 void setscrollbarinfo (hdlscrollbar hscrollbar, const tyscrollinfo *scrollinfo) {
00364     /*
00365     set the bounds of the scrollbar, and its current value.
00366     
00367     if the current info agrees with the parameters we do nothing, 
00368     avoiding unpleasant flicker.
00369     
00370     disables drawing while setting the values, and draws it when 
00371     all three values have been set.  avoids inconsistent displays.
00372     
00373     7.0b18 PBS: On Macs, if the control manager supports proportional thumbs,
00374     use them.
00375     */
00376     
00377     register hdlscrollbar h = hscrollbar;
00378     tyscrollinfo curinfo;
00379     
00380 #ifdef WIN95VERSION
00381     SCROLLINFO si;
00382 #endif
00383     
00384     if (h == nil) /*defensive driving*/
00385         return;
00386     
00387     getscrollbarinfo (h, &curinfo);
00388     
00389     if (((*scrollinfo).min == curinfo.min) && ((*scrollinfo).max == curinfo.max) && ((*scrollinfo).cur == curinfo.cur))
00390         return; /*nothing to do*/
00391     
00392 #ifdef MACVERSION
00393     pushemptyclip (); /*disable drawing*/
00394     
00395     SetControlMaximum (h, min (infinity, (*scrollinfo).max));
00396     
00397     SetControlMinimum (h, (*scrollinfo).min);
00398     
00399     SetControlValue (h, min (infinity, (*scrollinfo).cur));
00400     
00401 //#if __powerc || __GNUC__
00402 
00403     if (flmacproportionalthumbs) /*7.0b18 PBS: proportional thumbs on Macs*/
00404     
00405         SetControlViewSize (h, (*scrollinfo).pag);
00406 
00407 //#endif
00408     
00409     scrollbarpopclip ();
00410     
00411     displayscrollbar (h);
00412 #endif
00413 
00414 #ifdef WIN95VERSION
00415     si.cbSize = sizeof(SCROLLINFO);
00416     si.fMask = SIF_RANGE | SIF_POS | SIF_DISABLENOSCROLL | SIF_PAGE;
00417     si.nPos = (*scrollinfo).cur;
00418     si.nMin = (*scrollinfo).min;
00419     si.nMax = (*scrollinfo).max + (*scrollinfo).pag - 1;
00420     si.nPage = (*scrollinfo).pag;
00421 
00422     releasethreadglobals ();
00423 
00424     SetScrollInfo ((*hscrollbar)->hWnd, (*hscrollbar)->item, &si, TRUE);
00425     
00426     grabthreadglobals ();
00427 #endif
00428     } /*setscrollbarinfo*/
00429     
00430 
00431 void setscrollbarcurrent (hdlscrollbar hscrollbar, long current) {
00432 #ifdef MACVERSION
00433     register hdlscrollbar h = hscrollbar;
00434     
00435     if (h == nil) /*defensive driving*/
00436         return;
00437     
00438     scrollbarpushclip (h);
00439     
00440     SetControlValue (h, min (infinity, current));
00441     
00442     scrollbarpopclip ();
00443 #endif
00444 #ifdef WIN95VERSION
00445     SCROLLINFO si;
00446 
00447     si.cbSize = sizeof(SCROLLINFO);
00448     si.fMask = SIF_POS;
00449     si.nPos = current;
00450 
00451     releasethreadglobals ();
00452 
00453     SetScrollInfo ((*hscrollbar)->hWnd, (*hscrollbar)->item, &si, TRUE);
00454     
00455     grabthreadglobals ();
00456 #endif
00457     } /*setscrollbarcurrent*/
00458 
00459 
00460 short getscrollbarwidth (void) {
00461 #ifdef MACVERSION   
00462     if (config.flwindoidscrollbars)
00463         return (13);
00464     else
00465         return (16); /*standard Macintosh scrollbars*/
00466 #endif
00467 #ifdef WIN95VERSION
00468     return (0);  /*handled by system */
00469 #endif
00470     } /*getscrollbarwidth*/
00471 
00472 
00473 
00474 boolean newscrollbar (WindowPtr w, boolean flvert, hdlscrollbar *hscrollbar) {
00475 #ifdef MACVERSION
00476     
00477     /*
00478     create a new scroll bar linked into the control list of the indicated
00479     window.  
00480     
00481     we need to know if it is a vertical or horizontal scrollbar so we can
00482     choose the proper resource template.  we use a CDEF that has different
00483     specs for horiz and vertical scrollbars.
00484     */
00485     
00486     register short resnum;
00487     
00488     if (config.flwindoidscrollbars) {
00489     
00490         if (flvert)
00491             resnum = idvertbaroid;
00492         else
00493             resnum = idhorizbaroid;
00494         }
00495     else {
00496         if (flvert)
00497             resnum = idvertbar;
00498         else
00499             resnum = idhorizbar;
00500         }
00501     
00502     *hscrollbar = GetNewControl (resnum, w);
00503 #endif
00504 #ifdef WIN95VERSION
00505     hdlscrollbar h;
00506     h = (hdlscrollbar) NewHandle (sizeof(scrollbarrecord));
00507     if (h != NULL) {
00508         (*h)->hWnd = w;
00509         (*h)->item = flvert?SB_VERT:SB_HORZ;
00510         }
00511     *hscrollbar = h;
00512 #endif
00513     return ((*hscrollbar) != nil);
00514     } /*newscrollbar*/
00515     
00516     
00517 void disposescrollbar (hdlscrollbar hscrollbar) {
00518 #ifdef MACVERSION   
00519     register hdlscrollbar h = hscrollbar;
00520     
00521     if (h != nil)
00522         DisposeControl (h);
00523 #endif
00524 #ifdef WIN95VERSION
00525     DisposeHandle ((Handle) hscrollbar);
00526 #endif
00527     } /*disposescrollbar*/
00528     
00529 
00530 #ifdef MACVERSION   
00531 void getscrollbarrect (hdlscrollbar hscrollbar, Rect *r) {
00532 
00533     register hdlscrollbar h = hscrollbar;
00534     
00535     if (h != nil) 
00536     {
00537         //Code change by Timothy Paustian Sunday, May 21, 2000 9:07:18 PM
00538         //Changed to Opaque call for Carbon
00539         //This routine is never called in the PPC OT version.
00540         Rect contrlRect;
00541         #if ACCESSOR_CALLS_ARE_FUNCTIONS == 1
00542         GetControlBounds(h, &contrlRect);   
00543         #else
00544         contrlRect = (**h).contrlRect;
00545         #endif
00546         *r = contrlRect;
00547     }
00548     else
00549         zerorect (r);
00550     } /*getscrollbarrect*/
00551 #endif  
00552     
00553     
00554 void setscrollbarrect (hdlscrollbar hscrollbar, Rect r) {
00555 
00556 #ifdef MACVERSION   
00557     register hdlscrollbar h = hscrollbar;
00558     
00559     if (h != nil) {
00560         
00561         HideControl (h);
00562         
00563         SizeControl (h, r.right - r.left, r.bottom - r.top);
00564         
00565         MoveControl (h, r.left, r.top);
00566         }
00567 #endif
00568     } /*setscrollbarrect*/
00569     
00570 void scrollbarflushright (Rect r, hdlscrollbar hscrollbar) {
00571 #ifdef MACVERSION   
00572     register hdlscrollbar h = hscrollbar;
00573     register short width;
00574     
00575     if (h == nil) /*defensive driving*/
00576         return;
00577         
00578     width = getscrollbarwidth ();
00579     
00580     HideControl (h);
00581     
00582     SizeControl (h, width, r.bottom - r.top + 2);
00583     
00584     MoveControl (h, r.right - width + 1, r.top - 1);
00585 #endif
00586     } /*scrollbarflushright*/
00587     
00588     
00589 void scrollbarflushbottom (Rect r, hdlscrollbar hscrollbar) {
00590 #ifdef MACVERSION   
00591     register hdlscrollbar h = hscrollbar;
00592     register short width;
00593     
00594     if (h == nil) /*defensive driving*/
00595         return;
00596         
00597     width = getscrollbarwidth ();
00598         
00599     HideControl (h);
00600     
00601     SizeControl (hscrollbar, r.right - r.left, width);
00602         
00603     MoveControl (hscrollbar, r.left, r.bottom - width + 1);
00604 #endif
00605     } /*scrollbarflushbottom*/
00606     
00607 
00608 #ifdef MACVERSION   
00609 boolean findscrollbar (Point pt, WindowPtr w, hdlscrollbar *hscrollbar, short *scrollbarpart) {
00610     
00611     *scrollbarpart = FindControl (pt, w, hscrollbar);
00612     
00613     return (*hscrollbar != nil);
00614     } /*findscrollbar*/
00615     
00616 
00617 long gpreviousscrollvalue = 0;
00618 
00619 boolean scrollbarhit (hdlscrollbar hscrollbar, short part, boolean *flup, boolean *flpage) {
00620     
00621     /*
00622     can be called by a routine that tracks a mouse hit in a scroll bar.
00623     
00624     return true if it represents a valid scroll action, according to the info
00625     stored in the scrollbar handle.
00626     
00627     return false if the indicated action would move beyond the min or max for
00628     the scrollbar.
00629     
00630     set flup and flpage according to the indicated scrollbar part.
00631     */
00632     
00633     register hdlscrollbar h = hscrollbar;
00634     tyscrollinfo scrollinfo;
00635     
00636     if (h == nil) /*defensive driving*/
00637         return (false);
00638     
00639     getscrollbarinfo (h, &scrollinfo);
00640     
00641     switch (part) {
00642     
00643         case kControlUpButtonPart:
00644             *flup = false; /*scroll text down*/
00645             
00646             *flpage = false;
00647             
00648             return (scrollinfo.cur > scrollinfo.min);
00649             
00650         case kControlDownButtonPart:
00651             *flup = true; /*scroll text up*/
00652             
00653             *flpage = false;
00654             
00655             return (scrollinfo.cur < scrollinfo.max);
00656             
00657         case kControlPageUpPart:
00658             *flup = false; /*scroll text down*/
00659             
00660             *flpage = true; 
00661             
00662             return (scrollinfo.cur > scrollinfo.min);
00663             
00664         case kControlPageDownPart:
00665             *flup = true; /*scroll text up*/
00666             
00667             *flpage = true;
00668             
00669             return (scrollinfo.cur < scrollinfo.max);
00670         case kControlIndicatorPart:
00671             *flpage = false;
00672             if (scrollinfo.cur  == gpreviousscrollvalue)
00673                 return (false);
00674             if (scrollinfo.cur > gpreviousscrollvalue)
00675                 *flup = true;
00676             else
00677                 *flup = false;
00678             gpreviousscrollvalue = scrollinfo.cur;
00679             return (true);
00680         } /*switch*/
00681         
00682     return (false); /*fell through the switch statement*/
00683     } /*scrollbarhit*/
00684     
00685 #endif
00686 
00687 boolean initscrollbars (void) {
00688     
00689     /*
00690     7.0b18 PBS: check for 8.5 control manager on Macs -- proportional thumbs.
00691     */
00692     
00693     #if __powerc
00694 
00695         OSErr err;
00696         long response;
00697     
00698         err = Gestalt (gestaltControlMgrAttr, &response);
00699     
00700         if ((err == noErr) && (response & gestaltControlMgrPresent))
00701             flmacproportionalthumbs = true;
00702 
00703     #endif
00704     
00705     return (true);
00706     } /*initscrollbars*/

Generated on Wed May 31 18:20:00 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6