TweetFollow Us on Twitter

MACINTOSH C CARBON

Demonstration Program Appearance

Goto Contents

// *******************************************************************************************
// Appearance.c                                                            CLASSIC EVENT MODEL
// *******************************************************************************************
// 
// This program opens two kWindowDocumentProc windows containing:
//
// o  In the first window:
//
//    o  On Mac OS 8/9, a theme-compliant list view.
//
//    o  On Mac OS X, some text drawn with Appearance Manager functions.
//
// o  In the second window, various images drawn with Appearance primitives and, on Mac OS 
//    8/9, text drawn in the window header in the correct Appearance colour.
//
// Two of the images in the second window are edit text field frames and one is a list box
// frame.  At any one time, one of these will have a keyboard focus frame drawn around it.
// Clicking in one of the other frames will move the keyboard focus frame to that frame.
//
// The program utilises the following resources:
//
// o  A 'plst' resource.
//
// o  An 'MBAR' resource, and 'MENU' resources for Apple, File, and Edit menus (preload, 
//    non-purgeable).  
//
// o  Two 'WIND' resources (purgeable) (initially not visible).
//
// o  A 'STR#' list resource (purgeable) containing text drawn in the first window.
//
// o  'hrct' and 'hwin' resources (both purgeable), which provide help balloons describing the
//     contents of the windows (Mac OS 8/9).
//
// o  A 'SIZE' resource with the acceptSuspendResumeEvents,  canBackground, 
//    doesActivateOnFGSwitch, and isHighLevelEventAware flags set.
//
// *******************************************************************************************

// .................................................................................. includes

#include <Carbon.h>

// ................................................................................... defines

#define rMenubar          128
#define rNewWindow1       128
#define rNewWindow2       129
#define mAppleApplication 128
#define  iAbout           1
#define mFile             129
#define  iQuit            12
#define sDescription      128
#define MAX_UINT32        0xFFFFFFFF

// .......................................................................... global variables

Boolean   gRunningOnX = false;
Boolean   gDone;
Boolean   gInBackground;
WindowRef gWindowRef1, gWindowRef2;
SInt16    gPixelDepth;
Boolean   gIsColourDevice = false;
Rect      gCurrentRect;
Rect      gEditText1Rect = { 141, 20, 162, 239 };
Rect      gEditText2Rect = { 169, 20, 190, 239 };
Rect      gListBoxRect   = { 203, 90, 300, 239 };

// ....................................................................... function prototypes

void  main                        (void);
void  doPreliminaries             (void);
OSErr quitAppEventHandler         (AppleEvent *,AppleEvent *,SInt32);
void  doEvents                    (EventRecord *);
void  doUpdate                    (EventRecord *);
void  doActivate                  (EventRecord *);
void  doActivateWindow            (WindowRef,Boolean);
void  doOSEvent                   (EventRecord *);
void  doDrawAppearancePrimitives  (ThemeDrawState);
void  doDrawThemeCompliantTextOn9 (WindowRef,ThemeDrawState);
void  doDrawListViewOn9           (WindowRef);
void  doDrawThemeTextOnX          (WindowRef,ThemeDrawState);
void  doChangeKeyBoardFocus       (Point);
void  doGetDepthAndDevice         (void);

// ************************************************************************************** main

void  main(void)
{
  MenuBarHandle menubarHdl;
  SInt32        response;
  MenuRef       menuRef;
  SInt16        fontNum;
  EventRecord   EventStructure;

  // ........................................................................ do preliminaries

  doPreliminaries();

  // ............................................................... set up menu bar and menus

  menubarHdl = GetNewMBar(rMenubar);
  if(menubarHdl == NULL)
    ExitToShell();
  SetMenuBar(menubarHdl);
  DrawMenuBar();

  Gestalt(gestaltMenuMgrAttr,&response);
  if(response & gestaltMenuMgrAquaLayoutMask)
  {
    menuRef = GetMenuRef(mFile);
    if(menuRef != NULL)
    {
      DeleteMenuItem(menuRef,iQuit);
      DeleteMenuItem(menuRef,iQuit - 1);
      DisableMenuItem(menuRef,0);
    }

    gRunningOnX = true;
  }

  // .................................. open first window, set font and font size, show window

  if(!(gWindowRef1 = GetNewCWindow(rNewWindow1,NULL,(WindowRef)-1)))
    ExitToShell();

  SetPortWindowPort(gWindowRef1);
  if(!gRunningOnX)
    UseThemeFont(kThemeSmallSystemFont,smSystemScript);
  else
  {
    GetFNum("\pAmerican Typewriter",&fontNum);
    TextFont(fontNum);
    TextSize(11);
  }

  if(!gRunningOnX)
    SetWTitle(gWindowRef1,"\pList Views");
  else
    SetWTitle(gWindowRef1,"\pTheme Text");

  ShowWindow(gWindowRef1);

  // ................ open second window, set font, set background colour/pattern, show window


  if(!(gWindowRef2 = GetNewCWindow(rNewWindow2,NULL,(WindowRef)-1)))
    ExitToShell();

  SetPortWindowPort(gWindowRef2);
  UseThemeFont(kThemeSmallSystemFont,smSystemScript);

  SetThemeWindowBackground(gWindowRef2,kThemeBrushDialogBackgroundActive,false);

  ShowWindow(gWindowRef2);

  // ...... get pixel depth and whether colour device for certain Appearance Manager functions

  if(!gRunningOnX)
    doGetDepthAndDevice();

// .............. set top edit text field rectangle as target for initial keyboard focus frame

  gCurrentRect = gEditText1Rect;

  // ......................................................................... enter eventLoop

  gDone = false;

  while(!gDone)
  {
    if(WaitNextEvent(everyEvent,&EventStructure,MAX_UINT32,NULL))
      doEvents(&EventStructure);
  }
}

