📄 toolbar.c
字号:
#include <utility.h>
#include <ansi_c.h>
#include <userint.h>
#include "toolbar.h"
/********************/
/* Macros */
/********************/
#define kToolbarWidth 4096
/**************************************************************************/
/* ASSUMPTION: All toolbar buttons are square and will fit properly in a */
/* picture button of the size below. This assumption is */
/* necessary to support the drawing speed optimizations */
/**************************************************************************/
#define kToolbarButtonSize 23
/* Width of a separator */
#define kSeparatorWidth 7
/* Separation between buttons on the toolbar */
#define kButtonSeparation -1
/* Frequency of help polling timer when help is not active */
#define kToolbarHelpInactivePollPeriod 2.0
/* Frequency of help polling timer when help is active */
#define kToolbarHelpActivePollPeriod 0.05
/* Period of help removal timer */
#define kToolbarHelpAutoCloseTime 4.0
/* Number of pixels from bottom of control to top of help panel */
#define kToolbarHelpVerticalOffset 8
/* Toolbar background color */
#define kToolbarPanelColor VAL_PANEL_GRAY
/* Help panel coloring */
#define kToolbarHelpPanelColor VAL_WHITE
#define kToolbarHelpTextColor VAL_BLACK
#define kToolbarHelpTextBackgroundColor VAL_TRANSPARENT
/******************/
/* Types */
/******************/
typedef struct ToolbarItemStruct {
int type;
int controlId;
int active; /* REAL activation state */
int currActive; /* activation state based on drawn or not */
char *description;
int callbackType;
int menuItem;
void *callbackFunc;
void *callbackData;
ToolbarType toolbar;
} ToolbarItem, *ToolbarItemPtr;
typedef struct ToolbarStruct {
ListType items; /* list of toolbar items */
int menuBar; /* 0 if there is no menu bar */
int parentPanel; /* panel id of toolbar's parent panel */
int panelId; /* panel id of toolbar panel */
int helpPanel; /* panel id of toolbar's help panel */
int helpText; /* ctrl id of help panel text msg */
int helpTimer; /* ctrl id of the help panel expiration timer */
int helpEnabled; /* Is the toolbar help enabled? */
int helpActive; /* Is the help active (being displayed) */
int pollTimer; /* ctrl id of the help panel polling timer */
int sizeValid; /* Is the current toolbar sized to the items? */
int itemWidth; /* width of items on the toolbar */
} ToolbarRec, **ToolbarPtr;
/****************************************/
/* Private function prototypes */
/****************************************/
static int ToolbarIsVisible (ToolbarType toolbar);
static int NextItemIsButton (ListType itemList, int i);
static int GetItemIndexFromPosition (ToolbarType toolbar, int xPosition);
static int CreateToolbarHelpPanel (ToolbarType toolbar);
static int DiscardToolbarResources (ToolbarType toolbar);
static ToolbarItemPtr CopyToolbarItem (ToolbarItemPtr toolbarItem);
static void DisposeToolbarItem (ToolbarItemPtr toolbarItem);
static ListType CopyToolbarItemList (ListType itemList);
static void DisposeToolbarItemList (ListType itemList);
static int SizeToolbarToItems (ToolbarType toolbar);
static int SetPollTimer (ToolbarType toolbar, int enabled, int active,
int resetTimer);
static void SetCurrentHelpItem (ToolbarItemPtr itemPtr, ToolbarType toolbar);
static ToolbarItemPtr CurrentHelpItem (void);
static int PollTimerCallback (int panel, int control, int event,
void *callbackData, int eventData1,
int eventData2);
static int HelpTimerCallback (int panel, int control, int event,
void *callbackData, int eventData1,
int eventData2);
static int HelpPanelCallback (int panel, int event, void *callbackData,
int eventData1, int eventData2);
static int HideToolbarHelp (ToolbarType toolbar, int keepTracking,
int rememberCurrentItem);
static int DisplayToolbarHelp (ToolbarItemPtr toolbarItem, int yPosition);
static int ToolbarPanelCallback (int panel, int event, void *callbackData,
int eventData1, int eventData2);
static int GenericToolbarItemCallbackFunc (int panel, int control, int event,
void *callbackData, int eventData1,
int eventData2);
static int CreateNewToolbarItemCtrl (ToolbarItemPtr toolbarItem, char imageFile[]);
/****************************************/
/* Functions */
/****************************************/
static int ToolbarIsVisible (ToolbarType toolbar)
{
int error = -UIENoError;
int visible = 0;
if (!toolbar)
goto Error;
errChk (GetPanelAttribute (toolbar->panelId, ATTR_VISIBLE, &visible));
Error :
return visible;
}
static int CreateToolbarHelpPanel (ToolbarType toolbar)
{
int error = -UIENoError;
int tmpPanel = 0;
if (!toolbar)
return UIEHandleInvalid;
errChk (toolbar->helpPanel = NewPanel (toolbar->parentPanel, "Toolbar Help Panel", 0, 0, 0, 0));
errChk (SetPanelAttribute (toolbar->helpPanel, ATTR_FRAME_STYLE, VAL_OUTLINED_FRAME));
errChk (SetPanelAttribute (toolbar->helpPanel, ATTR_ACTIVATE_WHEN_CLICKED_ON, 0));
errChk (SetPanelAttribute (toolbar->helpPanel, ATTR_BACKCOLOR, kToolbarHelpPanelColor));
errChk (SetPanelAttribute (toolbar->helpPanel, ATTR_TITLEBAR_VISIBLE, 0));
errChk (SetPanelAttribute (toolbar->helpPanel, ATTR_SIZABLE, 0));
errChk (toolbar->helpText = NewCtrl (toolbar->helpPanel, CTRL_TEXT_MSG, "", 0,0));
errChk (SetCtrlAttribute (toolbar->helpPanel, toolbar->helpText,
ATTR_TEXT_BOLD, 0));
errChk (SetCtrlAttribute (toolbar->helpPanel, toolbar->helpText,
ATTR_TEXT_POINT_SIZE, 12));
errChk (SetCtrlAttribute (toolbar->helpPanel, toolbar->helpText,
ATTR_TEXT_COLOR, kToolbarHelpTextColor));
errChk (SetCtrlAttribute (toolbar->helpPanel, toolbar->helpText,
ATTR_TEXT_BGCOLOR, kToolbarHelpTextBackgroundColor));
errChk (toolbar->helpTimer = NewCtrl (toolbar->helpPanel, CTRL_TIMER,
"Help Timer", 0, 0));
errChk (InstallCtrlCallback (toolbar->helpPanel, toolbar->helpTimer,
HelpTimerCallback, (void *)toolbar));
errChk (SetCtrlAttribute (toolbar->helpPanel, toolbar->helpTimer,
ATTR_INTERVAL, kToolbarHelpAutoCloseTime));
errChk (SetCtrlAttribute (toolbar->helpPanel, toolbar->helpTimer,
ATTR_ENABLED, FALSE));
errChk (toolbar->pollTimer = NewCtrl (toolbar->helpPanel, CTRL_TIMER,
"Help Poll Timer", -150, -150));
errChk (InstallCtrlCallback (toolbar->helpPanel, toolbar->pollTimer,
PollTimerCallback, (void *)toolbar));
errChk (SetCtrlAttribute (toolbar->helpPanel, toolbar->helpTimer,
ATTR_INTERVAL, kToolbarHelpInactivePollPeriod));
toolbar->helpEnabled = FALSE;
toolbar->helpActive = FALSE;
errChk (SetPollTimer (toolbar, FALSE, FALSE, TRUE));
Error :
if (error < 0) {
if (tmpPanel)
DiscardPanel (tmpPanel);
if (toolbar->helpPanel) {
DiscardPanel (toolbar->helpPanel);
toolbar->helpPanel = 0;
toolbar->helpText = 0;
toolbar->helpTimer = 0;
toolbar->pollTimer = 0;
}
}
return error;
}
int Toolbar_New (int parentPanel, int menuBar, char title[],
int top, int left, ToolbarType *toolbar)
{
int error = -UIENoError;
ToolbarType newToolbar = NULL;
int menuVisible, menuHeight;
if (!parentPanel) {
MessagePopup ("Toolbar API Warning",
"Toolbars as top-level panels not supported yet.\n"
"This would be a fairly easy enhancement.");
return NULL;
}
nullChk (newToolbar = malloc (sizeof (ToolbarRec)));
newToolbar->parentPanel = parentPanel;
newToolbar->menuBar = menuBar;
errChk (GetPanelAttribute (newToolbar->parentPanel, ATTR_MENU_BAR_VISIBLE,
&menuVisible));
if (menuVisible) {
errChk (GetPanelAttribute (newToolbar->parentPanel, ATTR_MENU_HEIGHT,
&menuHeight));
top += menuHeight;
}
newToolbar->items = NULL;
newToolbar->sizeValid = 0;
newToolbar->helpEnabled = 0;
newToolbar->helpActive = 0;
errChk (CreateToolbarHelpPanel (newToolbar));
errChk (newToolbar->panelId = NewPanel (parentPanel, title, top, left,
kToolbarButtonSize, 0));
nullChk (newToolbar->items = ListCreate (sizeof (ToolbarItemPtr)));
errChk (SetPanelAttribute (newToolbar->panelId, ATTR_ACTIVATE_WHEN_CLICKED_ON, 0));
errChk (SetPanelAttribute (newToolbar->panelId, ATTR_FRAME_STYLE, VAL_OUTLINED_FRAME));
if (!title || !(*title)) {
errChk (SetPanelAttribute (newToolbar->panelId, ATTR_TITLEBAR_VISIBLE, 0));
}
errChk (SetPanelAttribute (newToolbar->panelId, ATTR_SIZABLE, 0));
errChk (SetPanelAttribute (newToolbar->panelId, ATTR_BACKCOLOR,
kToolbarPanelColor));
errChk (InstallPanelCallback (newToolbar->panelId, ToolbarPanelCallback,
(void *)newToolbar));
*toolbar = newToolbar;
Error :
if (error < 0) {
if (newToolbar)
Toolbar_Discard (newToolbar);
}
return error;
}
int Toolbar_Discard (ToolbarType toolbar)
{
int error = -UIENoError;
errChk (DiscardPanel (toolbar->helpPanel));
errChk (DiscardPanel (toolbar->panelId));
Error :
return error;
}
static int DiscardToolbarResources (ToolbarType toolbar)
{
int error = -UIENoError;
if (!toolbar)
return UIEHandleInvalid;
DisposeToolbarItemList (toolbar->items);
free (toolbar);
Error :
return error;
}
static ToolbarItemPtr CopyToolbarItem (ToolbarItemPtr toolbarItem)
{
int error = -UIENoError;
ToolbarItemPtr newItem = NULL;
if (toolbarItem == NULL)
return NULL;
nullChk (newItem = malloc (sizeof(ToolbarItem)));
*newItem = *toolbarItem;
newItem->description = NULL; /* this is to prevent disposal of */
if (toolbarItem->description) {
nullChk (newItem->description = StrDup (toolbarItem->description));
}
Error :
if (error < 0) {
if (newItem) {
DisposeToolbarItem (newItem);
newItem = NULL;
}
}
return newItem;
}
static void DisposeToolbarItem (ToolbarItemPtr toolbarItem)
{
if (!toolbarItem)
return;
if (toolbarItem->description)
free (toolbarItem->description);
free (toolbarItem);
}
static ListType CopyToolbarItemList (ListType itemList)
{
int error = -UIENoError;
ListType newList = NULL;
int i, numItems;
ToolbarItemPtr itemPtr, newItemPtr;
nullChk (newList = ListCreate (sizeof(ToolbarItemPtr)));
numItems = ListNumItems (itemList);
/**************************************************************************/
/* Set all the char pointers to NULL in new list since we don't want them */
/* to get discarded twice if we get an error. */
/**************************************************************************/
for (i = 1 ; i <= numItems ; i++) {
ListGetItem (itemList, &itemPtr, i);
nullChk (newItemPtr = CopyToolbarItem (itemPtr));
errChk (ListInsertItem (newList, &newItemPtr, END_OF_LIST));
}
Error :
if (error < 0) {
if (newList) {
DisposeToolbarItemList (newList);
newList = NULL;
}
}
return newList;
}
static void DisposeToolbarItemList (ListType itemList)
{
ToolbarItemPtr itemPtr;
int i, numItems;
numItems = ListNumItems (itemList);
for (i = 1 ; i <= numItems ; i++) {
ListGetItem (itemList, &itemPtr, i);
DisposeToolbarItem (itemPtr);
}
ListDispose (itemList);
}
int Toolbar_Duplicate (int destPanel, ToolbarType sourceToolbar, char title[],
int top, int left, ToolbarType *destToolbar)
{
int error = -UIENoError;
ToolbarType newToolbar = NULL;
ToolbarItemPtr currentItem;
int menuVisible, menuHeight;
int numItems, i;
if (!sourceToolbar)
return UIEHandleInvalid;
if (!destPanel) {
MessagePopup ("Toolbar API Warning",
"Toolbars as top-level panels not supported yet.\n"
"This would be a fairly easy enhancement.");
goto Error;
}
nullChk (newToolbar = malloc (sizeof (ToolbarRec)));
newToolbar->parentPanel = destPanel;
newToolbar->menuBar = sourceToolbar->menuBar;
errChk (GetPanelAttribute (newToolbar->parentPanel, ATTR_MENU_BAR_VISIBLE,
&menuVisible));
if (menuVisible) {
errChk (GetPanelAttribute (newToolbar->parentPanel, ATTR_MENU_HEIGHT,
&menuHeight));
top += menuHeight;
}
newToolbar->sizeValid = sourceToolbar->sizeValid;
newToolbar->itemWidth = sourceToolbar->itemWidth;
errChk (CreateToolbarHelpPanel (newToolbar));
errChk (newToolbar->panelId = DuplicatePanel (destPanel, sourceToolbar->panelId,
title, top, left));
nullChk (newToolbar->items = CopyToolbarItemList (sourceToolbar->items));
/*******************************************************/
/* Make all the toolbar items point to the new toolbar */
/* Also, set the callback data correctly for each item */
/*******************************************************/
numItems = ListNumItems (newToolbar->items);
for (i = 1 ; i <= numItems ; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -