Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
BasicDataBrowser.c
/* |
File: BasicDataBrowser.c |
Contains: Basic Data Browser sample, Carbon API |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
("Apple") in consideration of your agreement to the following terms, and your |
use, installation, modification or redistribution of this Apple software |
constitutes acceptance of these terms. If you do not agree with these terms, |
please do not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and subject |
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs |
copyrights in this original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or without |
modifications, in source and/or binary forms; provided that if you redistribute |
the Apple Software in its entirety and without modifications, you must retain |
this notice and the following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks or logos of |
Apple Computer, Inc. may be used to endorse or promote products derived from the |
Apple Software without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any patent rights that |
may be infringed by your derivative works or by other works in which the Apple |
Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Copyright © 2000-2003 Apple Computer, Inc., All Rights Reserved |
*/ |
#ifdef __APPLE_CC__ |
#include <Carbon/Carbon.h> |
#else |
#ifndef __CARBON__ |
#include <Carbon.h> |
#endif |
#endif |
// ANSI Headers |
#include <limits.h> |
// -------------------------------------------------------------------- |
// Globals |
enum { |
kFolder, |
kDocument, |
kFolderAlias, |
kTotalNumIcons, |
kSettingsDialog = 130, |
kCustomizeDialog = 129 |
}; |
enum { |
kNoDisjoint = 2, |
kDragSelect, |
kAlwaysExtend, |
kSelectOnlyOne, |
kResetSelection, |
kCommandToggles, |
kActiveItems, |
kFrameAndFocus, |
kVerticalScroll, |
kHorizontalScroll, |
kNoEmptySelection |
}; |
enum { |
kDisclosure = 1, |
kVarHeightRows, |
kExpandableRows, |
kPlainBackground, |
kFillHiliteStyle, |
kUseRelativeDates, |
kShowHeaderButtons |
}; |
enum { |
kCloseWindow = 'clos', |
kDBSettings = 'stng', |
kCustomizeView = 'cust', |
kShowPlacard = 'plac', |
kShowFrame = 'fram', |
kRevealItem = 'show', |
kSelectionFlags = 'flag' |
}; |
enum { |
kItemsPerContainer = 10, |
kMyCreator = 'DEMO', |
kMyDataBrowser = 'Brsr', |
kMyEventHandler = 'Evnt', |
kMyCustomizerID = ' ID ', |
kCheckboxColumn = 'cbox', |
kFlavorColumn = 'flvr', |
kColorColumn = 'colr', |
kIndexColumn = 'indx', |
kItemIDColumn = 'item', |
kIconOnlyColumn = 'icon', |
kDateTimeColumn = 'date', |
kPopupMenuColumn = 'menu', |
kProgressBarColumn = 'pbar', |
kSliderColumn = 'sldr' |
}; |
static MenuRef menu = NULL; |
static ControlRef placard = NULL; |
static UInt16 headerBtnHeight = 0; |
static IconRef icon[kTotalNumIcons] = {NULL}; |
enum { kBtnHeight = 20, kBtnWidth = 60, kScrollBarWidth = 16 }; |
#define Alias(itemID) (itemID == 44 || itemID == 486 || itemID == 509) |
#define Container(itemID) (!((itemID % 5) == 2 || itemID > 10000) && !Alias(itemID)) |
const DataBrowserTableViewColumnID columns[] = |
{ kCheckboxColumn, kFlavorColumn, kIconOnlyColumn, kColorColumn, kIndexColumn, |
kItemIDColumn, kDateTimeColumn, kSliderColumn, kProgressBarColumn, kPopupMenuColumn }; |
// -------------------------------------------------------------------- |
pascal void MyPlacardDrawProc(ControlRef, SInt16); |
static ControlUserPaneDrawUPP placardDrawProc = |
NewControlUserPaneDrawUPP(MyPlacardDrawProc); |
static void ConfigureDataBrowser(ControlRef); |
static void InstallDataBrowserCallbacks(ControlRef); |
static void CreateDataBrowser(WindowRef, ControlRef*); |
static void SetupGlobals(void); |
static void CleanupGlobals(void); |
static OSStatus InstallStandardMenuBar(Boolean); |
static ControlRef GetDataBrowserFromWindow(WindowRef); |
static bool SelectionFlagOn(ControlRef, DataBrowserSelectionFlags); |
OSStatus HandleDataBrowserCommand(ControlRef browser, HICommand command); |
OSStatus UpdateDataBrowserCommand(ControlRef browser, HICommand command); |
pascal OSStatus MyWindowEventHandler(EventHandlerCallRef, EventRef, void*); |
pascal OSStatus MyDialogEventHandler(EventHandlerCallRef, EventRef, void*); |
pascal OSStatus MyCommandEventHandler(EventHandlerCallRef, EventRef, void*); |
// -------------------------------------------------------------------- |
int main(void) |
{ |
WindowRef window = NULL; |
ControlRef browser = NULL; |
OSStatus err = noErr; |
Rect bounds = { 200, 200, 400, 600 }; |
EventTypeSpec windowEvents[] = { |
{ kEventClassCommand, kEventCommandProcess }, |
{ kEventClassCommand, kEventCommandUpdateStatus }, |
{ kEventClassWindow, kEventWindowClose }, |
{ kEventClassWindow, kEventWindowGetIdealSize }, |
{ kEventClassWindow, kEventWindowBoundsChanged }, |
{ kEventClassWindow, kEventWindowGetClickActivation }, |
{ kEventClassWindow, kEventWindowContextualMenuSelect } |
}; |
// Setup |
InitCursor(); |
SetupGlobals(); |
verify_noerr(InstallStandardMenuBar(true)); |
// Setup a window |
verify_noerr( |
CreateNewWindow( |
kDocumentWindowClass, |
kWindowInWindowMenuAttribute | |
kWindowStandardHandlerAttribute | |
kWindowStandardDocumentAttributes, &bounds, &window)); |
ControlRef rootControl; |
verify_noerr( |
CreateRootControl(window, &rootControl)); |
verify_noerr( |
SetAutomaticControlDragTrackingEnabledForWindow(window, true)); |
verify_noerr(InstallWindowEventHandler(window, |
NewEventHandlerUPP(MyWindowEventHandler), |
sizeof(windowEvents)/sizeof(EventTypeSpec), windowEvents, NULL, NULL)); |
verify_noerr( |
SetWindowTitleWithCFString(window, CFSTR("DataBrowser Demo"))); |
// Create the DataBrowser |
CreateDataBrowser(window, &browser); |
InstallDataBrowserCallbacks(browser); |
// Configure the DataBrowser |
ConfigureDataBrowser(browser); |
err = SetDataBrowserTarget(browser, 50); |
// Set the keyboard focus |
SetKeyboardFocus(window, browser, kControlDataBrowserPart); |
// Store DB as a window property |
SetWindowProperty(window, |
kMyCreator, kMyDataBrowser, |
sizeof(browser), &browser); |
// Show window & run |
ShowWindow(window); |
RunApplicationEventLoop(); |
CleanupGlobals(); |
return 0; |
} |
#pragma mark - |
#pragma mark ¥ Dialogs ¥ |
// -------------------------------------------------------------------- |
static void SetupControls(DialogRef dialog, UInt16 customizerID) |
{ |
ControlRef browser = |
GetDataBrowserFromWindow( |
GetDialogWindow(dialog)); |
const DialogItemIndex |
numItems = CountDITL(dialog); |
for (DialogItemIndex dialogItem = 0; |
dialogItem <= numItems; dialogItem++) |
{ |
Boolean controlValue = 0; |
ControlRef control = NULL; |
GetDialogItemAsControl( |
dialog, dialogItem, &control); |
// Set each control's reference |
SetControlReference(control, dialogItem); |
switch (customizerID) |
{ |
case kSettingsDialog: |
{ |
switch (dialogItem) |
{ |
case kActiveItems: |
{ GetDataBrowserActiveItems(browser, &controlValue); |
} break; |
case kFrameAndFocus: |
{ GetControlData(browser, kControlNoPart, |
kControlDataBrowserIncludesFrameAndFocusTag, |
sizeof(controlValue), &controlValue, NULL); |
} break; |
case kVerticalScroll: |
case kHorizontalScroll: |
{ Boolean *vBar = NULL, *hBar = NULL; |
switch (dialogItem) |
{ |
case kVerticalScroll: vBar = &controlValue; break; |
case kHorizontalScroll: hBar = &controlValue; break; |
} |
GetDataBrowserHasScrollBars(browser, hBar, vBar); |
} break; |
case kDragSelect: |
controlValue = SelectionFlagOn(browser, |
kDataBrowserDragSelect); break; |
case kSelectOnlyOne: |
controlValue = SelectionFlagOn(browser, |
kDataBrowserSelectOnlyOne); break; |
case kResetSelection: |
controlValue = SelectionFlagOn(browser, |
kDataBrowserResetSelection); break; |
case kCommandToggles: |
controlValue = SelectionFlagOn(browser, |
kDataBrowserCmdTogglesSelection); break; |
case kNoDisjoint: |
controlValue = SelectionFlagOn(browser, |
kDataBrowserNoDisjointSelection); break; |
case kAlwaysExtend: |
controlValue = SelectionFlagOn(browser, |
kDataBrowserAlwaysExtendSelection); break; |
} |
} break; |
case kCustomizeDialog: |
{ switch (dialogItem) |
{ |
case kVarHeightRows: |
{ GetDataBrowserTableViewGeometry( |
browser, NULL, &controlValue); |
if (!controlValue) |
{ |
GetDialogItemAsControl(dialog, |
kExpandableRows, &control); |
DeactivateControl(control); |
} |
} break; |
case kDisclosure: |
case kExpandableRows: |
{ Boolean expandableRows = false; |
DataBrowserPropertyID disclosureColumn = 0; |
GetDataBrowserListViewDisclosureColumn( |
browser, &disclosureColumn, &expandableRows); |
if (dialogItem != kDisclosure) |
controlValue = expandableRows; |
else if (disclosureColumn != 0) |
{ const UInt16 |
numColumns = sizeof(columns) / |
sizeof(DataBrowserPropertyID); |
for (UInt16 i = 0; i < numColumns; i++) |
if (disclosureColumn == columns[i]) |
{ controlValue = i + 3; break; } |
} |
} break; |
case kUseRelativeDates: |
{ DataBrowserPropertyFlags flags = 0; |
GetDataBrowserPropertyFlags( |
browser, kDateTimeColumn, &flags); |
controlValue = flags & kDataBrowserDateTimeRelative; |
} break; |
case kFillHiliteStyle: |
{ DataBrowserTableViewHiliteStyle hiliteStyle; |
GetDataBrowserTableViewHiliteStyle(browser, &hiliteStyle); |
controlValue = hiliteStyle; |
} break; |
case kShowHeaderButtons: |
{ GetDataBrowserListViewHeaderBtnHeight(browser, &headerBtnHeight); |
controlValue = headerBtnHeight != 0; |
} break; |
case kPlainBackground: |
{ GetDataBrowserListViewUsePlainBackground(browser, &controlValue); |
} break; |
} |
} break; |
} |
SetControlValue(control, controlValue); |
} |
} |
// -------------------------------------------------------------------- |
static DialogRef GetCustomizer(ControlRef browser, UInt16 customizerID) |
{ |
DialogRef customizer = NULL; |
if (browser != NULL) |
GetControlProperty(browser, kMyCreator, |
customizerID, sizeof(customizer), NULL, &customizer); |
return customizer; |
} |
// -------------------------------------------------------------------- |
static UInt16 GetCustomerID(WindowRef customizer) |
{ |
UInt16 customizerID = 0; |
GetWindowProperty( |
customizer, kMyCreator, kMyCustomizerID, |
sizeof(customizerID), NULL, &customizerID); |
return customizerID; |
} |
// -------------------------------------------------------------------- |
static void SetupCustomizer(ControlRef browser, UInt16 customizerID) |
{ |
WindowRef window = NULL; |
DialogRef customizer = |
GetCustomizer(browser, customizerID); |
const EventTypeSpec events[] = |
{ { kEventClassWindow, kEventWindowClose }, |
{ kEventClassControl, kEventControlHit }, |
{ kEventClassCommand, kEventCommandProcess}, |
{ kEventClassCommand, kEventCommandUpdateStatus} }; |
if (customizer == NULL) |
{ |
customizer = GetNewDialog( |
customizerID, NULL, (WindowRef)-1); |
window = GetDialogWindow(customizer); |
InstallStandardEventHandler( |
GetWindowEventTarget(window)); |
// Store dialog as a browser property |
SetControlProperty(browser, |
kMyCreator, customizerID, |
sizeof(customizer), &customizer); |
// Store browser as a window property |
SetWindowProperty(window, kMyCreator, |
kMyDataBrowser, sizeof(browser), &browser); |
// Setup initial control values |
SetupControls(customizer, customizerID); |
SetWindowClass(window, kFloatingWindowClass); |
// Store event handler as a window property |
EventHandlerUPP eventHandler = |
NewEventHandlerUPP(MyDialogEventHandler); |
verify_noerr(InstallWindowEventHandler(window, |
eventHandler, sizeof(events), events, NULL, NULL)); |
SetWindowProperty(window, kMyCreator, |
kMyEventHandler, sizeof(eventHandler), &eventHandler); |
// Store customizerID as a window property |
SetWindowProperty(window, kMyCreator, |
kMyCustomizerID, sizeof(customizerID), &customizerID); |
} |
else |
{ |
window = GetDialogWindow(customizer); |
ShowWindow(window); SelectWindow(window); |
} |
} |
#pragma mark - |
#pragma mark ¥ Utilities ¥ |
// -------------------------------------------------------------------- |
static void SetupGlobals(void) |
{ |
menu = ::GetMenu(200); ::InsertMenu(menu, -1); |
icon[kFolder] = NULL; |
::GetIconRef(kOnSystemDisk, |
kSystemIconsCreator, kGenericFolderIcon, &icon[kFolder]); |
icon[kDocument] = NULL; |
::GetIconRef(kOnSystemDisk, |
kSystemIconsCreator, kGenericDocumentIcon, &icon[kDocument]); |
icon[kFolderAlias] = NULL; |
IconRef aliasBadgeIcon = NULL; ::GetIconRef(kOnSystemDisk, |
kSystemIconsCreator, kAliasBadgeIcon, &aliasBadgeIcon); |
::CompositeIconRef(icon[kFolder], aliasBadgeIcon, &icon[kFolderAlias]); |
if (aliasBadgeIcon != NULL) ::ReleaseIconRef(aliasBadgeIcon); |
} |
// -------------------------------------------------------------------- |
static void CleanupGlobals(void) |
{ |
if (menu != NULL) |
{ |
::DeleteMenu(200); |
::DisposeMenu(menu); |
} |
for (UInt32 i = 0; i < kTotalNumIcons; i++) |
if (icon[i] != NULL) ::ReleaseIconRef(icon[i]); |
} |
// -------------------------------------------------------------------- |
static Boolean AppendString( |
Str255 ioDestString, ConstStr255Param inSourceString) |
{ |
SInt16 oldSize = ioDestString[0]; |
if (oldSize + inSourceString[0] <= 255) |
{ |
::BlockMoveData(&(inSourceString[1]), |
&(ioDestString[oldSize+1]), inSourceString[0]); |
ioDestString[0] += inSourceString[0]; |
return true; |
} |
return false; |
} |
// -------------------------------------------------------------------- |
static void GenerateString(DataBrowserItemID itemID, |
DataBrowserPropertyID property, StringPtr string) |
{ |
string[0] = 0; Str255 numString; |
::NumToString(itemID, numString); |
Boolean itemXProperty = property == kItemIDColumn || |
property == kDataBrowserItemSelfIdentityProperty; |
if (itemXProperty) AppendString(string, "\pItem "); |
AppendString(string, numString); |
if (!itemXProperty) |
{ |
numString[0] = sizeof(property); |
::BlockMoveData(&property, &(numString[1]), sizeof(property)); |
AppendString(string, "\p, "); AppendString(string, numString); |
} |
} |
// -------------------------------------------------------------------- |
static bool SelectionFlagOn( |
ControlRef browser, DataBrowserSelectionFlags flag) |
{ |
DataBrowserSelectionFlags flags; |
GetDataBrowserSelectionFlags(browser, &flags); |
return (flags & flag); |
} |
// -------------------------------------------------------------------- |
static void ActivateControl(DialogRef dialog, |
UInt8 dialogItem, UInt8 numItems, const UInt8 items[]) |
{ |
bool active = true; |
ControlRef control; |
for (UInt8 i = 0; active && i < numItems; i++) |
{ verify_noerr(GetDialogItemAsControl( |
dialog, items[i], &control)); |
active &= !GetControlValue(control); |
} |
verify_noerr(GetDialogItemAsControl( |
dialog, dialogItem, &control)); |
if (active) |
verify_noerr(ActivateControl(control)); |
else verify_noerr(DeactivateControl(control)); |
} |
// -------------------------------------------------------------------- |
static bool ToggleSelectionFlag(ControlRef browser, |
DataBrowserSelectionFlags flag, ControlRef control) |
{ |
DataBrowserSelectionFlags flags; |
GetDataBrowserSelectionFlags(browser, &flags); |
SetDataBrowserSelectionFlags(browser, flags ^ flag); |
// Make sure flag and representative |
SetControlValue(control, // control are synch'd |
(flags & flag) ? kThemeButtonOff : kThemeButtonOn); |
return !(flags & flag); |
} |
// -------------------------------------------------------------------- |
OSStatus InstallStandardMenuBar(Boolean draw) |
{ |
Handle menuBar; |
menuBar = GetNewMBar(128); |
if (menuBar) |
SetMenuBar(menuBar); |
if (draw) |
DrawMenuBar(); |
return noErr; |
} |
// -------------------------------------------------------------------- |
static ControlRef GetDataBrowserFromWindow(WindowRef window) |
{ |
ControlRef browser = NULL; |
if (window != NULL) |
GetWindowProperty(window, kMyCreator, |
kMyDataBrowser, sizeof(browser), NULL, &browser); |
return browser; |
} |
#pragma mark - |
#pragma mark ¥ Handlers ¥ |
// -------------------------------------------------------------------- |
static OSStatus HandleWindowCommand(EventRef inEvent) |
{ |
HICommand command; |
OSStatus result = eventNotHandledErr; |
GetEventParameter(inEvent, |
kEventParamDirectObject, typeHICommand, |
NULL, sizeof(command), NULL, &command); |
WindowRef window = GetUserFocusWindow(); |
check(command.attributes & kHICommandFromMenu); |
ControlRef browser = GetDataBrowserFromWindow(window); |
switch (GetEventKind(inEvent)) |
{ |
case kEventCommandProcess: |
{ |
if (command.commandID == kCloseWindow) |
{ |
result = noErr; |
EventRef event; CreateEvent( |
NULL, kEventClassWindow, |
kEventWindowClose, GetCurrentEventTime(), |
kEventAttributeUserEvent, &event); |
SetEventParameter( |
event, kEventParamDirectObject, |
typeWindowRef, sizeof(window), &window); |
SendEventToWindow(event, GetUserFocusWindow()); |
} |
else result = HandleDataBrowserCommand(browser, command); |
} break; |
case kEventCommandUpdateStatus: |
{ result = UpdateDataBrowserCommand(browser, command); |
} break; |
} |
return result; |
} |
// -------------------------------------------------------------------- |
static void HandleCustomizerControl(ControlRef control) |
{ |
WindowRef window = |
GetControlOwner(control); |
Boolean controlValue = |
GetControlValue(control); |
DialogItemIndex dialogItem = |
GetControlReference(control); |
ControlRef browser = |
GetDataBrowserFromWindow(window); |
switch (GetCustomerID(window)) |
{ |
case kCustomizeDialog: |
{ |
switch (dialogItem) |
{ |
case kDisclosure: |
case kExpandableRows: |
{ Boolean expandableRows = false; |
DataBrowserPropertyID disclosureColumn = 0; |
GetDataBrowserListViewDisclosureColumn( |
browser, &disclosureColumn, &expandableRows); |
if (dialogItem != kDisclosure) |
expandableRows = controlValue; |
else if (controlValue < 3) |
disclosureColumn = kDataBrowserItemNoProperty; |
else disclosureColumn = columns[controlValue-3]; |
SetDataBrowserListViewDisclosureColumn( |
browser, disclosureColumn, expandableRows); |
} break; |
case kShowHeaderButtons: |
{ SetDataBrowserListViewHeaderBtnHeight( |
browser, controlValue ? headerBtnHeight : 0); |
} break; |
case kFillHiliteStyle: |
{ SetDataBrowserTableViewHiliteStyle(browser, controlValue); |
} break; |
case kUseRelativeDates: |
{ DataBrowserPropertyFlags flags = 0; |
GetDataBrowserPropertyFlags( |
browser, kDateTimeColumn, &flags); |
SetDataBrowserPropertyFlags(browser, |
kDateTimeColumn, flags ^ kDataBrowserDateTimeRelative); |
} break; |
case kVarHeightRows: |
{ GetDataBrowserTableViewGeometry(browser, NULL, &controlValue); |
SetDataBrowserTableViewGeometry(browser, true, !controlValue); |
SetControlValue(control, !controlValue); |
GetDialogItemAsControl( |
GetDialogFromWindow( |
GetControlOwner(control)), |
kExpandableRows, &control); |
if (!controlValue) |
ActivateControl(control); |
else DeactivateControl(control); |
} break; |
case kPlainBackground: |
{ SetDataBrowserListViewUsePlainBackground(browser, controlValue); |
} break; |
} |
} break; |
case kSettingsDialog: |
{ |
const DialogRef dialog = |
GetDialogFromWindow(window); |
switch (dialogItem) |
{ |
case kFrameAndFocus: |
{ SetControlData(browser, kControlNoPart, |
kControlDataBrowserIncludesFrameAndFocusTag, |
sizeof(controlValue), &controlValue); |
} break; |
case kActiveItems: |
{ SetDataBrowserActiveItems(browser, controlValue); |
} break; |
case kVerticalScroll: |
case kHorizontalScroll: |
{ Boolean vBar, hBar; |
GetDataBrowserHasScrollBars(browser, &hBar, &vBar); |
switch (dialogItem) |
{ |
case kVerticalScroll: vBar = !vBar; break; |
case kHorizontalScroll: hBar = !hBar; break; |
} |
SetDataBrowserHasScrollBars(browser, hBar, vBar); |
if (hBar || vBar) |
{ Rect sInset = { 0, 0, 0, 0 }; |
GetDataBrowserScrollBarInset(browser, &sInset); |
if (hBar) sInset.right = kScrollBarWidth - 1; |
if (vBar) sInset.bottom = kScrollBarWidth - 1; |
SetDataBrowserScrollBarInset(browser, &sInset); |
} |
} break; |
case kDragSelect: |
{ ToggleSelectionFlag(browser, kDataBrowserDragSelect, control); |
} break; |
case kSelectOnlyOne: |
{ ToggleSelectionFlag(browser, kDataBrowserSelectOnlyOne, control); |
} break; |
case kResetSelection: |
{ ToggleSelectionFlag(browser, kDataBrowserResetSelection, control); |
} break; |
case kCommandToggles: |
{ ToggleSelectionFlag(browser, kDataBrowserCmdTogglesSelection, control); |
} break; |
case kNoDisjoint: |
{ ToggleSelectionFlag(browser, kDataBrowserNoDisjointSelection, control); |
} break; |
case kAlwaysExtend: |
{ ToggleSelectionFlag(browser, kDataBrowserAlwaysExtendSelection, control); |
} break; |
/* case kNoEmptySelection: |
{ ToggleSelectionFlag(browser, kDataBrowserNeverEmptySelectionSet, control); |
} break; */ |
} |
switch (dialogItem) |
{ |
case kNoDisjoint: |
case kSelectOnlyOne: |
{ |
const UInt8 dragSelectOverrides[] = |
{ kNoDisjoint, kSelectOnlyOne }; |
ActivateControl(dialog, kDragSelect, |
sizeof(dragSelectOverrides), dragSelectOverrides); |
} require_quiet(dialogItem == kSelectOnlyOne, kCommandToggles); |
case kResetSelection: |
{ |
const UInt8 alwaysExtendOverrides[] = |
{ kSelectOnlyOne, kResetSelection }; |
ActivateControl(dialog, kAlwaysExtend, |
sizeof(alwaysExtendOverrides), alwaysExtendOverrides); |
} |
kCommandToggles: |
case kCommandToggles: |
case kNoEmptySelection: |
// kCommandToggles is mutated by the others |
{ ControlRef cmdTogglesCntrl; |
verify_noerr(GetDialogItemAsControl( |
dialog, kCommandToggles, &cmdTogglesCntrl)); |
if (GetControlValue(cmdTogglesCntrl)) |
{ |
ThemeButtonValue value = kThemeButtonOn; |
const UInt8 overrides[] = { kNoDisjoint, |
kSelectOnlyOne, kResetSelection, kNoEmptySelection }; |
for (UInt8 i = 0; |
i < sizeof(overrides) && |
value == kThemeButtonOn; i++) |
{ |
verify_noerr(GetDialogItemAsControl( |
dialog, overrides[i], &control)); |
if (GetControlValue(control)) |
value = kThemeButtonMixed; |
} |
SetControlValue(cmdTogglesCntrl, value); |
} |
} break; |
} |
} break; |
} |
} |
// -------------------------------------------------------------------- |
OSStatus HandleDataBrowserCommand(ControlRef browser, HICommand command) |
{ |
OSStatus result = noErr; |
switch (command.commandID) |
{ |
default: |
{ result = eventNotHandledErr; |
} break; |
case kShowPlacard: |
{ Rect sBarInset, placardBounds = { 0 }; |
GetDataBrowserScrollBarInset(browser, &sBarInset); |
if (placard != NULL) |
{ GetControlBounds( |
placard, &placardBounds); |
DisposeControl(placard); placard = NULL; |
sBarInset.left -= placardBounds.right - placardBounds.left; |
} |
else |
{ GetControlBounds(browser, &placardBounds); |
placardBounds.top = placardBounds.bottom - 16; |
placardBounds.right = placardBounds.left + 100; |
verify_noerr(CreateUserPaneControl( |
GetControlOwner(browser), &placardBounds, 0, &placard)); |
SetControlVisibility(placard, true, true); |
SetControlReference(placard, (long)browser); |
verify_noerr(EmbedControl(placard, browser)); |
sBarInset.left += placardBounds.right - placardBounds.left; |
ControlUserPaneDrawUPP drawProc = placardDrawProc; |
verify_noerr(SetControlData(placard, kControlNoPart, |
kControlUserPaneDrawProcTag, sizeof(drawProc), &drawProc)); |
} |
verify_noerr(SetDataBrowserScrollBarInset(browser, &sBarInset)); |
} break; |
/* case kHICommandCut: |
case kHICommandUndo: |
case kHICommandRedo: |
case kHICommandCopy: |
case kHICommandPaste: |
case kHICommandClear: |
case kHICommandSelectAll: |
{ ExecuteDataBrowserEditCommand( |
browser, command.commandID); |
} break; */ |
case kDataBrowserListView: |
case kDataBrowserColumnView: |
{ DataBrowserViewStyle view; |
GetDataBrowserViewStyle(browser, &view); |
if (view != command.commandID) |
{ |
SetDataBrowserViewStyle( |
browser, command.commandID); |
ConfigureDataBrowser(browser); |
} |
} break; |
case kDBSettings: |
{ SetupCustomizer(browser, kSettingsDialog); |
} break; |
case kCustomizeView: |
{ SetupCustomizer(browser, kCustomizeDialog); |
} break; |
} |
return result; |
} |
// -------------------------------------------------------------------- |
OSStatus UpdateDataBrowserCommand(ControlRef browser, HICommand command) |
{ |
OSStatus result = noErr; |
bool commandIsEnabled = true; |
switch (command.commandID) |
{ |
default: |
{ result = eventNotHandledErr; |
} break; |
case kShowPlacard: |
{ CheckMenuItem(command.menu.menuRef, |
command.menu.menuItemIndex, placard != NULL); |
} break; |
/* case kHICommandCut: |
case kHICommandUndo: |
case kHICommandRedo: |
case kHICommandCopy: |
case kHICommandPaste: |
case kHICommandClear: |
case kHICommandSelectAll: |
{ commandIsEnabled = |
EnableDataBrowserEditCommand( |
browser, command.commandID); |
} break; */ |
case kCustomizeView: |
{ DataBrowserViewStyle viewStyle; |
::GetDataBrowserViewStyle(browser, &viewStyle); |
commandIsEnabled = (viewStyle == kDataBrowserListView); |
} break; |
} |
if (result == noErr) |
{ |
if (commandIsEnabled) |
EnableMenuCommand(command.menu.menuRef, command.commandID); |
else DisableMenuCommand(command.menu.menuRef, command.commandID); |
} |
return result; |
} |
#pragma mark - |
#pragma mark ¥ DB Callbacks ¥ |
// -------------------------------------------------------------------- |
static pascal Boolean MyAcceptDrag(ControlRef browser, |
DragReference theDrag, DataBrowserItemID itemID) |
{ |
bool accept = Container(itemID); |
SInt16 modifiers = 0; |
ThemeCursor cursor = kThemeArrowCursor; |
::GetDragModifiers(theDrag, &modifiers, NULL, NULL); |
switch (modifiers & ~btnState) // Filter out btnState (on for drop) |
{ |
case cmdKey: |
{ DataBrowserItemID target = kDataBrowserNoItem; |
::GetDataBrowserTarget(browser, &target); |
if (itemID != target) accept = false; |
} break; |
case optionKey: |
{ cursor = kThemeCopyArrowCursor; |
} break; |
case cmdKey | optionKey: |
{ cursor = kThemeAliasArrowCursor; |
} break; |
} |
::SetThemeCursor(cursor); |
return accept; |
} |
// -------------------------------------------------------------------- |
static pascal Boolean MyReceiveDrag(ControlRef browser, |
DragReference theDrag, DataBrowserItemID itemID) |
{ |
DataBrowserItemState itemState = 0L; |
if (itemID == kDataBrowserNoItem) |
itemState = kDataBrowserContainerIsOpen; |
else ::GetDataBrowserItemState(browser, itemID, &itemState); |
if (true || itemState & kDataBrowserContainerIsOpen) |
{ |
UInt16 numItems; ::CountDragItems(theDrag, &numItems); |
for (UInt32 i = 1; i <= numItems; i++) |
{ |
ItemReference theItemRef; |
DataBrowserItemID draggedItem; |
Size dataSize = sizeof(draggedItem); |
::GetDragItemReferenceNumber(theDrag, i, &theItemRef); |
::GetFlavorData(theDrag, theItemRef, typeUInt32, &draggedItem, &dataSize, 0); |
::RemoveDataBrowserItems(browser, kDataBrowserNoItem, |
1, &draggedItem, kDataBrowserItemNoProperty); |
::AddDataBrowserItems(browser, itemID, |
1, &draggedItem, kDataBrowserItemNoProperty); |
} |
} |
/* else |
{ |
AlertStdAlertParamRec alertParameters; |
alertParameters.movable = true; |
alertParameters.helpButton = false; |
alertParameters.filterProc = TEventDispatcher::ModalFilter(); |
alertParameters.defaultText = (StringPtr)kAlertDefaultOKText; |
alertParameters.cancelText = NULL; |
alertParameters.otherText = NULL; |
alertParameters.defaultButton = kAlertStdAlertOKButton; |
alertParameters.cancelButton = 0; |
alertParameters.position = kWindowDefaultPosition; |
SInt16 itemHit; |
TPascalString theString("\pDrag received in "); |
if (itemID != 0L) |
{ |
Str255 tempString; |
::NumToString(itemID, tempString); |
::AppendToString(theString, "\pItem "); |
::AppendToString(theString, tempString); |
} |
else ::AppendToString(theString, "\plist"); |
::StandardAlert(kAlertPlainAlert, theString, NULL, &alertParameters, &itemHit); |
} */ |
return true; |
} |
// -------------------------------------------------------------------- |
static pascal Boolean MyAddDragItem(ControlRef browser, |
DragReference theDrag, DataBrowserItemID itemID, ItemReference* itemRef) |
{ |
#pragma unused (browser) |
Str255 string; |
::GetDragItemReferenceNumber(theDrag, 0, itemRef); |
::GenerateString(itemID, 'col4', string); ::AppendString(string, "\p\n"); |
::AddDragItemFlavor(theDrag, *itemRef, 'TEXT', &(string[1]), string[0], 0); |
::AddDragItemFlavor(theDrag, *itemRef, typeUInt32, &itemID, sizeof(itemID), 0); |
return true; |
} |
// -------------------------------------------------------------------- |
static pascal OSStatus MyGetSetItemData(ControlRef browser, |
DataBrowserItemID itemID, DataBrowserPropertyID property, |
DataBrowserItemDataRef itemData, Boolean changeValue) |
{ |
#pragma unused (browser) |
Str255 pascalString; |
OSStatus err = noErr; |
if (!changeValue) switch (property) |
{ |
case kCheckboxColumn: |
if ((itemID % 5) == 2) |
{ err = ::SetDataBrowserItemDataButtonValue(itemData, kThemeButtonOn); |
err = ::SetDataBrowserItemDataDrawState(itemData, kThemeStateInactive); |
} |
break; |
case kFlavorColumn: |
{ ::GetIndString(pascalString, 128, itemID % 5 + 1); |
CFStringRef text = ::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), pascalString, kCFStringEncodingMacRoman); |
err = ::SetDataBrowserItemDataText(itemData, text); ::CFRelease(text); |
} // Fall through to kIconOnlyColumn |
case kIconOnlyColumn: |
{ err = ::SetDataBrowserItemDataIcon(itemData, Container(itemID) ? |
icon[kFolder] : Alias(itemID) ? icon[kFolderAlias] : icon[kDocument]); |
} break; |
case kColorColumn: |
{ ::GetIndString(pascalString, 129, itemID % 5 + 1); |
CFStringRef text = ::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), pascalString, kCFStringEncodingMacRoman); |
err = ::SetDataBrowserItemDataText(itemData, text); ::CFRelease(text); |
} break; |
case kIndexColumn: |
{ SInt16 mod5 = itemID % 5; |
if (mod5 == 0) mod5 = 5; |
::NumToString(mod5, pascalString); |
CFStringRef text = ::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), pascalString, kCFStringEncodingMacRoman); |
err = ::SetDataBrowserItemDataText(itemData, text); ::CFRelease(text); |
} break; |
case kDateTimeColumn: |
{ LongDateCvt dt; |
dt.hl.lHigh = 0; |
GetDateTime( &dt.hl.lLow ); |
dt.hl.lLow -= (((itemID - 1) % 10) * 28800 ); |
err = ::SetDataBrowserItemDataLongDateTime(itemData, &dt.c ); |
} break; |
case kSliderColumn: |
case kProgressBarColumn: |
{ err = ::SetDataBrowserItemDataValue(itemData, (itemID % 5) * 20); |
} break; |
case kPopupMenuColumn: |
{ if ((itemID % 5 + 1) != 1) |
{ err = ::SetDataBrowserItemDataMenuRef(itemData, menu); |
} |
err = ::SetDataBrowserItemDataValue(itemData, itemID % 5 + 1); |
} break; |
case kDataBrowserItemSelfIdentityProperty: |
{ err = ::SetDataBrowserItemDataIcon(itemData, Container(itemID) ? |
icon[kFolder] : Alias(itemID) ? icon[kFolderAlias] : icon[kDocument]); |
} // Fall through to text generator |
case kItemIDColumn: |
{ GenerateString(itemID, property, pascalString); |
CFStringRef text = ::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), pascalString, kCFStringEncodingMacRoman); |
err = ::SetDataBrowserItemDataText(itemData, text); ::CFRelease(text); |
} break; |
case kDataBrowserItemIsActiveProperty: |
if ((itemID % 5) == 3) |
{ err = ::SetDataBrowserItemDataBooleanValue(itemData, false); |
} break; |
case kDataBrowserItemIsEditableProperty: |
{ err = ::SetDataBrowserItemDataBooleanValue(itemData, true); |
} break; |
case kDataBrowserItemIsContainerProperty: |
{ err = ::SetDataBrowserItemDataBooleanValue(itemData, Container(itemID)); |
} break; |
case kDataBrowserContainerAliasIDProperty: |
if (Alias(itemID)) |
{ err = ::SetDataBrowserItemDataItemID(itemData, 4); |
} break; |
case kDataBrowserItemParentContainerProperty: |
{ err = ::SetDataBrowserItemDataItemID(itemData, (itemID-1) / kItemsPerContainer); |
} break; |
default: |
{ err = errDataBrowserPropertyNotSupported; |
} break; |
} |
else err = errDataBrowserPropertyNotSupported; |
return err; |
} |
// --------------------------------------------------------------------------------- |
static pascal Boolean MyItemComparison( |
ControlRef browser, DataBrowserItemID itemOneID, |
DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty) |
{ |
SInt16 compareResult = 0; |
#define Compare(i1,i2,p) MyItemComparison(browser,i1,i2,p) |
switch (sortProperty) |
{ |
case kFlavorColumn: |
{ Str255 s1, s2; |
::GetIndString(s1, 128, itemOneID % 5 + 1); |
::GetIndString(s2, 128, itemTwoID % 5 + 1); |
compareResult = ::CompareString(s1, s2, NULL); |
if (compareResult < 0) return true; |
else if (compareResult > 0) return false; |
else return Compare(itemOneID, itemTwoID, '????'); |
} break; |
case kColorColumn: |
{ Str255 s1, s2; |
::GetIndString(s1, 129, itemOneID % 5 + 1); |
::GetIndString(s2, 129, itemTwoID % 5 + 1); |
compareResult = ::CompareString(s1, s2, NULL); |
if (compareResult < 0) return true; |
else if (compareResult > 0) return false; |
else return Compare(itemOneID, itemTwoID, 'foo '); |
} break; |
case kProgressBarColumn: |
{ SInt32 val1 = (itemOneID % 5) * 20; |
SInt32 val2 = (itemTwoID % 5) * 20; |
if (val1 < val2) return true; |
else if (val1 > val2) return false; |
else return Compare(itemOneID, itemTwoID, '????'); |
} break; |
default: |
{ return itemOneID < itemTwoID; |
} break; |
} |
} |
// -------------------------------------------------------------------- |
static pascal void MyItemNotification( |
ControlRef browser, |
DataBrowserItemID itemID, |
DataBrowserItemNotification message) |
{ |
switch (message) |
{ |
/* case kDataBrowserItemSelected: |
{ Handle handle = NewHandle(0); |
GetDataBrowserItems(browser, |
kDataBrowserNoItem, true, kDataBrowserItemIsSelected, handle); |
UInt32 numSelectedItems = GetHandleSize(handle)/sizeof(DataBrowserItemID); |
} break; */ |
case kDataBrowserContainerOpened: |
{ // Generate some valid itemIDs |
DataBrowserItemID myItems[kItemsPerContainer]; |
for (UInt32 i = 0; i < kItemsPerContainer; i++) |
myItems[i] = itemID * kItemsPerContainer + i + 1; |
AddDataBrowserItems(browser, itemID, kItemsPerContainer, myItems, kIndexColumn); |
{ // Set up variable height rows |
Boolean variableHeightRows; |
GetDataBrowserTableViewGeometry( |
browser, NULL, &variableHeightRows); |
if (variableHeightRows) |
for (UInt16 i = 0; i < kItemsPerContainer; i++) |
SetDataBrowserTableViewItemRowHeight( |
browser, myItems[i], 20 + (myItems[i] - 1) % 10 * 3); |
} |
} break; |
/* case kDataBrowserSelectionSetChanged: |
{ ::DrawOneControl(fPlacard); |
} break; */ |
} |
} |
// -------------------------------------------------------------------- |
static pascal void MyItemHelpContent( |
ControlRef browser, DataBrowserItemID item, |
DataBrowserPropertyID property, HMContentRequest inRequest, |
HMContentProvidedType *outContentProvided, HMHelpContentPtr ioHelpContent) |
{ |
#pragma unused (browser) |
bool helpContentProperty = (property == kFlavorColumn) || |
(property == kDataBrowserItemSelfIdentityProperty); |
if (inRequest == kHMSupplyContent && item != kDataBrowserNoItem && helpContentProperty) |
{ |
*outContentProvided = kHMContentProvided; |
ioHelpContent->content[kHMMaximumContentIndex].contentType = kHMStringResContent; |
ioHelpContent->content[kHMMaximumContentIndex].u.tagStringRes.hmmIndex = item % 5 + 1; |
ioHelpContent->content[kHMMaximumContentIndex].u.tagStringRes.hmmResID = 130; |
} |
} |
// -------------------------------------------------------------------- |
static pascal void MyGetContextualMenu( |
ControlRef browser, MenuRef* contextualMenu, UInt32 *helpType, |
CFStringRef* helpItemString, AEDesc *selection) |
{ |
#pragma unused (browser, selection) |
*helpItemString = ::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), "\pTesting 1-2-3", kCFStringEncodingMacRoman); |
*helpType = kCMHelpItemOtherHelp; |
if (menu != NULL) |
*contextualMenu = menu; |
else |
{ |
*contextualMenu = ::GetMenu(200); |
::InsertMenu(*contextualMenu, -1); |
} |
} |
// -------------------------------------------------------------------- |
static pascal void MySelectContextualMenu( |
ControlRef browser, MenuRef contextualMenu, |
UInt32 selectionType, SInt16 menuID, MenuItemIndex menuItem) |
{ |
#pragma unused (browser, selectionType, menuID, menuItem) |
if (menu == NULL) |
{ |
::DeleteMenu(200); |
::DisposeMenu(contextualMenu); |
} |
} |
#pragma mark - |
#pragma mark ¥ Window Callbacks ¥ |
// -------------------------------------------------------------------- |
pascal void MyPlacardDrawProc(ControlRef control, SInt16) |
{ |
ControlRef browser = (ControlRef) |
GetControlReference(control); |
const Str255 text = "\p Items Selected"; |
Str255 placardString; |
UInt32 numSelectedItems; |
GetDataBrowserItemCount(browser, kDataBrowserNoItem, |
true, kDataBrowserItemIsSelected, &numSelectedItems); |
NumToString(numSelectedItems, placardString); |
BlockMoveData(&(text[1]), |
&(placardString[placardString[0]+1]), text[0]); |
placardString[0] += text[0]; |
Rect bounds; DrawThemePlacard(GetControlBounds(control, &bounds), |
IsControlActive(control) ? kThemeStateActive : kThemeStateInactive); |
SetThemeTextColor( |
IsControlActive(control) ? |
kThemeTextColorPlacardActive : |
kThemeTextColorPlacardInactive, 8, true); |
UseThemeFont(kThemeSmallSystemFont, smSystemScript); |
MoveTo(bounds.left + (bounds.right - bounds.left)/2 - |
::StringWidth(placardString)/2, bounds.bottom - 4); |
DrawString(placardString); |
} |
// -------------------------------------------------------------------- |
pascal OSStatus MyDialogEventHandler( |
EventHandlerCallRef, EventRef inEvent, void*) |
{ |
OSStatus result = eventNotHandledErr; |
switch (GetEventClass(inEvent)) |
{ |
case kEventClassCommand: |
{ result = HandleWindowCommand(inEvent); |
} break; |
case kEventClassControl: |
{ result = noErr; |
ControlRef control = NULL; |
GetEventParameter(inEvent, |
kEventParamDirectObject, typeControlRef, |
NULL, sizeof(control), NULL, &control); |
HandleCustomizerControl(control); |
} break; |
case kEventClassWindow: |
{ WindowRef window = NULL; |
GetEventParameter(inEvent, |
kEventParamDirectObject, typeWindowRef, |
NULL, sizeof(window), NULL, &window); |
DialogRef dialog = GetDialogFromWindow(window); |
switch (GetEventKind(inEvent)) |
{ |
case kEventWindowClose: |
{ result = noErr; |
ControlRef browser = |
GetDataBrowserFromWindow(window); |
UInt16 customizerID = GetCustomerID(window); |
EventHandlerUPP eventHandler = NULL; |
GetWindowProperty( |
window, kMyCreator, kMyEventHandler, |
sizeof(eventHandler), NULL, &eventHandler); |
DisposeEventHandlerUPP(eventHandler); |
DisposeDialog(dialog); dialog = NULL; |
SetControlProperty(browser, kMyCreator, |
customizerID, sizeof(dialog), &dialog); |
} break; |
} |
} |
} |
return result; |
} |
// -------------------------------------------------------------------- |
pascal OSStatus MyWindowEventHandler( |
EventHandlerCallRef, EventRef inEvent, void*) |
{ |
OSStatus result = noErr; |
switch (GetEventClass(inEvent)) |
{ |
default: |
{ result = eventNotHandledErr; |
} break; |
case kEventClassCommand: |
{ result = HandleWindowCommand(inEvent); |
} break; |
case kEventClassWindow: |
{ |
WindowRef window = NULL; |
GetEventParameter(inEvent, |
kEventParamDirectObject, typeWindowRef, |
NULL, sizeof(window), NULL, &window); |
switch (GetEventKind(inEvent)) |
{ |
default: |
{ result = eventNotHandledErr; |
} break; |
case kEventWindowClose: |
{ |
ControlRef browser = |
GetDataBrowserFromWindow(window); |
const UInt16 IDs[] = { |
kSettingsDialog, kCustomizeDialog }; |
for (UInt16 i = 0; i < sizeof(IDs); i++) |
{ |
const UInt16 ID = IDs[i]; |
DialogRef customizer = |
GetCustomizer(browser, ID); |
if (customizer != NULL) |
DisposeDialog(customizer); |
} |
DisposeWindow(window); |
QuitApplicationEventLoop(); |
} break; |
case kEventWindowBoundsChanged: |
{ ControlRef browser = GetDataBrowserFromWindow(window); |
Rect bounds; |
OSStatus theErr; |
UInt32 attributes = 0; |
GetPortBounds(GetWindowPort(window), &bounds); |
// Get the attributes from the event, which will tell us why the bounds changed |
theErr = GetEventParameter(inEvent, kEventParamAttributes, typeUInt32, nil, |
sizeof(attributes), nil, &attributes); |
check(theErr == noErr); |
if ((attributes & kWindowBoundsChangeUserDrag) == 0) // they are NOT dragging the window |
SizeControl(browser, bounds.right - bounds.left, bounds.bottom - bounds.top); |
} break; |
#if defined(typeQDPoint) |
case kEventWindowGetIdealSize: |
{ SInt16 baseLine = 0; |
Rect bestRect = { 0 }; |
Point idealDimensions = { 0 }; |
GetBestControlRect( |
GetDataBrowserFromWindow(window), &bestRect, &baseLine); |
SetEventParameter(inEvent, kEventParamDimensions, |
typeQDPoint, sizeof(idealDimensions), &idealDimensions); |
} break; |
case kEventWindowGetClickActivation: |
{ Point mousePt; UInt32 modifiers; |
ClickActivationResult activation; |
GetEventParameter(inEvent, |
kEventParamMouseLocation, typeQDPoint, |
NULL, sizeof(mousePt), NULL, &mousePt); |
GetEventParameter(inEvent, |
kEventParamKeyModifiers, typeUInt32, |
NULL, sizeof(modifiers), NULL, &modifiers); |
GetControlClickActivation( |
GetDataBrowserFromWindow(window), |
mousePt, modifiers, &activation); |
SetEventParameter(inEvent, kEventParamClickActivation, |
typeClickActivationResult, sizeof(activation), &activation); |
} break; |
#endif // defined(typeQDPoint) |
case kEventWindowContextualMenuSelect: |
{ |
} break; |
} |
} break; |
} |
return result; |
} |
#pragma mark - |
#pragma mark ¥ DataBrowser Setup ¥ |
// -------------------------------------------------------------------- |
static void CreateDataBrowser(WindowRef window, ControlRef *browser) |
{ |
Rect bounds; |
Boolean frameAndFocus = false; |
// Create a DataBrowser |
bounds.top = bounds.left = 0; |
bounds.right = 400; bounds.bottom = 200; |
verify_noerr(CreateDataBrowserControl(window, |
&bounds, kDataBrowserListView, browser)); |
// Turn off DB's focus frame |
verify_noerr(SetControlData( |
*browser, kControlNoPart, |
kControlDataBrowserIncludesFrameAndFocusTag, |
sizeof(frameAndFocus), &frameAndFocus)); |
} |
// -------------------------------------------------------------------- |
static void ConfigureDataBrowser(ControlRef browser) |
{ |
#ifndef kDataBrowserListViewAppendColumn |
#define kDataBrowserListViewAppendColumn ULONG_MAX |
#endif |
DataBrowserViewStyle viewStyle; |
::GetDataBrowserViewStyle(browser, &viewStyle); |
Rect insetRect; |
::GetDataBrowserScrollBarInset(browser, &insetRect); |
insetRect.right = kScrollBarWidth - 1; |
::SetDataBrowserScrollBarInset(browser, &insetRect); |
switch (viewStyle) |
{ |
case kDataBrowserListView: |
{ DataBrowserListViewColumnDesc columnDesc; |
columnDesc.headerBtnDesc.titleOffset = 0; |
columnDesc.headerBtnDesc.version = |
kDataBrowserListViewLatestHeaderDesc; |
columnDesc.headerBtnDesc.btnFontStyle.flags = |
kControlUseFontMask | kControlUseJustMask; |
columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlNoContent; |
::GetIconRef(kOnSystemDisk, kSystemIconsCreator, kGenericFolderIcon, |
&columnDesc.headerBtnDesc.btnContentInfo.u.iconRef); |
// Add the checkbox column |
columnDesc.propertyDesc.propertyID = kCheckboxColumn; |
columnDesc.propertyDesc.propertyType = kDataBrowserCheckboxType; |
columnDesc.propertyDesc.propertyFlags = kDataBrowserPropertyIsMutable | |
kDataBrowserDefaultPropertyFlags; |
columnDesc.headerBtnDesc.minimumWidth = 30; |
columnDesc.headerBtnDesc.maximumWidth = 30; |
columnDesc.headerBtnDesc.btnFontStyle.just = teCenter; |
columnDesc.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont; |
columnDesc.headerBtnDesc.btnFontStyle.style = normal; |
columnDesc.headerBtnDesc.titleString = ::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), "\p", kCFStringEncodingMacRoman); |
::AddDataBrowserListViewColumn(browser, |
&columnDesc, kDataBrowserListViewAppendColumn), |
// Add the Flavor column |
columnDesc.propertyDesc.propertyID = kFlavorColumn; |
columnDesc.propertyDesc.propertyType = kDataBrowserIconAndTextType; |
columnDesc.propertyDesc.propertyFlags = kDataBrowserPropertyIsMutable | |
kDataBrowserListViewSelectionColumn | |
kDataBrowserListViewDefaultColumnFlags; |
columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentIconRef; |
columnDesc.headerBtnDesc.minimumWidth = 0; |
columnDesc.headerBtnDesc.maximumWidth = 280; |
columnDesc.headerBtnDesc.btnFontStyle.just = teFlushDefault; |
columnDesc.headerBtnDesc.titleString =::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), "\pFlavor", kCFStringEncodingMacRoman); |
::AddDataBrowserListViewColumn(browser, |
&columnDesc, kDataBrowserListViewAppendColumn); |
// Add the icon column |
columnDesc.propertyDesc.propertyID = kIconOnlyColumn; |
columnDesc.propertyDesc.propertyType = kDataBrowserIconType; |
columnDesc.propertyDesc.propertyFlags = kDataBrowserListViewSelectionColumn | |
kDataBrowserListViewDefaultColumnFlags; |
columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentIconRef; |
columnDesc.headerBtnDesc.minimumWidth = 0; |
columnDesc.headerBtnDesc.maximumWidth = 100; |
columnDesc.headerBtnDesc.btnFontStyle.just = teCenter; |
columnDesc.headerBtnDesc.titleString = NULL; |
::AddDataBrowserListViewColumn(browser, |
&columnDesc, kDataBrowserListViewAppendColumn); |
// Add the Index column |
columnDesc.headerBtnDesc.maximumWidth = 120; |
columnDesc.propertyDesc.propertyID = kIndexColumn; |
columnDesc.propertyDesc.propertyType = kDataBrowserTextType; |
columnDesc.headerBtnDesc.btnFontStyle.just = teCenter; |
columnDesc.headerBtnDesc.titleString = ::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), "\pIndex", kCFStringEncodingMacRoman); |
::AddDataBrowserListViewColumn(browser, |
&columnDesc, kDataBrowserListViewAppendColumn); |
// Add the Color column |
columnDesc.propertyDesc.propertyID = kColorColumn; |
columnDesc.headerBtnDesc.btnFontStyle.just = teFlushRight; |
columnDesc.propertyDesc.propertyFlags = kDataBrowserPropertyIsMutable | |
kDataBrowserListViewDefaultColumnFlags; |
columnDesc.headerBtnDesc.titleString = ::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), "\pColor", kCFStringEncodingMacRoman); |
::AddDataBrowserListViewColumn(browser, |
&columnDesc, kDataBrowserListViewAppendColumn); |
// Add the ItemID column |
columnDesc.propertyDesc.propertyID = kItemIDColumn; |
columnDesc.propertyDesc.propertyFlags = kDataBrowserListViewDefaultColumnFlags; |
columnDesc.headerBtnDesc.btnFontStyle.just = teFlushDefault; |
columnDesc.headerBtnDesc.titleString = ::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), "\pItemID", kCFStringEncodingMacRoman); |
::AddDataBrowserListViewColumn(browser, |
&columnDesc, kDataBrowserListViewAppendColumn); |
/* // Add the slider column |
columnDesc.propertyDesc.propertyID = kSliderColumn; |
columnDesc.headerBtnDesc.btnFontStyle.just = teCenter; |
columnDesc.propertyDesc.propertyType = kDataBrowserSliderType; |
columnDesc.propertyDesc.propertyFlags = kDataBrowserSliderPlainThumb | |
kDataBrowserPropertyIsMutable | |
kDataBrowserListViewDefaultColumnFlags; |
columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly; |
columnDesc.headerBtnDesc.titleString = ::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), "\pSlider", kCFStringEncodingMacRoman); |
::AddDataBrowserListViewColumn(browser, |
&columnDesc, kDataBrowserListViewAppendColumn); |
*/ |
// Add the progress bar column |
columnDesc.propertyDesc.propertyID = kProgressBarColumn; |
columnDesc.headerBtnDesc.btnFontStyle.just = teFlushDefault; |
columnDesc.propertyDesc.propertyType = kDataBrowserRelevanceRankType; |
columnDesc.propertyDesc.propertyFlags = kDataBrowserListViewDefaultColumnFlags; |
columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly; |
columnDesc.headerBtnDesc.titleString = ::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), "\pRelevance Rank", kCFStringEncodingMacRoman); |
::AddDataBrowserListViewColumn(browser, |
&columnDesc, kDataBrowserListViewAppendColumn); |
// Add date/time column |
columnDesc.propertyDesc.propertyID = kDateTimeColumn; |
columnDesc.headerBtnDesc.btnFontStyle.just = teFlushLeft; |
columnDesc.propertyDesc.propertyType = kDataBrowserDateTimeType; |
columnDesc.propertyDesc.propertyFlags = kDataBrowserListViewSelectionColumn | |
kDataBrowserListViewDefaultColumnFlags; |
columnDesc.headerBtnDesc.minimumWidth = 50; |
columnDesc.headerBtnDesc.maximumWidth = 200; |
columnDesc.headerBtnDesc.titleString = ::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), "\pDate/Time", kCFStringEncodingMacRoman); |
::AddDataBrowserListViewColumn(browser, |
&columnDesc, kDataBrowserListViewAppendColumn); |
// Add column 8 |
columnDesc.propertyDesc.propertyID = kPopupMenuColumn; |
columnDesc.propertyDesc.propertyType = kDataBrowserPopupMenuType; |
columnDesc.propertyDesc.propertyFlags = kDataBrowserPropertyIsMutable | |
kDataBrowserListViewDefaultColumnFlags; |
columnDesc.headerBtnDesc.titleString = ::CFStringCreateWithPascalString( |
CFAllocatorGetDefault(), "\pPopup Menu", kCFStringEncodingMacRoman); |
::AddDataBrowserListViewColumn(browser, |
&columnDesc, kDataBrowserListViewAppendColumn); |
// Finish formatting the table |
//::SetDataBrowserTableViewRowHeight(browser, 10); |
//::SetDataBrowserSortProperty(browser, kFlavorColumn); |
::SetDataBrowserListViewDisclosureColumn(browser, kFlavorColumn, false); |
::ReleaseIconRef(columnDesc.headerBtnDesc.btnContentInfo.u.iconRef); |
} break; |
case kDataBrowserColumnView: |
{ //DataBrowserItemID path[] = { 48, 485 }; |
//::SetDataBrowserColumnViewPath(browser, 2, path); |
//::SetDataBrowserTarget(browser, 50695); |
} break; |
} |
//RestoreUserState(); |
} |
// -------------------------------------------------------------------- |
void InstallDataBrowserCallbacks(ControlRef browser) |
{ |
DataBrowserCallbacks myCallbacks; |
//Use latest layout and callback signatures |
myCallbacks.version = kDataBrowserLatestCallbacks; |
verify_noerr(InitDataBrowserCallbacks(&myCallbacks)); |
myCallbacks.u.v1.itemDataCallback = |
NewDataBrowserItemDataUPP(MyGetSetItemData); |
myCallbacks.u.v1.itemCompareCallback = |
NewDataBrowserItemCompareUPP(MyItemComparison); |
myCallbacks.u.v1.itemNotificationCallback = |
NewDataBrowserItemNotificationUPP(MyItemNotification); |
myCallbacks.u.v1.acceptDragCallback = |
NewDataBrowserAcceptDragUPP(MyAcceptDrag); |
myCallbacks.u.v1.receiveDragCallback = |
NewDataBrowserReceiveDragUPP(MyReceiveDrag); |
myCallbacks.u.v1.addDragItemCallback = |
NewDataBrowserAddDragItemUPP(MyAddDragItem); |
myCallbacks.u.v1.itemHelpContentCallback = |
NewDataBrowserItemHelpContentUPP(MyItemHelpContent); |
myCallbacks.u.v1.getContextualMenuCallback = |
NewDataBrowserGetContextualMenuUPP(MyGetContextualMenu); |
myCallbacks.u.v1.selectContextualMenuCallback = |
NewDataBrowserSelectContextualMenuUPP(MySelectContextualMenu); |
verify_noerr(SetDataBrowserCallbacks(browser, &myCallbacks)); |
} |
// -------------------------------------------------------------------- |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-05-08