// *************************************************************************** doPreliminaries

void  doPreliminaries(void)
{
  OSErr osError;

  MoreMasterPointers(32);
  InitCursor();
  FlushEvents(everyEvent,0);

  osError = AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,
                            NewAEEventHandlerUPP((AEEventHandlerProcPtr) quitAppEventHandler),
                            0L,false);
  if(osError != noErr)
    ExitToShell();  
}

// **************************************************************************** doQuitAppEvent

OSErr  quitAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon)
{
  OSErr    osError;
  DescType returnedType;
  Size     actualSize;

  osError = AEGetAttributePtr(appEvent,keyMissedKeywordAttr,typeWildCard,&returnedType,NULL,0,
                              &actualSize);

  if(osError == errAEDescNotFound)
  {
    gDone = true;
    osError = noErr;
  } 
  else if(osError == noErr)
    osError = errAEParamMissed;

  return osError;
}

// ********************************************************************************** doEvents

void  doEvents(EventRecord *eventStrucPtr)
{
  SInt32         menuChoice;
  MenuID         menuID;
  MenuItemIndex  menuItem;
  WindowPartCode partCode;
  WindowRef      windowRef;

  switch(eventStrucPtr->what)
  {
    case kHighLevelEvent:
      AEProcessAppleEvent(eventStrucPtr);
      break;

    case keyDown:
      if((eventStrucPtr->modifiers & cmdKey) != 0)
      {
        menuChoice = MenuEvent(eventStrucPtr);
        menuID = HiWord(menuChoice);
        menuItem = LoWord(menuChoice);
        if(menuID == mFile && menuItem  == iQuit)
          gDone = true;
      }
      break;

    case mouseDown:
      if(partCode = FindWindow(eventStrucPtr->where,&windowRef))
      {
        switch(partCode)
        {
          case inMenuBar:
            menuChoice = MenuSelect(eventStrucPtr->where);
            menuID = HiWord(menuChoice);
            menuItem = LoWord(menuChoice);

            if(menuID == 0)
              return;

            switch(menuID)
            {
              case mAppleApplication:
                if(menuItem == iAbout)
                {
                  SysBeep(10);
                  HiliteMenu(0);
                }
                break;

              case mFile:
                if(menuItem == iQuit)
                  gDone = true;
                break;
            }
            break;
        
          case inContent:
            if(windowRef != FrontWindow())
              SelectWindow(windowRef);
            else
            {
              if(FrontWindow() == gWindowRef2)
              {
                SetPortWindowPort(gWindowRef2);
                doChangeKeyBoardFocus(eventStrucPtr->where);
              }
            }
            break;
          
          case inDrag:
            DragWindow(windowRef,eventStrucPtr->where,NULL);
            break;
        }
      }
      break;

    case updateEvt:
      doUpdate(eventStrucPtr);
      break;

    case activateEvt:
      doActivate(eventStrucPtr);
      break;

    case osEvt:
      doOSEvent(eventStrucPtr);
      break;
  }
}

// ********************************************************************************** doUpdate

void  doUpdate(EventRecord *eventStrucPtr)
{
  WindowRef windowRef;

  windowRef = (WindowRef) eventStrucPtr->message;

  BeginUpdate(windowRef);

  SetPortWindowPort(windowRef);

  if(windowRef == gWindowRef2)
  {
    if(gWindowRef2 == FrontWindow() && !gInBackground)
    {
      doDrawAppearancePrimitives(kThemeStateActive);
      DrawThemeFocusRect(&gCurrentRect,true);
      if(!gRunningOnX)
        doDrawThemeCompliantTextOn9(windowRef,kThemeStateActive);
    }
    else
    {
      doDrawAppearancePrimitives(kThemeStateInactive);
      if(!gRunningOnX)
        doDrawThemeCompliantTextOn9(windowRef,kThemeStateInactive);
    }
  }

  if(windowRef == gWindowRef1)
  {
    if(!gRunningOnX)
      doDrawListViewOn9(windowRef);
  }

  EndUpdate(windowRef);
}

