This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
magicka/deps/cdk-5.0-20161210/button.c

573 lines
12 KiB
C
Raw Normal View History

#include <cdk_int.h>
#include "button.h"
#include <limits.h>
/*
* $Author: Aarian.P.Aleahmad $
* $Date: 2016/01/31 20:32:25 $
* $Revision: 1.38 $
*/
DeclareCDKObjects (BUTTON, Button, setCdk, Int);
/*
* This creates a button widget.
*/
CDKBUTTON *newCDKButton (CDKSCREEN *cdkscreen,
int xplace,
int yplace,
const char *text,
tButtonCallback callback,
boolean Box,
boolean shadow)
{
/* *INDENT-EQLS* */
CDKBUTTON *button = 0;
int parentWidth = getmaxx (cdkscreen->window);
int parentHeight = getmaxy (cdkscreen->window);
int boxWidth = 0;
int boxHeight;
int xpos = xplace;
int ypos = yplace;
if ((button = newCDKObject (CDKBUTTON, &my_funcs)) == 0)
return (0);
setCDKButtonBox (button, Box);
boxHeight = 1 + 2 * BorderOf (button);
/* Translate the char * to a chtype. */
button->info = char2Chtype (text, &button->infoLen, &button->infoPos);
boxWidth = MAXIMUM (boxWidth, button->infoLen) + 2 * BorderOf (button);
/* Create the string alignments. */
button->infoPos = justifyString (boxWidth - 2 * BorderOf (button),
button->infoLen, button->infoPos);
/*
* Make sure we didn't extend beyond the dimensions of the window.
*/
boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth);
boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight);
/* Rejustify the x and y positions if we need to. */
alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
/* *INDENT-EQLS* Create the button. */
ScreenOf (button) = cdkscreen;
ObjOf (button)->fn = &my_funcs;
button->parent = cdkscreen->window;
button->win = newwin (boxHeight, boxWidth, ypos, xpos);
button->shadowWin = (WINDOW *)NULL;
button->xpos = xpos;
button->ypos = ypos;
button->boxWidth = boxWidth;
button->boxHeight = boxHeight;
button->callback = callback;
button->callbackData = NULL;
ObjOf (button)->inputWindow = button->win;
ObjOf (button)->acceptsFocus = TRUE;
initExitType (button);
button->shadow = shadow;
button->highlight = A_REVERSE;
/* Is the window NULL? */
if (button->win == (WINDOW *)NULL)
{
destroyCDKObject (button);
return (0);
}
keypad (button->win, TRUE);
/* If a shadow was requested, then create the shadow window. */
if (shadow)
button->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1);
/* Register this baby. */
registerCDKObject (cdkscreen, vBUTTON, button);
/* Return the button pointer. */
return (button);
}
/*
* This was added for the builder.
*/
int activateCDKButton (CDKBUTTON *button, chtype *actions)
{
chtype input = 0;
boolean functionKey;
int ret;
drawCDKButton (button, ObjOf (button)->box);
if (actions == 0)
{
for (;;)
{
input = (chtype)getchCDKObject (ObjOf (button), &functionKey);
/* Inject the character into the widget. */
ret = injectCDKButton (button, input);
if (button->exitType != vEARLY_EXIT)
{
return ret;
}
}
}
else
{
int length = chlen (actions);
int x = 0;
/* Inject each character one at a time. */
for (x = 0; x < length; x++)
{
ret = injectCDKButton (button, actions[x]);
if (button->exitType != vEARLY_EXIT)
{
return ret;
}
}
}
/* Set the exit type and exit. */
setExitType (button, 0);
return -1;
}
/*
* This sets multiple attributes of the widget.
*/
void setCDKButton (CDKBUTTON *button, const char *mesg, boolean Box)
{
setCDKButtonMessage (button, mesg);
setCDKButtonBox (button, Box);
}
/*
* This sets the information within the button.
*/
void setCDKButtonMessage (CDKBUTTON *button, const char *info)
{
/* Clean out the old message. */
freeChtype (button->info);
button->infoPos = 0;
button->infoLen = 0;
/* Copy in the new message. */
button->info = char2Chtype (info, &button->infoLen, &button->infoPos);
button->infoPos = justifyString (button->boxWidth - 2 * BorderOf (button),
button->infoLen, button->infoPos);
/* Redraw the button widget. */
eraseCDKButton (button);
drawCDKButton (button, ObjOf (button)->box);
}
chtype *getCDKButtonMessage (CDKBUTTON *button)
{
return button->info;
}
/*
* This sets the box flag for the button widget.
*/
void setCDKButtonBox (CDKBUTTON *button, boolean Box)
{
ObjOf (button)->box = Box;
ObjOf (button)->borderSize = Box ? 1 : 0;
}
boolean getCDKButtonBox (CDKBUTTON *button)
{
return ObjOf (button)->box;
}
/*
* This sets the background attribute of the widget.
*/
static void _setBKattrButton (CDKOBJS *object, chtype attrib)
{
if (object != 0)
{
CDKBUTTON *widget = (CDKBUTTON *)object;
wbkgd (widget->win, attrib);
}
}
static void drawCDKButtonText (CDKBUTTON *button)
{
int boxWidth = button->boxWidth;
int i;
/* Draw in the message. */
for (i = 0; i < boxWidth - 2 * BorderOf (button); i++)
{
chtype c;
int pos = button->infoPos;
int len = button->infoLen;
if (i >= pos && (i - pos) < len)
c = button->info[i - pos];
else
c = ' ';
if (HasFocusObj (button))
{
c = button->highlight | CharOf (c);
}
(void)mvwaddch (button->win, BorderOf (button), i + BorderOf (button), c);
}
}
/*
* This draws the button widget.
*/
static void _drawCDKButton (CDKOBJS *object, boolean Box GCC_UNUSED)
{
CDKBUTTON *button = (CDKBUTTON *)object;
/* Is there a shadow? */
if (button->shadowWin != (WINDOW *)NULL)
{
drawShadow (button->shadowWin);
}
/* Box the widget if asked. */
if (ObjOf (button)->box)
{
drawObjBox (button->win, ObjOf (button));
}
drawCDKButtonText (button);
wrefresh (button->win);
}
/*
* This erases the button widget.
*/
static void _eraseCDKButton (CDKOBJS *object)
{
if (validCDKObject (object))
{
CDKBUTTON *button = (CDKBUTTON *)object;
eraseCursesWindow (button->win);
eraseCursesWindow (button->shadowWin);
}
}
/*
* This moves the button field to the given location.
*/
static void _moveCDKButton (CDKOBJS *object,
int xplace,
int yplace,
boolean relative,
boolean refresh_flag)
{
CDKBUTTON *button = (CDKBUTTON *)object;
int currentX = getbegx (button->win);
int currentY = getbegy (button->win);
int xpos = xplace;
int ypos = yplace;
int xdiff = 0;
int ydiff = 0;
/*
* If this is a relative move, then we will adjust where we want
* to move to.
*/
if (relative)
{
xpos = getbegx (button->win) + xplace;
ypos = getbegy (button->win) + yplace;
}
/* Adjust the window if we need to. */
alignxy (WindowOf (button), &xpos, &ypos, button->boxWidth,
button->boxHeight);
/* Get the difference. */
xdiff = currentX - xpos;
ydiff = currentY - ypos;
/* Move the window to the new location. */
moveCursesWindow (button->win, -xdiff, -ydiff);
moveCursesWindow (button->shadowWin, -xdiff, -ydiff);
/* Touch the windows so they 'move'. */
refreshCDKWindow (WindowOf (button));
/* Redraw the window, if they asked for it. */
if (refresh_flag)
{
drawCDKButton (button, ObjOf (button)->box);
}
}
/*
* This allows the user to use the cursor keys to adjust the
* position of the widget.
*/
void positionCDKButton (CDKBUTTON *button)
{
/* Declare some variables. */
int origX = getbegx (button->win);
int origY = getbegy (button->win);
chtype key = (chtype)0;
boolean functionKey;
/* Let them move the widget around until they hit return. */
while (key != KEY_ENTER)
{
key = (chtype)getchCDKObject (ObjOf (button), &functionKey);
if (key == KEY_UP || key == '8')
{
if (getbegy (button->win) > 0)
{
moveCDKButton (button, 0, -1, TRUE, TRUE);
}
else
{
Beep ();
}
}
else if (key == KEY_DOWN || key == '2')
{
if (getbegy (button->win) + getmaxy (button->win) <
getmaxy (WindowOf (button)) - 1)
{
moveCDKButton (button, 0, 1, TRUE, TRUE);
}
else
{
Beep ();
}
}
else if (key == KEY_LEFT || key == '4')
{
if (getbegx (button->win) > 0)
{
moveCDKButton (button, -1, 0, TRUE, TRUE);
}
else
{
Beep ();
}
}
else if (key == KEY_RIGHT || key == '6')
{
if (getbegx (button->win) + getmaxx (button->win) < getmaxx
(WindowOf (button)) - 1)
{
moveCDKButton (button, 1, 0, TRUE, TRUE);
}
else
{
Beep ();
}
}
else if (key == '7')
{
if (getbegy (button->win) > 0 && getbegx (button->win) > 0)
{
moveCDKButton (button, -1, -1, TRUE, TRUE);
}
else
{
Beep ();
}
}
else if (key == '9')
{
if (getbegx (button->win) + getmaxx (button->win) < getmaxx
(WindowOf (button)) - 1 &&
getbegy (button->win) > 0)
{
moveCDKButton (button, 1, -1, TRUE, TRUE);
}
else
{
Beep ();
}
}
else if (key == '1')
{
if (getbegx (button->win) > 0 && getbegx (button->win) +
getmaxx (button->win) < getmaxx (WindowOf (button)) - 1)
{
moveCDKButton (button, -1, 1, TRUE, TRUE);
}
else
{
Beep ();
}
}
else if (key == '3')
{
if (getbegx (button->win) + getmaxx (button->win) <
getmaxx (WindowOf (button)) - 1
&& getbegy (button->win) + getmaxy (button->win) <
getmaxy (WindowOf (button)) - 1)
{
moveCDKButton (button, 1, 1, TRUE, TRUE);
}
else
{
Beep ();
}
}
else if (key == '5')
{
moveCDKButton (button, CENTER, CENTER, FALSE, TRUE);
}
else if (key == 't')
{
moveCDKButton (button, getbegx (button->win), TOP, FALSE, TRUE);
}
else if (key == 'b')
{
moveCDKButton (button, getbegx (button->win), BOTTOM, FALSE, TRUE);
}
else if (key == 'l')
{
moveCDKButton (button, LEFT, getbegy (button->win), FALSE, TRUE);
}
else if (key == 'r')
{
moveCDKButton (button, RIGHT, getbegy (button->win), FALSE, TRUE);
}
else if (key == 'c')
{
moveCDKButton (button, CENTER, getbegy (button->win), FALSE, TRUE);
}
else if (key == 'C')
{
moveCDKButton (button, getbegx (button->win), CENTER, FALSE, TRUE);
}
else if (key == CDK_REFRESH)
{
eraseCDKScreen (ScreenOf (button));
refreshCDKScreen (ScreenOf (button));
}
else if (key == KEY_ESC)
{
moveCDKButton (button, origX, origY, FALSE, TRUE);
}
else if (key != KEY_ENTER)
{
Beep ();
}
}
}
/*
* This destroys the button object pointer.
*/
static void _destroyCDKButton (CDKOBJS *object)
{
if (object != 0)
{
CDKBUTTON *button = (CDKBUTTON *)object;
/* Free up the character pointers. */
freeChtype (button->info);
/* Free up the window pointers. */
deleteCursesWindow (button->shadowWin);
deleteCursesWindow (button->win);
/* Clean the key bindings. */
cleanCDKObjectBindings (vBUTTON, button);
/* Unregister the object. */
unregisterCDKObject (vBUTTON, button);
}
}
/*
* This injects a single character into the widget.
*/
static int _injectCDKButton (CDKOBJS *object, chtype input)
{
CDKBUTTON *widget = (CDKBUTTON *)object;
int ret = unknownInt;
bool complete = FALSE;
setExitType (widget, 0);
/* Check a predefined binding. */
if (checkCDKObjectBind (vBUTTON, widget, input) != 0)
{
checkEarlyExit (widget);
complete = TRUE;
}
else
{
switch (input)
{
case KEY_ESC:
setExitType (widget, input);
complete = TRUE;
break;
case KEY_ERROR:
setExitType (widget, input);
complete = TRUE;
break;
case KEY_ENTER:
case SPACE:
if (widget->callback)
widget->callback (widget);
setExitType (widget, KEY_ENTER);
ret = 0;
complete = TRUE;
break;
case CDK_REFRESH:
eraseCDKScreen (ScreenOf (widget));
refreshCDKScreen (ScreenOf (widget));
break;
default:
Beep ();
break;
}
}
if (!complete)
{
setExitType (widget, 0);
}
ResultOf (widget).valueInt = ret;
return (ret != unknownInt);
}
static void _focusCDKButton (CDKOBJS *object)
{
CDKBUTTON *button = (CDKBUTTON *)object;
drawCDKButtonText (button);
wrefresh (button->win);
}
static void _unfocusCDKButton (CDKOBJS *object)
{
CDKBUTTON *button = (CDKBUTTON *)object;
drawCDKButtonText (button);
wrefresh (button->win);
}
dummyRefreshData (Button)
dummySaveData (Button)