/* sundialogs - dialogs support for SunView */
/* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
/* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
/* You may give out copies of this software; for conditions see the */
/* file COPYING included with this distribution. */
#include "dialogs.h"
#include xlstat.h"
#include "xlgraph.h"
#include <fcntl.h>
extern Frame BaseFrame;
extern LVAL s_text_length;
typedef struct {
LVAL object;
int idleOn, frontOnly;
int mouse_x, mouse_y;
Panel panel;
} DialogData;
int inModal = FALSE;
/* layout definitions */
# define BUTTON_HEIGHT_PAD 20
# define BUTTON_WIDTH_PAD 15
# define TOGGLE_HEIGHT_PAD 5
# define TOGGLE_WIDTH_PAD 30
# define CHOICE_WIDTH_PAD 20
# define CHOICE_HEIGHT 30
# define TEXT_WIDTH_PAD 20
# define TEXT_HEIGHT_PAD 5
# define SCROLL_WIDTH 250
# define SCROLL_HEIGHT 20
/***********************************************************************/
/** **/
/** Utility Functions **/
/** **/
/***********************************************************************/
static Point StringSize(text)
char *text;
{
struct pixfont *font = pf_default();
struct pr_size string_size;
Point size;
size.v = font->pf_defaultsize.y;
string_size = pf_textwidth(strlen(text), font, text);
size.h = string_size.x;
return(size);
}
static FindItemType(item)
LVAL item;
{
if (consp(item)) return(ITEM_LIST);
else if (button_item_p(item)) return(BUTTON_ITEM);
else if (toggle_item_p(item)) return(TOGGLE_ITEM);
else if (text_item_p(item)) return(TEXT_ITEM);
else if (choice_item_p(item)) return(CHOICE_ITEM);
else if (scroll_item_p(item)) return(SCROLL_ITEM);
else if (list_item_p(item)) return(LIST_ITEM);
else xlfail("item of unknown type");
}
static Panel_item FindPanelItem(item)
LVAL item;
{
Frame frame;
LVAL dialog;
DialogData *ddata;
Panel panel;
Panel_item panel_item, current_item;
dialog = slot_value(item, s_dialog);
if (! objectp(dialog)) xlerror("not a dialog object", dialog);
frame = (Frame) GETDIALOGADDRESS(dialog);
if (frame == NULL) return(NULL);
else {
ddata = (DialogData *) GetWRefCon(frame);
panel = ddata->panel;
panel_item = NULL;
panel_each_item(panel, current_item)
if ((LVAL) panel_get(current_item, PANEL_CLIENT_DATA) == item)
panel_item = current_item;
panel_end_each;
if (panel_item == NULL) xlfail("can't find internal item");
return(panel_item);
}
}
/***********************************************************************/
/** **/
/** General Dialog Functions **/
/** **/
/***********************************************************************/
static done_proc(frame)
Frame frame;
{
DialogData *ddata = (DialogData *) GetWRefCon(frame);
if (ddata != NULL) send_message(ddata->object, sk_close);
}
DialogAllocate(dialog)
LVAL dialog;
{
Frame dialog_frame;
Panel dialog_panel;
Point loc, size;
char *title;
int is_modeless;
DialogData *ddata;
if (check_dialog_address(dialog)) DialogRemove(dialog);
if (! stringp(slot_value(dialog, s_title)))
xlerror("not a string", slot_value(dialog, s_title));
title = (char *) getstring(slot_value(dialog, s_title));
loc = ListToPoint(slot_value(dialog, s_location));
size = ListToPoint(slot_value(dialog, s_size));
is_modeless = (slot_value(dialog, s_type) == s_modeless) ? TRUE : FALSE;
dialog_frame = window_create(BaseFrame, FRAME,
FRAME_NO_CONFIRM, TRUE,
FRAME_SHOW_LABEL, is_modeless,
FRAME_LABEL, title, 0);
set_dialog_address(dialog_frame, dialog);
dialog_panel = window_create(dialog_frame, PANEL, 0);
if (is_modeless) window_set(dialog_frame, WIN_SHOW, TRUE, 0);
window_set(dialog_frame, FRAME_DONE_PROC, done_proc, 0);
ddata = (DialogData *) StCalloc(sizeof(DialogData), 1);
SetWRefCon(dialog_frame, ddata);
ddata->object = dialog;
ddata->panel = dialog_panel;
InstallDialogItems(dialog);
window_fit(dialog_panel);
window_fit(dialog_frame);
}
DialogRemove(dialog)
LVAL dialog;
{
DialogData *ddata;
Frame frame;
if (check_dialog_address(dialog)
&& (frame = (Frame) GETDIALOGADDRESS(dialog)) != NULL) {
ddata = (DialogData *) GetWRefCon(frame);
StFree(ddata);
window_destroy(frame);
}
if (objectp(dialog)) standard_hardware_clobber(dialog);
}
DialogSetDefaultButton(dialog, item)
LVAL dialog, item;
{
}
DialogReset()
{
inModal = FALSE;
}
LVAL DialogGetModalItem(dialog)
LVAL dialog;
{
Frame frame;
int oldInModal = inModal;
LVAL item = NIL;
/*++++++ deal with interrupts++++++*/
/*+++++++++ does not work on dialogs created as modeless ++++*/
StSunReleaseButton();
inModal = TRUE;
frame = (Frame) GETDIALOGADDRESS(dialog);
if (frame != NULL) {
/* make sure window is NOT showing before using window_loop */
if (window_get(frame, WIN_SHOW)) window_set(frame, WIN_SHOW, FALSE, 0);
item = (LVAL) window_loop(frame);
}
inModal = oldInModal;
return(item);
}
/***********************************************************************/
/** **/
/** Item Installation Functions **/
/** **/
/***********************************************************************/
static button_proc(item, event)
Panel_item item;
Event *event;
{
LVAL lisp_item = (LVAL) panel_get(item, PANEL_CLIENT_DATA);
if (inModal) window_return(lisp_item);
else errset_send(lisp_item, sk_do_action);
}
static choice_proc(item, event)
Panel_item item;
Event *event;
{
LVAL lisp_item = (LVAL) panel_get(item, PANEL_CLIENT_DATA);
errset_send(lisp_item, sk_do_action);
}
static scroll_proc(item, value, event)
Panel_item item;
int value;
Event *event;
{
LVAL lisp_item = (LVAL) panel_get(item, PANEL_CLIENT_DATA);
LVAL dialog;
Frame frame;
Panel panel;
DialogData *ddata;
int oldval, increment;
int fd, oldflags, error;
dialog = slot_value(lisp_item, s_dialog);
frame = (Frame) GETDIALOGADDRESS(dialog);
if (frame == NULL) xlfail("dialog not allocated");
ddata = (DialogData *) GetWRefCon(frame);
panel = ddata->panel;
oldval = (int) panel_get(item, PANEL_VALUE);
if (oldval < value) increment = 1;
else if (oldval > value) increment = -1;
else increment = 0;
fd = (int) window_get(panel, WIN_FD);
oldflags = fcntl(fd, F_GETFL, FNDELAY);
fcntl(fd, F_SETFL, oldflags | FNDELAY);
value = oldval;
error = FALSE;
while (! error && input_readevent(fd, event)) {
value += increment;
panel_set(item, PANEL_VALUE, value, 0);
error = errset_send(lisp_item, sk_do_action);
}
error = FALSE;
while (! error && ! event_is_up(event)) {
value += increment;
panel_set(item, PANEL_VALUE, value, 0);
error = errset_send(lisp_item, sk_do_action);
while (! error && input_readevent(fd, event)) {
value += increment;
panel_set(item, PANEL_VALUE, value, 0);
error = errset_send(lisp_item, sk_do_action);
}
}
fcntl(fd, F_SETFL, oldflags);
errset_send(lisp_item, sk_do_action);
}
static InstallDialogItems(dialog)
LVAL dialog;
{
Frame frame;
Panel panel;
DialogData *ddata;
LVAL items;
frame = (Frame) GETDIALOGADDRESS(dialog);
if (frame != NULL) {
ddata = (DialogData *) GetWRefCon(frame);
items = slot_value(dialog, s_items);
if (ddata != NULL) {
panel = ddata->panel;
InstallItemList(panel, items);
}
}
}
static InstallItemList(panel, items)
Panel panel;
LVAL items;
{
for (; consp(items); items = cdr(items))
if (consp(car(items))) InstallItemList(panel, car(items));
else InstallItem(panel, car(items));
}
static InstallItem(panel, item)
Panel panel;
LVAL item;
{
int type;
if (! dialog_item_p(item)) xlerror("not a dialog item", item);
type = FindItemType(item);
switch (type) {
case BUTTON_ITEM: InstallButtonItem(panel, item); break;
case TOGGLE_ITEM: InstallToggleItem(panel, item); break;
case CHOICE_ITEM: InstallChoiceItem(panel, item); break;
case TEXT_ITEM: InstallTextItem(panel, item); break;
case SCROLL_ITEM: InstallScrollItem(panel, item); break;
default: xlfail("unkown item type");
}
}
static InstallButtonItem(panel, item)
Panel panel;
LVAL item;
{
char *text;
Point loc;
Panel_item button_item;
if (! stringp(slot_value(item, s_text)))
xlerror("not a string", slot_value(item, s_text));
text = (char *) getstring(slot_value(item, s_text));
loc = ListToPoint(slot_value(item, s_location));
button_item = panel_create_item(panel, PANEL_BUTTON,
PANEL_LABEL_IMAGE,
panel_button_image(panel, text, 0, 0),
PANEL_ITEM_X, loc.h,
PANEL_ITEM_Y, loc.v,
PANEL_CLIENT_DATA, item,
PANEL_NOTIFY_PROC, button_proc,
0);
}
static InstallToggleItem(panel, item)
Panel panel;
LVAL item;
{
char *text;
Point loc;
Panel_item toggle_item;
int value;
if (! stringp(slot_value(item, s_text)))
xlerror("not a string", slot_value(item, s_text));
text = (char *) getstring(slot_value(item, s_text));
loc = ListToPoint(slot_value(item, s_location));
value = (slot_value(item, s_value) != NIL) ? TRUE : FALSE;
toggle_item = panel_create_item(panel, PANEL_TOGGLE,
PANEL_CHOICE_STRINGS, text, 0,
PANEL_ITEM_X, loc.h,
PANEL_ITEM_Y, loc.v,
PANEL_CLIENT_DATA, item,
PANEL_NOTIFY_PROC, choice_proc,
0);
DialogToggleItemValue(item, TRUE, value);
}
static InstallChoiceItem(panel, item)
Panel panel;
LVAL item;
{
LVAL text;
Point loc;
Panel_item choice_item;
char *str;
int i;
LVAL value;
loc = ListToPoint(slot_value(item, s_location));
choice_item = panel_create_item(panel, PANEL_CHOICE,
PANEL_LAYOUT, PANEL_VERTICAL,
PANEL_ITEM_X, loc.h,
PANEL_ITEM_Y, loc.v,
PANEL_CLIENT_DATA, item,
PANEL_NOTIFY_PROC, choice_proc,
0);
for (text = slot_value(item, s_text), i = 0;
consp(text);
text = cdr(text), i++) {
str = (char *) getstring(car(text));
panel_set(choice_item, PANEL_CHOICE_STRING, i, str, 0);
}
value = slot_value(item, s_value);
if (fixp(value)) DialogChoiceItemValue(item, TRUE, getfixnum(value));
}
static InstallTextItem(panel, item)
Panel panel;
LVAL item;
{
char *text;
Point loc;
Panel_item panel_item;
int editable, len;
LVAL text_length;
if (! stringp(slot_value(item, s_text)))
xlerror("not a string", slot_value(item, s_text));
text = (char *) getstring(slot_value(item, s_text));
loc = ListToPoint(slot_value(item, s_location));
editable = (slot_value(item, s_editable) != NIL) ? TRUE : FALSE;
if (editable) {
text_length = slot_value(item, s_text_length);
len = (fixp(text_length)) ? getfixnum(text_length) : 0;
len = max(len, strlen(text));
panel_item = panel_create_item(panel, PANEL_TEXT,
PANEL_VALUE, text,
PANEL_VALUE_DISPLAY_LENGTH, len,
PANEL_ITEM_X, loc.h,
PANEL_ITEM_Y, loc.v,
PANEL_CLIENT_DATA, item,
0);
}
else
panel_item = panel_create_item(panel, PANEL_MESSAGE,
PANEL_LABEL_STRING, text,
PANEL_ITEM_X, loc.h,
PANEL_ITEM_Y, loc.v,
PANEL_CLIENT_DATA, item,
0);
}
static InstallScrollItem(panel, item)
Panel panel;
LVAL item;
{
Point loc, size;
Panel_item scroll_item;
int low, high, value;
LVAL temp;
loc = ListToPoint(slot_value(item, s_location));
size = ListToPoint(slot_value(item, s_size));
temp = slot_value(item, s_min_value);
low = fixp(temp) ? getfixnum(temp) : 0;
temp = slot_value(item, s_max_value);
high = fixp(temp) ? getfixnum(temp) : 100;
temp = slot_value(item, s_value);
value = (fixp(temp)) ? getfixnum(temp) : low;
scroll_item = panel_create_item(panel, PANEL_SLIDER,
PANEL_ITEM_X, loc.h,
PANEL_ITEM_Y, loc.v,
PANEL_SLIDER_WIDTH, size.h,
PANEL_MIN_VALUE, low,
PANEL_MAX_VALUE, high,
PANEL_VALUE, value,
PANEL_CLIENT_DATA, item,
PANEL_NOTIFY_LEVEL, PANEL_ALL,
PANEL_SHOW_RANGE, FALSE,
PANEL_SHOW_VALUE, FALSE,
PANEL_NOTIFY_PROC, scroll_proc,
0);
}
/***********************************************************************/
/** **/
/** Dialog Item Functions **/
/** **/
/***********************************************************************/
DialogButtonGetDefaultSize(item, width, height)
LVAL item;
int *width, *height;
{
LVAL text = slot_value(item, s_text);
Point sz;
if (! stringp(text)) xlerror("not a string", text);
sz = StringSize(getstring(text));
if (width != NULL) *width = sz.h + BUTTON_WIDTH_PAD;
if (height != NULL) *height = sz.v + BUTTON_HEIGHT_PAD;
}
DialogToggleGetDefaultSize(item, width, height)
LVAL item;
int *width, *height;
{
LVAL text = slot_value(item, s_text);
Point sz;
if (! stringp(text)) xlerror("not a string", text);
sz = StringSize(getstring(text));
if (width != NULL) *width = sz.h + TOGGLE_WIDTH_PAD;
if (height != NULL) *height = sz.v + TOGGLE_HEIGHT_PAD;
}
LVAL DialogToggleItemValue(item, set, value)
LVAL item;
int set, value;
{
Panel_item panel_item = FindPanelItem(item);
if (set) set_slot_value(item, s_value, (value) ? s_true : NIL);
if (panel_item != NULL) {
if (set) panel_set(panel_item, PANEL_TOGGLE_VALUE, 0, value, 0);
value = (int) panel_get(panel_item, PANEL_TOGGLE_VALUE, 0);
set_slot_value(item, s_value, (value) ? s_true : NIL);
}
return(slot_value(item, s_value));
}
DialogChoiceGetDefaultSize(item, width, height)
LVAL item;
int *width, *height;
{
Point sz, pt;
LVAL text = slot_value(item, s_text);
for (sz.h = 0, sz.v = 0; consp(text); text = cdr(text)) {
pt = StringSize(getstring(car(text)));
sz.h = max(sz.h, pt.h);
sz.v += CHOICE_HEIGHT;
}
if (width != NULL) *width = sz.h + CHOICE_WIDTH_PAD;
if (height != NULL) *height = sz.v;
}
LVAL DialogChoiceItemValue(item, set, value)
LVAL item;
int set, value;
{
Panel_item panel_item = FindPanelItem(item);
if (set) set_slot_value(item, s_value, cvfixnum((FIXTYPE) value));
if (panel_item != NULL) {
if (set) panel_set(panel_item, PANEL_VALUE, value, 0);
value = (int) panel_get(panel_item, PANEL_VALUE);
set_slot_value(item, s_value, cvfixnum((FIXTYPE) value));
}
return(slot_value(item, s_value));
}
DialogTextGetDefaultSize(item, width, height)
LVAL item;
int *width, *height;
{
Point sz;
LVAL text_length = slot_value(item, s_text_length);
int len;
sz = StringSize(getstring(slot_value(item, s_text)));
len = sz.h;
if (fixp(text_length)) {
sz = StringSize("M");
len = max(len, getfixnum(text_length) * sz.h);
}
if (width != NULL) *width = len + TEXT_WIDTH_PAD;
if (height != NULL) *height = sz.v + TEXT_HEIGHT_PAD;
}
LVAL DialogTextItemText(item, set, text)
LVAL item;
int set;
char *text;
{
Panel_item panel_item = FindPanelItem(item);
int editable = (slot_value(item, s_editable) != NIL) ? TRUE : FALSE;
if (set) set_slot_value(item, s_text, cvstring(text));
if (panel_item != NULL) {
if (editable) {
if (set) panel_set(panel_item, PANEL_VALUE, text, 0);
text = panel_get(panel_item, PANEL_VALUE);
}
else {
if (set) panel_set(panel_item, PANEL_LABEL_STRING, text, 0);
text = panel_get(panel_item, PANEL_LABEL_STRING);
}
set_slot_value(item, s_text, cvstring(text));
}
return(slot_value(item, s_text));
}
DialogScrollGetDefaultSize(item, width, height)
LVAL item;
int *width, *height;
{
Point sz;
if (width != NULL) *width = SCROLL_WIDTH;
if (height != NULL) *height = SCROLL_HEIGHT;
}
LVAL DialogScrollItemValue(item, set, value)
LVAL item;
int set, value;
{
Panel_item panel_item = FindPanelItem(item);
if (set) set_slot_value(item, s_value, cvfixnum((FIXTYPE) value));
if (panel_item != NULL) {
if (set) panel_set(panel_item, PANEL_VALUE, value, 0);
value = (int) panel_get(panel_item, PANEL_VALUE);
set_slot_value(item, s_value, cvfixnum((FIXTYPE) value));
}
return(slot_value(item, s_value));
}
LVAL DialogScrollItemMax(item, set, value)
LVAL item;
int set, value;
{
Panel_item panel_item = FindPanelItem(item);
if (set) set_slot_value(item, s_min_value, cvfixnum((FIXTYPE) value));
if (panel_item != NULL) {
if (set) panel_set(panel_item, PANEL_MIN_VALUE, value, 0);
value = (int) panel_get(panel_item, PANEL_MIN_VALUE);
set_slot_value(item, s_min_value, cvfixnum((FIXTYPE) value));
}
return(slot_value(item, s_min_value));
}
LVAL DialogScrollItemMin(item, set, value)
LVAL item;
int set, value;
{
Panel_item panel_item = FindPanelItem(item);
if (set) set_slot_value(item, s_max_value, cvfixnum((FIXTYPE) value));
if (panel_item != NULL) {
if (set) panel_set(panel_item, PANEL_MAX_VALUE, value, 0);
value = (int) panel_get(panel_item, PANEL_MAX_VALUE);
set_slot_value(item, s_max_value, cvfixnum((FIXTYPE) value));
}
return(slot_value(item, s_max_value));
}
DialogListItemSetText() {}
LVAL DialogListItemSelection() {}
DialogListGetDefaultSize() {}
#ifdef COMMENT
multiple lines in static text items
#endif COMMENT
syntax highlighted by Code2HTML, v. 0.9.1