// ******************************************************************************** doActivate

void  doActivate(EventRecord *eventStrucPtr)
{
  WindowRef windowRef;
  Boolean   becomingActive;

  windowRef = (WindowRef) eventStrucPtr->message;
  becomingActive = ((eventStrucPtr->modifiers & activeFlag) == activeFlag);
  doActivateWindow(windowRef,becomingActive);
}

// ************************************************************************** doActivateWindow

void  doActivateWindow(WindowRef windowRef,Boolean becomingActive)
{
  if(windowRef == gWindowRef2)
  {
    SetPortWindowPort(gWindowRef2);
    doDrawAppearancePrimitives(becomingActive);
    DrawThemeFocusRect(&gCurrentRect,becomingActive);

    if(!gRunningOnX)
      doDrawThemeCompliantTextOn9(windowRef,becomingActive);

  }
  else if(windowRef == gWindowRef1 && gRunningOnX)
  {
    SetPortWindowPort(gWindowRef1);
    doDrawThemeTextOnX(windowRef,becomingActive);
  }
}

// ********************************************************************************* doOSEvent

void  doOSEvent(EventRecord *eventStrucPtr)
{
  switch((eventStrucPtr->message >> 24) & 0x000000FF)
  {
    case suspendResumeMessage:
      if((eventStrucPtr->message & resumeFlag) == 1)
      {
        SetThemeCursor(kThemeArrowCursor);
        gInBackground = false;
      }
      else
        gInBackground = true;
      break;
  }
}

// **************************************************************** doDrawAppearancePrimitives

void  doDrawAppearancePrimitives(ThemeDrawState inState)
{
  Rect theRect;

  if(gRunningOnX)
  {
    GetWindowPortBounds(gWindowRef2,&theRect);
    EraseRect(&theRect);
  }

  SetRect(&theRect,-1,-1,261,26);
  DrawThemeWindowHeader(&theRect,inState);

  SetRect(&theRect,20,46,119,115);
  DrawThemePrimaryGroup(&theRect,inState);

  SetRect(&theRect,140,46,239,115);
  DrawThemeSecondaryGroup(&theRect,inState);

  SetRect(&theRect,20,127,240,128);
  DrawThemeSeparator(&theRect,inState);

  DrawThemeEditTextFrame(&gEditText1Rect,inState);

  DrawThemeEditTextFrame(&gEditText2Rect,inState);

  SetRect(&theRect,20,203,62,245);
  DrawThemeGenericWell(&theRect,inState,false);

  SetRect(&theRect,20,258,62,300);
  DrawThemeGenericWell(&theRect,inState,true);

  SetRect(&theRect,75,202,76,302);
  DrawThemeSeparator(&theRect,inState);

  DrawThemeListBoxFrame(&gListBoxRect,inState);

  SetRect(&theRect,-1,321,261,337);
  DrawThemePlacard(&theRect,inState);
}

// *************************************************************** doDrawThemeCompliantTextOn9

void  doDrawThemeCompliantTextOn9(WindowRef windowRef,ThemeDrawState inState)
{
  SInt16 windowWidth, stringWidth;
  Rect   portRect;
  Str255 message = "\pBalloon help is available";

  if(inState == kThemeStateActive)
    SetThemeTextColor(kThemeTextColorWindowHeaderActive,gPixelDepth,gIsColourDevice);
  else
    SetThemeTextColor(kThemeTextColorWindowHeaderInactive,gPixelDepth,gIsColourDevice);

  GetWindowPortBounds(windowRef,&portRect);
  windowWidth = portRect.right - portRect.left;
  stringWidth = StringWidth(message);
  MoveTo((windowWidth / 2) - (stringWidth / 2), 17);
  DrawString(message);  
}

// ************************************************************************* doDrawListViewOn9

