Mac OS X Preferences Window II by Seth Willits
12-14-05




I haven't quite finished the splitter control yet, but in the mean time, I wrote a quick project showing how to construct a proper (as of 10.4) preferences window. New in this version as opposed to the ooold one I did several years ago, is mainly the toolbar items actually being able to be selected. Now, this ONLY works in Mac OS X 10.4. Yes, sorry guys and gals, but it wasn't in Carbon in 10.3 even though Cocoa could do it. The good news is it does gracefully fail! Your users will never know the difference except they won't actually see the selection on the item.



Setup
First off, we have a window with five toolbar items in a control array named TBPrefs (a control array is easier to work with in this case rather than five individual controls), and then on the window is a PagePanel with five pages on it. Each page is the "view" corresponding to the toolbar item at the same index.

When the window opens, images are assigned to the toolbar items (since they're loaded with masks from disk) and the default values for the different properties for the window and panel are assigned in the window open even, selecting the first preference view.

Sub Open()
  // Set Defaults
  PagePanel1.Value = 2
  TBPrefs(2).SelectItem
  me.Width = 474
  me.Height = 370
  me.Top = Screen(0).Height / 4
  me.Left = Screen(0).Width / 2 - me.Width / 2
End Sub
Sub Open()
  // Just Setting the Images of the ToolbarItems
  Select Case index
  Case kTBDebugger
    me.Image = LoadMaskedImage(prefsDebugger)
  Case kTBBuildProcess
    me.Image = LoadMaskedImage(prefsBuildProcess)
  Case kTBCodeEditor
    me.Image = LoadMaskedImage(prefsCodeEditor)
  Case kTBFormEditor
    me.Image = LoadMaskedImage(prefsFormEditor)
  Case kTBHelp
    me.Image = LoadMaskedImage(prefsHelp)
  end Select
End Sub


When and item is clicked on, it's selected with the call to me.SelectItem a method extension in the OSXPreferences module in the project.

Sub SelectItem(Extends item as ToolbarItem)
  Const kHIToolbarItemSelected = 128
  
  #if TargetCarbon
    Const Carbon = "CarbonLib"
  #elseif TargetMachO
    Const Carbon = "Carbon"
  #endif
  
  Declare Function HIToolbarItemChangeAttributes Lib Carbon (inToolbarItem as Integer,_
    inAttrsToSet as Integer, inAttrsToClear as Integer) as Integer
  
  dim err as integer
  err = HIToolbarItemChangeAttributes(item.Handle, kHIToolbarItemSelected, 0)
End Sub


Sub Action()
  // Select the ToolbarItem then the
  // PagePanel and Resize the Window
  me.SelectItem
  SelectPanel index
End Sub
Sub SelectPanel(index as Integer)
  // Using 4 (which means lock the top center
  // of the window and grow from there) isn't
  // the standard behavior of a preferences window
  // because ideally, your window should always
  // be the same width, but it does work and show
  // the options you have nicely, if you change
  // the width and heights of the panels
  
  Select Case index
  Case kTBDebugger
    SmoothResize self, 474, 200, 4
  Case kTBBuildProcess
    SmoothResize self, 474, 300, 4
  Case kTBCodeEditor
    SmoothResize self, 474, 370, 4
  Case kTBFormEditor
    SmoothResize self, 474, 400, 4
  Case kTBHelp
    SmoothResize self, 474, 350, 4
  end Select

  PagePanel1.Value = index
End Sub


Lastly, SelectPanel actually goes in and resizes the window to the appropriate eight (all of your panels should be the same width), and changes the page panel to the new page!


Finished
That's it. It's not very exciting, but it's a polish that I think ever Mac OS X app needs to have. Download the project.