home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / gui / macgui.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  21.4 KB  |  850 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. // StPrepareForDialog
  20.  
  21.     // macfe
  22. #include "macgui.h"
  23. #include "uprefd.h"
  24. #include "resgui.h"
  25. #include "mimages.h"
  26. #include "uerrmgr.h"
  27. #include "macutil.h"
  28.     // Netscape
  29. #include "client.h"
  30. #include "ntypes.h"
  31. #include "shist.h"
  32. #include "glhist.h"
  33. #include "lo_ele.h"
  34. #include "mkutils.h"
  35. #include "prefapi.h"
  36.  
  37.     // PowerPlant
  38. #include <UEnvironment.h>
  39.     // system
  40.  
  41. #include <LowMem.h>
  42.  
  43. #ifdef PROFILE
  44. #pragma profile on
  45. #endif
  46.  
  47. void DrawArc( const RGBColor& initColor, const Rect& box, Boolean inset );
  48.  
  49. // ÑÑ StPrepareForDialog
  50.  
  51. StPrepareForDialog::StPrepareForDialog()
  52. {
  53.     ErrorManager::PrepareToInteract();
  54.     UDesktop::Deactivate();
  55. }
  56.  
  57. StPrepareForDialog::~StPrepareForDialog()
  58. {
  59.     UDesktop::Activate();
  60. }
  61.  
  62.  
  63. // class StTempClipRgn
  64. RgnHandle StTempClipRgn::sOldClip = NULL;    
  65. RgnHandle StTempClipRgn::sMergedNewClip = NULL;
  66.  
  67. StTempClipRgn::StTempClipRgn (RgnHandle newClip)
  68. {
  69.     if (sOldClip == NULL) sOldClip = ::NewRgn();
  70.     if (sMergedNewClip == NULL) sMergedNewClip = ::NewRgn();
  71.     
  72.     ::GetClip(sOldClip);
  73.     ::SectRgn(sOldClip, newClip, sMergedNewClip);
  74.     ::SetClip(sMergedNewClip);
  75. }
  76.  
  77. StTempClipRgn::~StTempClipRgn()
  78. {
  79.     ::SetClip(sOldClip);
  80. }
  81.  
  82.  
  83. // class HyperStyle
  84. extern Boolean gIsPrinting;
  85.  
  86. /*
  87. HyperStyle::HyperStyle( HyperStyle* style )
  88. {
  89.     memcpy( this, style, sizeof( HyperStyle ) );    // Just copy the fields
  90. }
  91. */
  92.  
  93. HyperStyle::HyperStyle( MWContext *context, const CCharSet* charSet, LO_TextAttr* attr, Boolean onlyMeasuring,
  94.     LO_TextStruct* element )
  95. {
  96.     fElement = element;
  97.     
  98.     fFontReference = CFontReference::GetFontReference(charSet, attr, context, sUnderlineLinks);
  99.     
  100.     strike = ( attr->attrmask & LO_ATTR_STRIKEOUT );
  101.     fInlineInput = ( attr->attrmask & ( LO_ATTR_INLINEINPUT | LO_ATTR_INLINEINPUTTHICK | LO_ATTR_INLINEINPUTDOTTED ) );
  102.     fOnlyMeasuring = onlyMeasuring;
  103.  
  104.     if ( !fOnlyMeasuring )
  105.     {
  106.         rgbFgColor = UGraphics::MakeRGBColor( attr->fg.red, attr->fg.green, attr->fg.blue );
  107.         rgbBkColor = UGraphics::MakeRGBColor( attr->bg.red, attr->bg.green, attr->bg.blue );
  108.     }
  109.     
  110.     memcpy( &fAttr, attr, sizeof( LO_TextAttr ) );    // Just copy the fields
  111.  
  112. }
  113.  
  114. // Ñ calculate a rectangular area of the page based on "where" and the
  115. //    length of "text", using this style's font information; note that if
  116. //    we have a reference element, we use the line height given by layout,
  117. //    otherwise we figure out a line height using the text metrics
  118. Rect HyperStyle::InvalBackground( Point where, char* text, int start, int end, Boolean blinks )
  119. {
  120.     int                    usedText;
  121.     int                    unusedText;
  122.     Rect                hiliteArea;
  123.  
  124.     int                    length;
  125.     
  126.     Apply();
  127.     GetFontInfo();
  128.     
  129.     length = end - start + 1;
  130.     
  131.     usedText = fFontReference->TextWidth(text, start, length);
  132.     unusedText = start ? fFontReference->TextWidth(text, 0, start) : 0;
  133.     if ( !fElement || !fElement->line_height )
  134.     {
  135.         hiliteArea.top = where.v;
  136.         hiliteArea.left = where.h + unusedText;
  137.         hiliteArea.bottom = hiliteArea.top + fFontInfo.ascent + fFontInfo.descent;
  138.         hiliteArea.right = hiliteArea.left + usedText;
  139.     }
  140.     else
  141.     {
  142.         hiliteArea.top = where.v - fElement->y_offset;
  143.         hiliteArea.left = where.h + unusedText;
  144.         hiliteArea.bottom = hiliteArea.top + fElement->line_height;
  145.         hiliteArea.right = hiliteArea.left + usedText;
  146.  
  147.         if ( blinks ||
  148.             ( fAttr.fontmask & LO_FONT_ITALIC ) )
  149.         {
  150.             hiliteArea.right += ( fFontInfo.widMax / 2 );
  151.             hiliteArea.left -= MIN( 2, ( fFontInfo.widMax / 8 ) );
  152.         }
  153.     }
  154.     
  155.     return hiliteArea;
  156. }
  157.  
  158.  
  159. void HyperStyle::DrawText(    Point where,
  160.                             char* text,
  161.                             int start,
  162.                             int end )
  163. {
  164.     Boolean        selected;
  165.     Boolean        swapped = FALSE;
  166.     int            length = end - start + 1;
  167.     
  168.     Assert_( fElement );
  169.     
  170.     selected = ( ( fElement->ele_attrmask & LO_ELE_SELECTED ) != 0 &&
  171.                     fElement->sel_start <= start &&
  172.                     end <= fElement->sel_end );
  173.  
  174.     Boolean        paint_background = selected || !fAttr.no_background;
  175.  
  176.     fFontReference->SetMode( paint_background ? srcCopy : srcOr );
  177.     
  178.     // Ñ stupid layout reverses bk / fg colors when it tries to draw selected
  179.     //         put the actual fg color back in fg, and put the user's hilite color
  180.     //        into bk
  181.     // Ñ selection takes precedence over blink
  182.     if ( selected )
  183.     {
  184.         // Ñ put the colors back and check to make sure that highlighting
  185.         //        will actually show up
  186.         rgbFgColor = rgbBkColor;
  187.         LMGetHiliteRGB( &rgbBkColor );
  188.         if ( UGraphics::EqualColor( rgbFgColor, rgbBkColor ) )
  189.         {
  190.             swapped = TRUE;
  191.             rgbFgColor.red = ~rgbBkColor.red;
  192.             rgbFgColor.green = ~rgbBkColor.green;
  193.             rgbFgColor.blue = ~rgbBkColor.blue;
  194.         }
  195.     }
  196.  
  197.     Apply();
  198.     GetFontInfo();
  199.  
  200.     long unusedText = start ? fFontReference->TextWidth(text, 0, start) : 0;
  201.     int x = where.h + unusedText;
  202.     int y = where.v + fFontInfo.ascent;
  203.  
  204.     fFontReference->DrawText(x, y, text, start, end );
  205.     
  206.     if ( paint_background )
  207.     {            
  208.         short    fontHeight = fFontInfo.ascent + fFontInfo.descent + fFontInfo.leading;
  209.         
  210.         if ( !fElement )
  211.             return;
  212.         
  213.         // Ñ╩if the font height is less than the element's line height,
  214.         //        there will be rectangular areas above and below the text
  215.         //        that are not drawn with the selection highlighting
  216.         //        we draw them here
  217.         if ( fontHeight < fElement->line_height )
  218.         {
  219.             long    usedText = fFontReference->TextWidth(text, start, length);
  220.             Rect    hiliteArea;
  221.         
  222.             hiliteArea.top = where.v - fElement->y_offset;
  223.             hiliteArea.left = where.h + unusedText;
  224.             hiliteArea.right = hiliteArea.left + usedText;
  225.             hiliteArea.bottom = where.v;
  226.             
  227.             ::EraseRect( &hiliteArea );
  228.  
  229.             hiliteArea.bottom = hiliteArea.top + fElement->line_height;
  230.             hiliteArea.top += ( fFontInfo.ascent + fFontInfo.descent + fElement->y_offset );
  231.             ::EraseRect( &hiliteArea );
  232.         }
  233.     }        
  234.  
  235. /*
  236.     // Ñ╩special case for selected italics
  237. // FIX ME! Don't forget about this when we redo printing
  238. //    if ( !gIsPrinting && ( (fStyle & italic) != 0 ) )
  239.     if ( (fAttr.fontmask & LO_FONT_ITALIC) != 0 )
  240.     {
  241.         if ( swapped )
  242.             ::RGBForeColor( &rgbBkColor );
  243.         
  244.         // **** should this use fFontReference->SetMode?    
  245.         ::TextMode( srcOr );
  246.         fFontReference->DrawText(where.h, where.v + fFontInfo.ascent, text, 0, fElement->text_len );
  247.     }
  248. */
  249.  
  250.     Boolean isMisspelled = (fAttr.attrmask & LO_ATTR_SPELL) != 0;
  251.     if ( strike || isMisspelled )
  252.     {
  253.         // I have consciously decided that if a word is misspelled and
  254.         // striked that it is preferable to not strike and just mark
  255.         // for misspelling; this may not be the correct decision. [brade]
  256.         long    usedText = fFontReference->TextWidth(text, start, length);
  257.         short    vstrike;
  258.         
  259.         if ( isMisspelled )
  260.         {
  261.             // for misspelled words we want a dashed underline
  262.             PenPat( &qd.gray );
  263.             vstrike = -( fFontInfo.descent - 1 );
  264.         }
  265.         else
  266.             vstrike = ( fFontInfo.ascent / 2 ) - 1;
  267.  
  268.         ::Move( -usedText, -vstrike );
  269.         ::Line( usedText, 0 );
  270.  
  271.         // restore things...
  272.         ::Move( 0, vstrike );
  273.         
  274.         if ( isMisspelled )
  275.             PenPat( &qd.black );
  276.     }
  277.     
  278.     if ( fInlineInput )
  279.     {
  280.         long    usedText = fFontReference->TextWidth( text, start, length );
  281.         short    vInline = fFontInfo.descent;
  282.  
  283.         if ( fInlineInput & LO_ATTR_INLINEINPUTTHICK ) {
  284.         
  285.             PenSize( 1, 2);
  286.             vInline -= 2;
  287.             
  288.         } else {
  289.         
  290.             PenSize( 1, 1);
  291.             vInline -= 1;
  292.             
  293.         }
  294.         
  295.         if ( fInlineInput & LO_ATTR_INLINEINPUTDOTTED )
  296.             PenPat( &UQDGlobals::GetQDGlobals()->gray);
  297.         else
  298.             PenPat( &UQDGlobals::GetQDGlobals()->black);
  299.  
  300.         
  301.         ::Move( -usedText, vInline );
  302.         ::Line( usedText, 0 );
  303.         
  304.         // restore things...
  305.         ::Move( 0, -vInline );
  306.         PenSize( 1, 1);
  307.         PenPat( &UQDGlobals::GetQDGlobals()->black);
  308.         
  309.     }
  310. }
  311.  
  312. const char* sUnderlineLinksPref = "browser.underline_anchors";
  313. Boolean HyperStyle::sUnderlineLinks = true;
  314. XP_HashTable HyperStyle::sFontHash = NULL;
  315.  
  316. void HyperStyle::InitHyperStyle()
  317. {
  318. #if 0
  319.     if ( !sFontHash )
  320.     {    
  321.         // the table size be: 2 fonts * 7 styles (bold, italic underline combos) * 
  322.         // 10 for safety (multiple languages)
  323.         sFontHash = XP_HashTableNew( 140, StyleHash, StyleCompFunction );
  324.     }
  325. #endif
  326.     
  327.     PREF_RegisterCallback(sUnderlineLinksPref, SetUnderlineLinks, nil);
  328.     SetUnderlineLinks(sUnderlineLinksPref, nil);
  329.     
  330.     CWebFontReference::Init();
  331. }
  332.  
  333. void HyperStyle::FinishHyperStyle()
  334. {
  335.     CWebFontReference::Finish();
  336. }
  337.  
  338. int HyperStyle::SetUnderlineLinks(const char * /*newpref*/, void * /*stuff*/)
  339. {
  340.     XP_Bool value;
  341.     PREF_GetBoolPref(sUnderlineLinksPref, &value);
  342.     sUnderlineLinks = value;
  343.     return 0;
  344. }
  345.  
  346. /*
  347. // Hash it.
  348. // Time critical
  349. uint32 HyperStyle::StyleHash( const void* style )
  350. {
  351.     return ((    ((HyperStyle*)style)->fFont << 1 ) + 
  352.                 ((HyperStyle*)style)->fSize );
  353. }
  354.  
  355. // Compare two hyperstyles
  356. // time critical routine
  357. // should function like strcmp
  358. int HyperStyle::StyleCompFunction( const void* style1, const void* style2 )
  359. {
  360.     Boolean equal = (     style1 &&
  361.                         style2 &&
  362.                     (((HyperStyle*)style1)->fFont == ((HyperStyle*)style2)->fFont) && 
  363.                     (((HyperStyle*)style1)->fSize == ((HyperStyle*)style2)->fSize) );
  364.  
  365.     if ( equal )
  366.         return 0;
  367.     else if ( !style1 )
  368.         return -1;
  369.     else if ( !style2 )
  370.         return 1;
  371.     else if (
  372.         (((HyperStyle*)style1)->fFont + ((HyperStyle*)style1)->fSize) > 
  373.         (((HyperStyle*)style2)->fFont + ((HyperStyle*)style2)->fSize) )
  374.         return -1;
  375.     else
  376.         return 1;
  377. }
  378. */
  379.  
  380. void HyperStyle::GetFontInfo()
  381. {
  382. /*
  383.     HyperStyle* hashStyle = (HyperStyle*)XP_Gethash( sFontHash, this, NULL );
  384.     if ( !hashStyle )
  385.     {        
  386.         fFontReference->GetFontInfo(&fFontInfo);
  387.  
  388.         hashStyle = new HyperStyle(this);
  389.         XP_Puthash(sFontHash, hashStyle, hashStyle);
  390.     }
  391.     else
  392.         fFontInfo = hashStyle->fFontInfo;
  393. */
  394.     fFontReference->GetFontInfo(&fFontInfo);
  395. }
  396.  
  397. //    TextWidth Dispatch routine
  398. short  HyperStyle::TextWidth(char* text, int firstByte, int byteCount )
  399. {    
  400.     return fFontReference->TextWidth(text, firstByte, byteCount);
  401. }
  402.  
  403. /*-----------------------------------------------------------------------------
  404. UGraphics is full of little graphics utilities
  405. Original version by atotic
  406. mark messed it up
  407. -----------------------------------------------------------------------------*/
  408.  
  409. void UGraphics::Initialize()
  410. {
  411. }
  412.  
  413. void UGraphics::SetFore( CPrefs::PrefEnum r )
  414. {
  415.     UGraphics::SetIfColor( CPrefs::GetColor( r ) );
  416. }
  417.  
  418. void UGraphics::SetBack( CPrefs::PrefEnum r )
  419. {
  420.     UGraphics::SetIfBkColor( CPrefs::GetColor( r ) );
  421. }
  422.  
  423. void UGraphics::VertLine( int x, int top, int height, CPrefs::PrefEnum r )
  424. {
  425.     UGraphics::SetFore( r );
  426.     MoveTo( x, top );
  427.     LineTo( x, top + height - 1 );
  428. }
  429.  
  430. void UGraphics::HorizLineAtWidth (int vertical, int left, int width, CPrefs::PrefEnum r)
  431. {
  432.     UGraphics::SetFore (r);
  433.     MoveTo (left, vertical);
  434.     LineTo (left + width - 1, vertical);
  435. }
  436.  
  437.  
  438. // Draws a diagonal to the rectangle
  439. void UGraphics::DrawLine( int16 top, int16 left, int16 bottom, int16 right, CPrefs::PrefEnum color )
  440. {
  441.     UGraphics::SetFore( color );
  442.     MoveTo( left, top );
  443.     LineTo( right, bottom );
  444. }
  445.  
  446. CGrafPtr UGraphics::IsColorPort( GrafPtr port )
  447. {
  448.     Assert_( port );
  449.     return ((((CGrafPtr)port)->portVersion) & 0xC000) == 0xC000? (CGrafPtr) port: nil;
  450. }
  451.  
  452. //
  453. //    Important Note!
  454. //    If you are going to muck with the colors of a window, be sure to give it
  455. //    a custom wctb resource! Otherwise the window will be created with a pointer
  456. //    to the SYSTEMWIDE global AuxRec and you'll change EVERYTHING.
  457. //
  458.  
  459. void 
  460. UGraphics::SetWindowColor( GrafPort* window, short field, const RGBColor& color )
  461. {
  462.     if ( !UEnvironment::HasFeature( env_SupportsColor ) )
  463.         return;
  464.     
  465.     // Get window's auxilary record. Skip on failure
  466.     AuxWinHandle        aux = NULL;
  467.     AuxWinHandle        def = NULL;
  468.     
  469.     CTabHandle            awCTable = NULL;
  470.     Boolean                foundFieldInTable = FALSE;
  471.     Boolean                hasAuxWinRec = FALSE;
  472.     Boolean                isDefault = FALSE;
  473.     
  474.     Assert_( window );
  475.     if ( !window )
  476.         return;
  477.         
  478.     hasAuxWinRec = ::GetAuxWin( window, &aux );
  479.     ::GetAuxWin( NULL, &def );
  480.     isDefault = (*aux)->awCTable == (*def)->awCTable;
  481.     
  482.     if ( isDefault || !hasAuxWinRec || !aux )
  483.     {
  484.         XP_TRACE(("UGraphics::SetWindowColor (%p) -> nil", window));
  485.         return;
  486.     }
  487.  
  488.     // Get the color table
  489.     // Find the fore/background colors, and set them to the unified scheme
  490.     awCTable = (*aux)->awCTable;
  491.     
  492.     for ( unsigned long i = 0; i <= (*awCTable)->ctSize; i++ )
  493.     {
  494.         if ( (*awCTable)->ctTable[ i ].value == field )
  495.         {
  496.             foundFieldInTable = true;
  497.             if ( UGraphics::EqualColor( (*awCTable)->ctTable[ i ].rgb, color ) )
  498.                 return;
  499.             
  500.             (*awCTable)->ctTable[ i ].rgb = color;
  501.             CTabChanged( awCTable );
  502.         }    
  503.     }
  504.     Assert_( foundFieldInTable );
  505. }
  506.  
  507. void UGraphics::SetWindowColors (LWindow *window)
  508. {
  509.     SetWindowColor (window->GetMacPort(), wContentColor, CPrefs::GetColor(CPrefs::WindowBkgnd));
  510. }
  511.  
  512. void UGraphics::FrameRectMotif (const Rect& box, Boolean inset)
  513. {
  514.     RGBColor lighter = {65535,65535,65535}, darker = {0,0,0};
  515.     FrameRectBevel(box, inset, lighter, darker);
  516. }
  517.  
  518.  
  519. void UGraphics::FrameRectSubtle (const Rect& box, Boolean inset)
  520. {
  521.     RGBColor lighter = {60000,60000,60000}, darker = {20000,20000,20000};
  522.     FrameRectBevel(box, inset, lighter, darker);
  523. }
  524.  
  525. void UGraphics::FrameRectBevel (const Rect& box, Boolean inset, const RGBColor &lighter,
  526.                                     const RGBColor &darker )
  527. {        
  528.     ::PenSize(1,1);                        
  529.     if (inset)    UGraphics::SetIfColor (darker);
  530.     else        UGraphics::SetIfColor (lighter);
  531.     MoveTo (box.left, box.top);
  532.     LineTo (box.right-1, box.top);
  533.     MoveTo (box.left, box.top);
  534.     LineTo (box.left, box.bottom-1);
  535.     
  536.     if (inset)    UGraphics::SetIfColor (lighter);
  537.     else        UGraphics::SetIfColor (darker);
  538.     MoveTo (box.right-1, box.bottom-1);
  539.     LineTo (box.right-1, box.top+1);
  540.     MoveTo (box.right-1, box.bottom-1);
  541.     LineTo (box.left+1, box.bottom-1);
  542. }
  543.  
  544. void UGraphics::FrameRectShaded (const Rect& box, Boolean inset)
  545. {
  546.     RGBColor addOn = {20000, 20000, 20000};
  547.     RGBColor lighter = {60000,60000,60000}, darker = {0,0,0};
  548.     // subPin substracts value, makes color darker
  549.     // addPin adds value, makes color lighter
  550.     SetIfColor(addOn);
  551.     if (inset)
  552.     {
  553.         OpColor(&darker);
  554.         PenMode(subPin);
  555.     }
  556.     else
  557.     {    
  558.         OpColor(&lighter);
  559.         PenMode(addPin);
  560.     }
  561.     MoveTo (box.left, box.top);
  562.     LineTo (box.right-1, box.top);
  563.     MoveTo (box.left, box.top);
  564.     LineTo (box.left, box.bottom-1);
  565.     
  566.     if (inset)
  567.     {    
  568.         OpColor(&lighter);
  569.         PenMode(addPin);
  570.     }
  571.     else
  572.     {
  573.         OpColor(&darker);
  574.         PenMode(subPin);
  575.     }
  576.     MoveTo (box.right-1, box.bottom-1);
  577.     LineTo (box.right-1, box.top+1);
  578.     MoveTo (box.right-2, box.bottom-1);
  579.     LineTo (box.left+1, box.bottom-1);
  580.         PenMode(srcCopy);
  581. }
  582.  
  583. void DrawArc( const RGBColor& initColor, const Rect& box, Boolean inset )
  584. {
  585.     RGBColor lighter = {60000,60000,60000}, darker = {0,0,0};
  586.  
  587.     UGraphics::SetIfColor( initColor );
  588.     if ( inset )
  589.     {
  590.         OpColor( &darker );
  591.         PenMode( subPin );
  592.     }
  593.     else
  594.     {    
  595.         OpColor( &lighter );
  596.         PenMode( addPin );
  597.     }
  598.     FrameArc( &box, 225, 180 );
  599.     if ( inset )
  600.     {    
  601.         OpColor( &lighter );
  602.         PenMode( addPin );
  603.     }
  604.     else
  605.     {
  606.         OpColor( &darker );
  607.         PenMode( subPin );
  608.     }
  609.     FrameArc( &box, 45, 180 );
  610. }
  611.  
  612. void UGraphics::FrameCircleShaded( const Rect& box, Boolean inset )
  613. {
  614.     RGBColor first = { 20000, 20000, 20000 };    
  615.     RGBColor second = { 30000, 30000, 30000 };
  616.     // subPin substracts value, makes color darker
  617.     // addPin adds value, makes color lighter
  618.     DrawArc( first, box, inset );
  619.     Rect tempRect = box; // box is CONST!
  620.     InsetRect( &tempRect, -1, -1 );
  621.     DrawArc( second, tempRect, inset );    
  622.     PenMode( srcCopy );
  623. }
  624.  
  625. void ArithHighlight( const Rect& box, const RGBColor& curr );
  626. void ArithHighlight( const Rect& box, const RGBColor& curr )
  627. {
  628.     RGBColor    tmp = curr;
  629.  
  630.     tmp.red = ~tmp.red;
  631.     tmp.green = ~tmp.green;
  632.     tmp.blue = ~tmp.blue;
  633.  
  634.     RGBColor darker = { 0, 0, 0};
  635.     RGBColor addOn = { 30000, 30000, 30000 };
  636.  
  637.     UGraphics::SetIfColor( addOn );
  638.     OpColor( &tmp );
  639.     
  640.     PenMode( addPin );
  641.     PenPat( &UQDGlobals::GetQDGlobals()->black );
  642.     ::PaintRect( &box );
  643.     PenMode( patCopy );
  644. }
  645.  
  646. void UGraphics::FrameTopLeftShaded( const Rect& box, short width, const RGBColor& curr )
  647. {
  648.     Rect        l;
  649.     l.top = box.top;
  650.     l.left = box.left;
  651.     l.right = box.right;
  652.     l.bottom = box.top + width;
  653.     ArithHighlight( l, curr );
  654.     l.top += width;
  655.     l.right = l.left + width;
  656.     l.bottom = box.bottom;
  657.     ArithHighlight( l, curr );
  658. }
  659.  
  660. void UGraphics::FrameEraseRect( const Rect& box, short width, Boolean focussed )
  661. {
  662.     Rect lineRect;
  663.  
  664.     // top left -> top right
  665.     lineRect.top = box.top;
  666.     lineRect.left = box.left;
  667.     lineRect.bottom = lineRect.top + width;
  668.     lineRect.right = box.right;
  669.  
  670.     ::EraseRect( &lineRect );
  671.     if ( focussed )
  672.         DarkenRect( lineRect );
  673.  
  674.     // bottom left -> bottom right
  675.     lineRect.top = box.bottom - width;
  676.     lineRect.bottom = box.bottom;
  677.     ::EraseRect( &lineRect );
  678.     if ( focussed )
  679.         DarkenRect( lineRect );
  680.  
  681.     // top left -> bottom left
  682.     lineRect.top = box.top;
  683.     lineRect.left = box.left;
  684.     lineRect.bottom = box.bottom;
  685.     lineRect.right = lineRect.left + width;
  686.     ::EraseRect( &lineRect );
  687.     if ( focussed )
  688.         DarkenRect( lineRect );
  689.  
  690.     // top right -> bottom right
  691.     lineRect.left = box.right - width;
  692.     lineRect.right = box.right;
  693.     ::EraseRect( &lineRect );
  694.     if ( focussed )
  695.         DarkenRect( lineRect );
  696. }
  697.  
  698. void UGraphics::DarkenRect( const Rect& box )
  699. {
  700.     RGBColor darker = { 0, 0, 0};
  701.     RGBColor addOn = { 10000, 10000, 10000 };
  702.     SetIfColor( addOn );
  703.     OpColor( &darker );
  704.     PenMode( subPin );
  705.     PenPat( &UQDGlobals::GetQDGlobals()->black );
  706.     ::PaintRect( &box );
  707.     PenMode( patCopy );
  708. }
  709.  
  710. Boolean    UGraphics::PointInBigRect(SPoint32 rectLoc, SDimension16 rectSize, SPoint32 loc)
  711. {
  712.     return ((loc.v > rectLoc.v) &&
  713.         (loc.v < (rectLoc.v + rectSize.height)) &&
  714.         (loc.h > rectLoc.h) &&
  715.         (loc.h < (rectLoc.h + rectSize.width)));
  716. }
  717.  
  718.  
  719.  
  720. RgnHandle UGraphics::sTempRegions[] = { NULL, NULL, NULL, NULL, NULL };
  721. Boolean UGraphics::sRegionsUsed[] = { false, false, false, false, false };
  722.  
  723. //
  724. // Get a temporary region from our cache (array, actually) of
  725. // allocated regions, if possible.  A parallel array of booleans
  726. // indicates which regions are in use; if all are unavailable,
  727. // just allocate a new one.  Call ReleaseTempRegion() when you╒re
  728. // done using the region.
  729. //
  730. RgnHandle UGraphics::GetTempRegion()
  731. {
  732.     for (short i = 0; i < kRegionCacheSize; i++)
  733.     {
  734.         if (sRegionsUsed[i] == false)
  735.         {
  736.             sRegionsUsed[i] = true;
  737.             if (sTempRegions[i] == NULL)
  738.                 sTempRegions[i] = ::NewRgn();
  739.             return sTempRegions[i];
  740.             
  741.         }
  742.     }
  743.     
  744.     return (::NewRgn());
  745. }
  746.  
  747. //
  748. // Release a temporary region returned from GetTempRegion(). 
  749. // We call SetEmptyRgn() here to save some memory, and because
  750. // when the region is reused in GetTempRegion the caller will
  751. // expect the ╥new╙ region to be empty.  If the region wasn╒t
  752. // found in the cache array, then it must have been freshly
  753. // allocated by GetTempRegion because all cached regions were
  754. // in use at the time, so just dispose of the region.
  755. //
  756. void UGraphics::ReleaseTempRegion(RgnHandle rgn)
  757. {
  758.     for (short i = 0; i < kRegionCacheSize; i++)
  759.     {
  760.         if (sTempRegions[i] == rgn)
  761.         {
  762.             sRegionsUsed[i] = false;
  763.             SetEmptyRgn(rgn);
  764.             return;
  765.         }
  766.     }
  767.     
  768.     ::DisposeRgn(rgn);
  769. }
  770.  
  771.  
  772. /*****************************************************************************
  773.  * class CEditBroadcaster
  774.  * LEditField that notifies listeners about its changes
  775.  *****************************************************************************/
  776.  
  777. CEditBroadcaster::CEditBroadcaster(LStream *inStream)
  778.     :    CTSMEditField(inStream)
  779. {
  780. }
  781.  
  782. void CEditBroadcaster::UserChangedText()
  783. {
  784.     BroadcastMessage(msg_EditField, this);
  785. }
  786.  
  787. /*****************************************************************************
  788.  * class CGAEditBroadcaster
  789.  * LGAEditField that notifies listeners about its changes
  790.  *****************************************************************************/
  791.  
  792. CGAEditBroadcaster::CGAEditBroadcaster(LStream *inStream)
  793.     :    LGAEditField(inStream)
  794. {
  795. }
  796.  
  797. void CGAEditBroadcaster::UserChangedText()
  798. {
  799.     BroadcastMessage(msg_EditField, this);
  800. }
  801.  
  802. void
  803. CGAEditBroadcaster::BroadcastValueMessage()
  804. {
  805.     BroadcastMessage(msg_EditField, this);
  806. }
  807.  
  808. /*****************************************************************************
  809.  * class CTextEdit
  810.  * LTextEdit that keeps track if it has been modified
  811.  *****************************************************************************/
  812.  
  813. CTextEdit::CTextEdit(LStream *inStream) : LTextEdit(inStream)
  814. {
  815.     fModified = FALSE;
  816. }
  817.  
  818. void CTextEdit::UserChangedText()
  819. {
  820.     fModified = TRUE;
  821.     LTextEdit::UserChangedText();
  822. }
  823.  
  824. /*****************************************************************************
  825.  * class CResPicture
  826.  * LPicture with an associated resfile ID
  827.  *****************************************************************************/
  828. CResPicture::CResPicture(LStream *inStream)
  829.     : LPicture(inStream)
  830. {
  831.     mResFileID = -1;
  832. }
  833.  
  834. void CResPicture::DrawSelf()
  835. {
  836.     Int16 resfile = ::CurResFile();
  837.     if (mResFileID != -1)
  838.         ::UseResFile(mResFileID);
  839.     
  840.     LPicture::DrawSelf();
  841.     
  842.     ::UseResFile(resfile);
  843. }
  844.  
  845.  
  846. #ifdef PROFILE
  847. #pragma profile off
  848. #endif
  849.  
  850.