void  doDrawListViewOn9(WindowRef windowRef)
{
  Rect   theRect;
  SInt16 a;

  GetWindowPortBounds(windowRef,&theRect);

  SetThemeBackground(kThemeBrushListViewBackground,gPixelDepth,gIsColourDevice);
  EraseRect(&theRect);

  theRect.left += 130;

  SetThemeBackground(kThemeBrushListViewSortColumnBackground,gPixelDepth,gIsColourDevice);
  EraseRect(&theRect);

  SetThemePen(kThemeBrushListViewSeparator,gPixelDepth,gIsColourDevice);

  GetWindowPortBounds(windowRef,&theRect);

  for(a=theRect.top;a<=theRect.bottom;a+=18)
  {
    MoveTo(theRect.left,a);
    LineTo(theRect.right - 1,a);
  }

  SetThemeTextColor(kThemeTextColorListView,gPixelDepth,gIsColourDevice);

  for(a=theRect.top;a<=theRect.bottom +18;a+=18)
  {
    MoveTo(theRect.left,a - 5);
    DrawString("\p   List View Background        List View Sort Column");
  }
}

// ************************************************************************ doDrawThemeTextOnX

void  doDrawThemeTextOnX(WindowRef windowRef,ThemeDrawState inState)
{
  Rect        portRect;
  Str255      theString;
  CFStringRef stringRef;

  GetWindowPortBounds(windowRef,&portRect);
  EraseRect(&portRect);

  if(inState == kThemeStateActive)
    TextMode(srcOr);
  else
    TextMode(grayishTextOr);

  SetRect(&portRect,portRect.left,30,portRect.right,50);
  DrawThemeTextBox(CFSTR("System Font"),kThemeSystemFont,inState,true,
                   &portRect,teJustCenter,NULL);
  SetRect(&portRect,portRect.left,60,portRect.right,80);
  DrawThemeTextBox(CFSTR("Emphasized System Font"),kThemeEmphasizedSystemFont,inState,true,
                   &portRect,teJustCenter,NULL);
  SetRect(&portRect,portRect.left,90,portRect.right,105);
  DrawThemeTextBox(CFSTR("Small System Font"),kThemeSmallSystemFont,inState,true,
                   &portRect,teJustCenter,NULL);
  SetRect(&portRect,portRect.left,120,portRect.right,135);
  DrawThemeTextBox(CFSTR("Small Emphasized System Font"),kThemeSmallEmphasizedSystemFont,
                   inState,true,&portRect,teJustCenter,NULL);
  SetRect(&portRect,portRect.left,150,portRect.right,170);
  DrawThemeTextBox(CFSTR("Application Font"),kThemeApplicationFont,inState,true,
                   &portRect,teJustCenter,NULL);
  SetRect(&portRect,portRect.left,180,portRect.right,190);
  DrawThemeTextBox(CFSTR("Label Font"),kThemeLabelFont,inState,true,
                   &portRect,teJustCenter,NULL);
  
  GetIndString(theString,sDescription,1);
  stringRef = CFStringCreateWithPascalString(NULL,theString,CFStringGetSystemEncoding());
  SetRect(&portRect,portRect.left + 20,210,portRect.right - 20,300);
  DrawThemeTextBox(stringRef,kThemeCurrentPortFont,inState,true,&portRect,teJustCenter,NULL);

  if(stringRef != NULL)
    CFRelease(stringRef);
}

// ********************************************************************* doChangeKeyBoardFocus

void  doChangeKeyBoardFocus(Point mouseXY)
{
  Rect portRect;

  DrawThemeFocusRect(&gCurrentRect,false);
  DrawThemeEditTextFrame(&gCurrentRect,kThemeStateActive);
  SetPortWindowPort(gWindowRef2);
  GlobalToLocal(&mouseXY);

  if(PtInRect(mouseXY,&gEditText1Rect))
    gCurrentRect = gEditText1Rect;
  else if(PtInRect(mouseXY,&gEditText2Rect))
    gCurrentRect = gEditText2Rect;
  else if(PtInRect(mouseXY,&gListBoxRect))
    gCurrentRect = gListBoxRect;

  GetWindowPortBounds(gWindowRef2,&portRect);
  InvalWindowRect(gWindowRef2,&portRect);
}

// *********************************************************************** doGetDepthAndDevice

void doGetDepthAndDevice(void)
{
  GDHandle deviceHdl;

  deviceHdl = GetMainDevice();
  gPixelDepth = (*(*deviceHdl)->gdPMap)->pixelSize;
  if(((1 << gdDevType) & (*deviceHdl)->gdFlags) != 0)
    gIsColourDevice = true;
}

// *******************************************************************************************

Demonstration Program Appearance Comments

When this program is run, the user should:

o With the "Drawing With Primitives" window frontmost, click in the edit text frame not
  currently outlined with the keyboard focus frame, or in the list box frame, so as to move the
  keyboard focus frame to that rectangle.

o Click on the desktop to send the application to the background and note the changed
  appearance of the frames and text in the "Drawing With Primitives" window.  On Mac OS 8/9,
  note also that there is no change to the appearance of the content region of the "List Views"
  window.  On Mac OS X, note the changed appearance of the text in the "Theme Text" window. 
  Click on the "Drawing With Primitives" window to bring the application to the foreground with
  that window active, noting the changed appearance of the frames and text.  Click on the
  "Theme Text" window to make it active and note the changed appearance of the text.

o On Mac OS 8/9, Choose Show Balloons from the Help menu and move the cursor over the frames in
  the window titled "Drawing With Primitives" window (when active), and the left and right 
  sides of the window titled "List Views" (when active), noting the descriptions
  in the balloons.

In the following, reference is made to graphics devices and pixel depth.  Graphics devices and
pixel depth are explained at Chapter 11.

Global Variables

gWindowRef1 and gWindowRef2 will be assigned references to window objects.

gPixelDepth will be assigned the pixel depth of the main device (screen).  gIsColourDevice will
be assigned true if the graphics device is a colour device and false if it is a monochrome
device.  The values in these two variables are required by certain Appearance Manager
functions.

gCurrentRect will be assigned the rectangle which is to be the current target for the keyboard
focus frame.  gEditText1Rect, gEditText2Rect, and gListBoxRect are assigned the rectangles for
the two edit text frames and the list box frame.

main

After each window is created, its graphics port is set as the current port before the port's
font is set.  For the first window's graphics port, if the program is running on Mac OS 8/9,
the Appearance Manager function UseThemeFont is called to set the font to the small system
font.  Otherwise the Font Manager function GetFNum is called to get the font number for
American Typewriter, which is then set as the port's font, at 11 points, by the QuickDraw
functions TextFont and TextSize.  For the second window's graphics port, UseThemeFont is called
to set the font to the small system font.

If the program is running on OS 8/9, SetThemeWindowBackground is called to set a
theme-compliant colour/pattern for the "Drawing With Primitives" window's content area.  This
means that the content area will be automatically repainted with that colour/pattern when
required with no further assistance from the application.  When false is passed in the third
parameter, the content region of the window is not invalidated.  (Passing true in this instance
is not appropriate because the window is not yet showing.)

If the program is running on OS 8/9, doGetDepthAndDevice is called to determine the current
pixel depth of the graphics port, and whether the current graphics device is a colour device,
and assign the results to the global variables gPixelDepth and gIsColourDevice.  These values
are required by certain Appearance Manager functions which, in this program, are not called if
the program is running on Mac OS X.

The next line sets the initial target for the keyboard focus frame.  This is the rectangle used
by the first edit text field frame.

doEvents

At the mouseDown case, the inContent case within the partCode switch is of relevance to the
demonstration.

If the mouse-down was within the content region of a window, and if that window is not the
front window, SelectWindow is called to bring that window to the front and activate it.

However, if the window is the front window, and if that window is the "Drawing With Primitives"
window, that window's graphics port is set as the current graphics port for drawing, and
doChangeKeyBoardFocus is called.  That function determines whether the mouse-down was within
one of the edit text field frames or the list box frame, and moves the keyboard focus if
necessary.

doUpdate

Within the doUpdate function, if the window to which the update event relates is the "Drawing
With Primitives" window, if that window is currently the front window, and if the application
is not currently in the background:

o Functions are called to draw the primitives and, on Mac OS 8/9 only, the window header text
  in the active mode.

o DrawThemeFocusRect is called to draw the keyboard focus frame using the rectangle currently
  assigned to the global variable gCurrentRect.

If, however, the "Drawing With Primitives" window is not the front window, the same calls are
made but with the primitives and, on Mac OS 8/9 only, text being drawn in the inactive mode. 
Note that no call is required to erase the keyboard focus frame because this will already have
been erased when the window was deactivated (see below).

If the window to which the update event relates is the "List Views" window, doDrawListViewOn9
is called to draw the window's content area.  Note that, for this window, there is no
differentiation between active and inactive modes.  This is because, for list views, the same
brush type constants are used regardless of whether the window is active or inactive.

doActivateWindow

When an activate event is received for the "Drawing With Primitives" window, functions are
called to draw the primitives and, on Mac OS 8/9 only, the window header text.  In addition, an
Appearance Manager function which draws and erases the keyboard focus rectangle is called.  The
value passed in the becomingActive parameter of these calls ensures ensure that, firstly, the
primitives and text are drawn in the appropriate mode and, secondly, the keyboard focus frame
is either drawn or erased, depending on whether the window is coming to the front or being sent
to the back.

If the activate event is for the first window and the program is running on Mac OS X,
doDrawThemeTextOnX is called to draw some text in the window in either the active or inactive
mode.

doDrawAppearancePrimitives

doDrawAppearancePrimitives uses Appearance Manager functions for drawing Appearance primitives,
and is called to draw the various frames in the "Drawing With Primitives" window.  The mode in
which the primitives are drawn (active or inactive) is determined by the Boolean value passed
in the inState parameter.

doDrawThemeCompliantTextOn9

doDrawThemeCompliantTextOn9, which is called only if the program is running on Mac OS 8/9, draw
some advisory text in the window header of the "Drawing With Primitives" window.  The QuickDraw
drawing function DrawString does the drawing; however, before the drawing begins, the
Appearance Manager function SetThemeTextColor is used to set the foreground colour for drawing
text, in either the active or inactive modes, so as to comply with the Platinum appearance.

At the first two lines, if "Drawing With Primitives" is the active window, SetThemeTextColor is
called with the kThemeTextColorWindowHeaderActive text colour constant passed in the first
parameter.  At the next two lines, if the window is inactive, SetThemeTextColor is called with
kThemeTextColorWindowHeaderInactive passed in the first parameter.  Note that SetThemeTextColor
requires the pixel depth of the graphics port, and whether the graphics device is a colour
device or a monochrome device, passed in the second and third parameters.

The next four lines simply adjust QuickDraw's pen location so that the text is drawn centered
laterally in the window header frame.  The call to DrawString draws the specified text.

doDrawListViewOn9

doDrawListViewOn9, which  is called only if the program is running on Mac OS 8/9, draws a list
view background in the specified window.

The first line copies the window's port rectangle to a local variable of type Rect.

The call to SetThemeBackground sets the background colour/pattern to the colour/pattern
represented by the theme-compliant brush type constant kThemeBrushListViewBackground.  The
QuickDraw function EraseRect fills the whole of the port rectangle with this colour/pattern.

The next line adjusts the Rect variable's left field so that the rectangle now represents the
right half of the port rectangle.  The same drawing process is then repeated, but this time
with kThemeBrushListViewSortColumnBackground passed in the first parameter of the
SetThemeBackground call.

SetThemePen is then called with the colour/pattern represented by the constant
kThemeBrushListViewSeparator passed in the first parameter.  The rectangle for drawing is then
expanded to equate with the port rectangle before the following five lines draw one-pixel-wide
horizontal lines, at 18-pixel intervals, from the top to the bottom of the port rectangle.

Finally, some text is drawn in the list view in the theme-compliant colour for list views. 
SetThemeTextColour is called with the kThemeTextColorListView passed in, following which a for
loop draws some text, at 18-pixel intervals, from the top to the bottom of the port rectangle.

doDrawThemeTextOnX

doDrawThemeTextOnX is called only if the program is running on Mac OS X.  It draws anti-aliased
text in the first window.

GetWindowPortBounds is called to copy the port rectangle to a local variable of type Rect. 
EraseRect is then called to erase the port rectangle, a necessary precursor to drawing over
existing anti-aliased text on Mac OS X using the Appearance Manager function DrawThemeTextBox.

As was done in the function doDrawThemeCompliantTextOn9, SetThemeTextColor could be used here
to set the text colour according to the value received in the inState formal parameter. 
However, in this instance the alternative of calling TextMode is used.  The so-called transfer
modes passed in the calls to TextMode are explained at Chapter 12.  srcOr is the default
transfer mode for text, and causes the colour of the glyph (the visual representation of a
character) to be determined by the graphics port's foreground colour.  The non-standard mode
grayishTextOr is used to draw text in the deactivated state.

Before each call to DrawThemeTextBox, SetRect is called to adjust the top and bottom fields of
the Rect variable portRect.  This controls the vertical positioning of the text in the window,
being passed in DrawThemeTextBox's inBoundingBox parameter.  teJustCenter is passed in
DrawThemeTextBox's inJust parameter to cause the text to be centre-justified within the
rectangle.  The Appearance Manager constants passed in the inFontID parameter determine the
size and style of the drawn text.

At the last block, a string is retrieved from a 'STR#' Resource.  After being converted to a
CFString, that string is drawn by DrawThemeTextBox in the bottom of the window.  Note that
kThemeCurrentPort passed in the inFontID parameter so as to cause the text to be drawn using
the window's graphics port font, which was set in main.

doChangeKeyBoardFocus

doChangeKeyBoardFocus is called when a mouse-down occurs in the content region of the "Drawing
With Primitives" window.

At the first two lines, Appearance Manager functions are used to, firstly, erase the keyboard
focus frame from the rectangle around which it is currently drawn and, secondly, redraw an edit
text field frame around that rectangle.

The call to GlobalToLocal converts the coordinates of the mouse-down to the local coordinates
required by the following calls to PtInRect.  PtInRect returns true if the mouse-down is within
the rectangle passed in the second parameter.  If one of the calls to PtInRect returns true,
that rectangle is made the current rectangle for keyboard focus by assigning it to the global
variable gCurrentRect.

The call to InvalWindowRect ensures that the keyboard focus frame will be drawn by the call to
DrawThemeFocusRect in the function doUpdate.

doGetDepthAndDevice

doGetDepthAndDevice determines the pixel depth of the graphics port, and whether the graphics
device is a colour device or a monochrome device, and assigns the results to two global
variables.  This information is required by the Appearance Manager functions SetThemeTextColor,
SetThemeBackground, and SetThemePen.
 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Deeper 2.2.1 - Enable hidden features in...
Deeper is a personalization utility for macOS which allows you to enable and disable the hidden functions of the Finder, Dock, QuickTime, Safari, iTunes, login window, Spotlight, and many of Apple's... Read more
Spotify 1.0.59.395. - Stream music, crea...
Spotify is a streaming music service that gives you on-demand access to millions of songs. Whether you like driving rock, silky R&B, or grandiose classical music, Spotify's massive catalogue puts... Read more
FileZilla 3.27.0.1 - Fast and reliable F...
FileZilla (ported from Windows) is a fast and reliable FTP client and server with lots of useful features and an intuitive interface. Version 3.27.0.1: MSW: Add misssing file to .zip binary package... Read more
Sierra Cache Cleaner 11.0.6 - Clear cach...
Sierra Cache Cleaner is an award-winning general purpose tool for macOS X. SCC makes system maintenance simple with an easy point-and-click interface to many macOS X functions. Novice and expert... Read more
Live Home 3D Pro 3.1.2 - $69.99
Live Home 3D Pro, a successor of Live Interior 3D, is the powerful yet intuitive home design software that lets you build the house of your dreams right on your Mac. It has every feature of Live Home... Read more
Pinegrow 3.04 - Mockup and design webpag...
Pinegrow (was Pinegrow Web Designer) is desktop app that lets you mockup and design webpages faster with multi-page editing, CSS and LESS styling, and smart components for Bootstrap, Foundation,... Read more
DiskCatalogMaker 7.1.2 - Catalog your di...
DiskCatalogMaker is a simple disk management tool which catalogs disks. Simple, light-weight, and fast Finder-like intuitive look and feel Super-fast search algorithm Can compress catalog data for... Read more
Apple iTunes 12.6.2 - Play Apple Music a...
Apple iTunes lets you organize and stream Apple Music, download and watch video and listen to Podcasts. It can automatically download new music, app, and book purchases across all your devices and... Read more
Transmit 5.0 - Excellent FTP/SFTP client...
Transmit is an excellent FTP (file transfer protocol), SFTP, S3 (Amazon.com file hosting) and iDisk/WebDAV client that allows you to upload, download, and delete files over the internet. With the... Read more
Adobe Lightroom 6.12 - Import, develop,...
Adobe Lightroom is available as part of Adobe Creative Cloud for as little as $9.99/month bundled with Photoshop CC as part of the photography package. Lightroom 6 is also available for purchase as a... Read more

Latest Forum Discussions

See All

The best deals on the App Store this wee...
There are quite a few truly superb games on sale on the App Store this week. If you haven't played some of these, many of which are true classics, now's the time to jump on the bandwagon. Here are the deals you need to know about. [Read more] | Read more »
Realpolitiks Mobile (Games)
Realpolitiks Mobile 1.0 Device: iOS Universal Category: Games Price: $5.99, Version: 1.0 (iTunes) Description: PLEASE NOTE: The game might not work properly on discontinued 1GB of RAM devices (iPhone 5s, iPhone 6, iPhone 6 Plus, iPad... | Read more »
Layton’s Mystery Journey (Games)
Layton’s Mystery Journey 1.0.0 Device: iOS Universal Category: Games Price: $15.99, Version: 1.0.0 (iTunes) Description: THE MUCH-LOVED LAYTON SERIES IS BACK WITH A 10TH ANNIVERSARY INSTALLMENT! Developed by LEVEL-5, LAYTON’S... | Read more »
Full Throttle Remastered (Games)
Full Throttle Remastered 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: Originally released by LucasArts in 1995, Full Throttle is a classic graphic adventure game from industry legend Tim... | Read more »
Stunning shooter Morphite gets a new tra...
Morphite is officially landing on iOS in September. The game looks like the space shooter we've been needing on mobile, and we're going to see if it fits the bill quite shortly. The game's a collaborative effort between Blowfish Studios, We're Five... | Read more »
Layton's Mystery Journey arrives to...
As you might recall, Layton's Mystery Journey is headed to iOS and Android -- tomorrow! To celebrate the impending launch, Level-5's released a new trailer, complete with an adorable hamster. [Read more] | Read more »
Sidewords (Games)
Sidewords 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: Grab a cup of coffee and relax with Sidewords. Sidewords is part logic puzzle, part word game, all original. No timers. No... | Read more »
Noodlecake Games' 'Leap On!...
Noodlecake Games is always good for some light-hearted arcade fun, and its latest project, Leap On! could carry on that tradition. It's a bit like high stakes tetherball in a way. Your job is to guide a cute little blob around a series of floating... | Read more »
RuneScape goes mobile later this year
Yes, RuneScape still exists. In fact, it's coming to iOS and Android in just a few short months. Jagex, creators of the hit fantasy MMORPG of yesteryear, is releasing RuneScape Mobile and Old School RuneScape for mobile devices, complete with... | Read more »
Crash of Cars wants you to capture the c...
Crash of Cars is going full on medieval in its latest update, introducing castles and all manner of new cars and skins fresh from the Dark Ages. The update introduces a new castle-themed map (complete with catapults) and a gladiator-style battle... | Read more »

Price Scanner via MacPrices.net

Save or Share
FotoJet Designer, is a simple but powerful new graphic design apps available on both Mac and Windows. With FotoJet Designer’s 900+ templates, thousands of resources, and powerful editing tools you... Read more
Logo Maker Shop iOS App Lets Businesses Get C...
A newly released app is designed to help business owners to get creative with their branding by designing their own logos. With more than 1,000 editable templates, Logo Maker Shop 1.0 provides the... Read more
Sale! New 15-inch MacBook Pros for up to $150...
Amazon has the new 2017 15″ MacBook Pros on sale for up to $150 off MSRP including free shipping: – 15″ 2.8GHz MacBook Pro Space Gray: $2249 $150 off MSRP – 15″ 2.89Hz MacBook Pro Space Gray: $2779 $... Read more
DEVONthink To Go 2.1.7 For iOS Brings Usabili...
DEVONtechnologies has updated DEVONthink To Go, the iOS companion to DEVONthink for Mac, with enhancements and bug fixes. Version 2.1.7 adds an option to clear the Global Inbox and makes the grid... Read more
15-inch 2.2GHz Retina MacBook Pro, Apple refu...
Apple has Certified Refurbished 2015 15″ 2.2GHz Retina MacBook Pros available for $1699. That’s $300 off MSRP, and it’s the lowest price available for a 15″ MacBook Pro. An Apple one-year warranty is... Read more
13-inch 2.3GHz Silver MacBook Pro on sale for...
B&H Photo has the new 2017 13″ 2.3GHz/256GB Silver MacBook Pro (MPXU2LL/A) on sale for $1399 including free shipping plus NY & NJ sales tax only. Their price is $100 off MSRP. Read more
Apple Tackles Distracted Driving With iOS 11...
One of the most important new features coming in iOS 11 is Do Not Disturb while driving, intended to help drivers stay more focused on the road. With Do Not Disturb while driving, your iPhone can... Read more
iMazing Mini for Mac: Free Automatic and Priv...
Geneva, Switzerland-based indie developer DigiDNA has released iMazing Mini, their free macOS utility designed to automatically back up iOS devices over any local Wi-Fi network. The app offers users... Read more
Clearance 2016 13-inch MacBook Airs, Apple re...
Apple dropped prices recently on Certified Refurbished 2016 13″ MacBook Airs, with models now available starting at $809. An Apple one-year warranty is included with each MacBook, and shipping is... Read more
9.7-inch 2017 iPads available for $299, save...
B&H Photo has 2017 9.7″ 32GB WiFi iPads on sale for $30 off MSRP for a limited time. Shipping is free, and pay sales tax in NY & NJ only: – 32GB iPad WiFi: $299, $30 off Read more

Jobs Board

Senior Payments Architect - *Apple* Pay - A...
Changing the world is all in a day's work at Apple . If you love innovation, here's your chance to make a career of it. You'll work hard. But the job comes with more Read more
Frameworks Engineering Manager, *Apple* Wat...
Frameworks Engineering Manager, Apple Watch Job Number: 41632321 Santa Clara Valley, California, United States Posted: Jun. 15, 2017 Weekly Hours: 40.00 Job Summary Read more
Manager, *Apple* Media Products - Apple Inc...
Job Summary The Apple Media Products Discovery, Fraud and Abuse team is responsible for protecting the integrity of Apple services. As a manager of the team, you Read more
*Apple* Watch, Accessories, Engineering Proj...
Job Summary Engineering Project Manager, Apple Watch Accessories. The Accessories group is looking for an Engineering Project Manager (EPM) to lead the design and Read more
Sr. Technical Writer - *Apple* Information...
Changing the world is all in a day's work at Apple . If you love innovation, here's your chance to make a career of it. You'll work hard. But the job comes with more Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.