Files
wmaker/WINGs/wpopupbutton.c
T

799 lines
19 KiB
C
Raw Normal View History

1998-09-29 22:36:29 +00:00
#include "WINGsP.h"
1999-01-06 15:22:33 +00:00
1998-09-29 22:36:29 +00:00
typedef struct W_PopUpButton {
W_Class widgetClass;
WMView *view;
void *clientData;
WMAction *action;
char *caption;
WMArray *items;
2000-05-21 23:56:33 +00:00
1998-09-29 22:36:29 +00:00
short selectedItemIndex;
short highlightedItem;
WMView *menuView; /* override redirect popup menu */
1999-01-06 15:22:33 +00:00
WMHandlerID timer; /* for autoscroll */
/**/
int scrollStartY; /* for autoscroll */
1998-09-29 22:36:29 +00:00
struct {
unsigned int pullsDown:1;
unsigned int configured:1;
unsigned int insideMenu:1;
1999-01-06 15:22:33 +00:00
unsigned int enabled:1;
1998-09-29 22:36:29 +00:00
} flags;
} PopUpButton;
#define MENU_BLINK_DELAY 60000
#define MENU_BLINK_COUNT 2
1999-03-30 22:14:17 +00:00
#define SCROLL_DELAY 10
1999-01-06 15:22:33 +00:00
1998-09-29 22:36:29 +00:00
#define DEFAULT_WIDTH 60
#define DEFAULT_HEIGHT 20
#define DEFAULT_CAPTION ""
static void destroyPopUpButton(PopUpButton *bPtr);
static void paintPopUpButton(PopUpButton *bPtr);
static void handleEvents(XEvent *event, void *data);
static void handleActionEvents(XEvent *event, void *data);
static void resizeMenu(PopUpButton *bPtr);
WMPopUpButton*
WMCreatePopUpButton(WMWidget *parent)
{
PopUpButton *bPtr;
W_Screen *scr = W_VIEW(parent)->screen;
bPtr = wmalloc(sizeof(PopUpButton));
memset(bPtr, 0, sizeof(PopUpButton));
bPtr->widgetClass = WC_PopUpButton;
bPtr->view = W_CreateView(W_VIEW(parent));
if (!bPtr->view) {
1999-10-09 20:07:23 +00:00
wfree(bPtr);
1998-09-29 22:36:29 +00:00
return NULL;
}
bPtr->view->self = bPtr;
WMCreateEventHandler(bPtr->view, ExposureMask|StructureNotifyMask
|ClientMessageMask, handleEvents, bPtr);
W_ResizeView(bPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
bPtr->caption = wstrdup(DEFAULT_CAPTION);
WMCreateEventHandler(bPtr->view, ButtonPressMask|ButtonReleaseMask,
handleActionEvents, bPtr);
1999-01-06 15:22:33 +00:00
bPtr->flags.enabled = 1;
bPtr->items =
WMCreateArrayWithDestructor(4, (WMFreeDataProc*)WMDestroyMenuItem);
1999-10-20 03:25:06 +00:00
2000-01-05 22:02:22 +00:00
bPtr->selectedItemIndex = -1;
2000-07-10 22:37:39 +00:00
bPtr->menuView = W_CreateUnmanagedTopView(scr);
1998-09-29 22:36:29 +00:00
W_ResizeView(bPtr->menuView, bPtr->view->size.width, 1);
WMCreateEventHandler(bPtr->menuView, ButtonPressMask|ButtonReleaseMask
1999-01-06 15:22:33 +00:00
|EnterWindowMask|LeaveWindowMask|ButtonMotionMask
|ExposureMask, handleActionEvents, bPtr);
1998-09-29 22:36:29 +00:00
return bPtr;
}
void
WMSetPopUpButtonAction(WMPopUpButton *bPtr, WMAction *action, void *clientData)
{
CHECK_CLASS(bPtr, WC_PopUpButton);
bPtr->action = action;
bPtr->clientData = clientData;
}
1999-10-20 03:25:06 +00:00
WMMenuItem*
1998-09-29 22:36:29 +00:00
WMAddPopUpButtonItem(WMPopUpButton *bPtr, char *title)
{
1999-10-20 03:25:06 +00:00
WMMenuItem *item;
1998-09-29 22:36:29 +00:00
CHECK_CLASS(bPtr, WC_PopUpButton);
1999-10-20 03:25:06 +00:00
item = WMCreateMenuItem();
WMSetMenuItemTitle(item, title);
WMAddToArray(bPtr->items, item);
1999-10-20 03:25:06 +00:00
1998-09-29 22:36:29 +00:00
if (bPtr->menuView && bPtr->menuView->flags.realized)
resizeMenu(bPtr);
1999-10-20 03:25:06 +00:00
return item;
1998-09-29 22:36:29 +00:00
}
1999-10-20 03:25:06 +00:00
WMMenuItem*
1998-09-29 22:36:29 +00:00
WMInsertPopUpButtonItem(WMPopUpButton *bPtr, int index, char *title)
{
1999-10-20 03:25:06 +00:00
WMMenuItem *item;
1998-09-29 22:36:29 +00:00
CHECK_CLASS(bPtr, WC_PopUpButton);
1999-10-20 03:25:06 +00:00
item = WMCreateMenuItem();
WMSetMenuItemTitle(item, title);
1998-09-29 22:36:29 +00:00
WMInsertInArray(bPtr->items, index, item);
1998-09-29 22:36:29 +00:00
/* if there is an selected item, update it's index to match the new
* position */
if (index < bPtr->selectedItemIndex)
bPtr->selectedItemIndex++;
if (bPtr->menuView && bPtr->menuView->flags.realized)
resizeMenu(bPtr);
1999-10-20 03:25:06 +00:00
return item;
1998-09-29 22:36:29 +00:00
}
void
WMRemovePopUpButtonItem(WMPopUpButton *bPtr, int index)
{
CHECK_CLASS(bPtr, WC_PopUpButton);
wassertr(index >= 0 && index < WMGetArrayItemCount(bPtr->items));
1998-09-29 22:36:29 +00:00
WMDeleteFromArray(bPtr->items, index);
1998-09-29 22:36:29 +00:00
1999-10-20 03:25:06 +00:00
if (bPtr->selectedItemIndex >= 0 && !bPtr->flags.pullsDown) {
1998-09-29 22:36:29 +00:00
if (index < bPtr->selectedItemIndex)
bPtr->selectedItemIndex--;
else if (index == bPtr->selectedItemIndex) {
1999-11-02 21:28:08 +00:00
/* reselect first item if the removed item is the
1998-09-29 22:36:29 +00:00
* selected one */
bPtr->selectedItemIndex = 0;
if (bPtr->view->flags.mapped)
paintPopUpButton(bPtr);
}
}
if (bPtr->menuView && bPtr->menuView->flags.realized)
resizeMenu(bPtr);
}
1999-01-06 15:22:33 +00:00
void
WMSetPopUpButtonEnabled(WMPopUpButton *bPtr, Bool flag)
{
bPtr->flags.enabled = flag;
if (bPtr->view->flags.mapped)
paintPopUpButton(bPtr);
}
Bool
WMGetPopUpButtonEnabled(WMPopUpButton *bPtr)
{
return bPtr->flags.enabled;
}
1998-09-29 22:36:29 +00:00
void
WMSetPopUpButtonSelectedItem(WMPopUpButton *bPtr, int index)
{
wassertr(index < WMGetArrayItemCount(bPtr->items));
/* if (index >= WMGetArrayCount(bPtr->items))
index = -1;*/
1998-09-29 22:36:29 +00:00
bPtr->selectedItemIndex = index;
if (bPtr->view->flags.mapped)
paintPopUpButton(bPtr);
}
2000-11-11 18:08:10 +00:00
1998-09-29 22:36:29 +00:00
int
WMGetPopUpButtonSelectedItem(WMPopUpButton *bPtr)
{
1999-10-20 03:25:06 +00:00
if (!bPtr->flags.pullsDown && bPtr->selectedItemIndex < 0)
1998-09-29 22:36:29 +00:00
return -1;
else
return bPtr->selectedItemIndex;
}
void
WMSetPopUpButtonText(WMPopUpButton *bPtr, char *text)
{
if (bPtr->caption)
1999-10-09 20:07:23 +00:00
wfree(bPtr->caption);
1998-09-29 22:36:29 +00:00
if (text)
bPtr->caption = wstrdup(text);
else
bPtr->caption = NULL;
if (bPtr->view->flags.realized) {
if (bPtr->flags.pullsDown || bPtr->selectedItemIndex < 0) {
paintPopUpButton(bPtr);
}
}
}
void
WMSetPopUpButtonItemEnabled(WMPopUpButton *bPtr, int index, Bool flag)
{
WMSetMenuItemEnabled(WMGetFromArray(bPtr->items, index), flag);
1998-09-29 22:36:29 +00:00
}
Bool
WMGetPopUpButtonItemEnabled(WMPopUpButton *bPtr, int index)
{
return WMGetMenuItemEnabled(WMGetFromArray(bPtr->items, index));
}
1998-09-29 22:36:29 +00:00
void
WMSetPopUpButtonPullsDown(WMPopUpButton *bPtr, Bool flag)
{
bPtr->flags.pullsDown = flag;
1999-10-20 03:25:06 +00:00
if (flag) {
1998-09-29 22:36:29 +00:00
bPtr->selectedItemIndex = -1;
1999-10-20 03:25:06 +00:00
}
1998-09-29 22:36:29 +00:00
if (bPtr->view->flags.mapped)
paintPopUpButton(bPtr);
}
int
WMGetPopUpButtonNumberOfItems(WMPopUpButton *bPtr)
{
return WMGetArrayItemCount(bPtr->items);
1998-09-29 22:36:29 +00:00
}
char*
WMGetPopUpButtonItem(WMPopUpButton *bPtr, int index)
{
if (index >= WMGetArrayItemCount(bPtr->items) || index < 0)
1998-09-29 22:36:29 +00:00
return NULL;
1999-10-20 03:25:06 +00:00
return WMGetMenuItemTitle(WMGetFromArray(bPtr->items, index));
1999-10-20 03:25:06 +00:00
}
WMMenuItem*
WMGetPopUpButtonMenuItem(WMPopUpButton *bPtr, int index)
{
return WMGetFromArray(bPtr->items, index);
1998-09-29 22:36:29 +00:00
}
1999-10-20 03:25:06 +00:00
1998-09-29 22:36:29 +00:00
static void
paintPopUpButton(PopUpButton *bPtr)
{
W_Screen *scr = bPtr->view->screen;
char *caption;
Pixmap pixmap;
if (bPtr->flags.pullsDown) {
caption = bPtr->caption;
} else {
1999-10-20 03:25:06 +00:00
if (bPtr->selectedItemIndex < 0) {
1998-09-29 22:36:29 +00:00
/* if no item selected, show the caption */
caption = bPtr->caption;
1999-11-02 21:28:08 +00:00
} else {
1999-10-20 03:25:06 +00:00
caption = WMGetPopUpButtonItem(bPtr, bPtr->selectedItemIndex);
1998-09-29 22:36:29 +00:00
}
}
pixmap = XCreatePixmap(scr->display, bPtr->view->window,
bPtr->view->size.width, bPtr->view->size.height,
scr->depth);
1999-03-09 14:58:01 +00:00
XFillRectangle(scr->display, pixmap, WMColorGC(scr->gray), 0, 0,
1998-09-29 22:36:29 +00:00
bPtr->view->size.width, bPtr->view->size.height);
W_DrawRelief(scr, pixmap, 0, 0, bPtr->view->size.width,
bPtr->view->size.height, WRRaised);
if (caption) {
1999-01-06 15:22:33 +00:00
W_PaintText(bPtr->view, pixmap, scr->normalFont, 6,
(bPtr->view->size.height-WMFontHeight(scr->normalFont))/2,
bPtr->view->size.width, WALeft,
1999-03-09 14:58:01 +00:00
bPtr->flags.enabled ? WMColorGC(scr->black) : WMColorGC(scr->darkGray),
1999-01-06 15:22:33 +00:00
False, caption, strlen(caption));
1998-09-29 22:36:29 +00:00
}
if (bPtr->flags.pullsDown) {
XCopyArea(scr->display, scr->pullDownIndicator->pixmap,
pixmap, scr->copyGC, 0, 0, scr->pullDownIndicator->width,
scr->pullDownIndicator->height,
bPtr->view->size.width-scr->pullDownIndicator->width-4,
(bPtr->view->size.height-scr->pullDownIndicator->height)/2);
} else {
int x, y;
x = bPtr->view->size.width - scr->popUpIndicator->width - 4;
y = (bPtr->view->size.height-scr->popUpIndicator->height)/2;
XSetClipOrigin(scr->display, scr->clipGC, x, y);
XSetClipMask(scr->display, scr->clipGC, scr->popUpIndicator->mask);
XCopyArea(scr->display, scr->popUpIndicator->pixmap, pixmap,
scr->clipGC, 0, 0, scr->popUpIndicator->width,
scr->popUpIndicator->height, x, y);
}
XCopyArea(scr->display, pixmap, bPtr->view->window, scr->copyGC, 0, 0,
bPtr->view->size.width, bPtr->view->size.height, 0, 0);
XFreePixmap(scr->display, pixmap);
}
static void
handleEvents(XEvent *event, void *data)
{
PopUpButton *bPtr = (PopUpButton*)data;
CHECK_CLASS(data, WC_PopUpButton);
switch (event->type) {
case Expose:
if (event->xexpose.count!=0)
break;
paintPopUpButton(bPtr);
break;
case DestroyNotify:
destroyPopUpButton(bPtr);
break;
}
}
static void
paintMenuEntry(PopUpButton *bPtr, int index, int highlight)
{
W_Screen *scr = bPtr->view->screen;
int yo;
int width, height, itemHeight, itemCount;
1999-10-20 03:25:06 +00:00
char *title;
itemCount = WMGetArrayItemCount(bPtr->items);
if (index < 0 || index >= itemCount)
return;
1998-09-29 22:36:29 +00:00
itemHeight = bPtr->view->size.height;
width = bPtr->view->size.width;
height = itemHeight * itemCount;
1999-01-06 15:22:33 +00:00
yo = (itemHeight - WMFontHeight(scr->normalFont))/2;
1998-09-29 22:36:29 +00:00
if (!highlight) {
XClearArea(scr->display, bPtr->menuView->window, 0, index*itemHeight,
width, itemHeight, False);
return;
} else if (index < 0 && bPtr->flags.pullsDown) {
return;
}
1999-03-09 14:58:01 +00:00
XFillRectangle(scr->display, bPtr->menuView->window, WMColorGC(scr->white),
1998-09-29 22:36:29 +00:00
1, index*itemHeight+1, width-3, itemHeight-3);
1999-10-20 03:25:06 +00:00
title = WMGetPopUpButtonItem(bPtr, index);
1998-09-29 22:36:29 +00:00
W_DrawRelief(scr, bPtr->menuView->window, 0, index*itemHeight,
width, itemHeight, WRRaised);
W_PaintText(bPtr->menuView, bPtr->menuView->window, scr->normalFont, 6,
1999-10-20 03:25:06 +00:00
index*itemHeight + yo, width, WALeft, WMColorGC(scr->black),
False, title, strlen(title));
1998-09-29 22:36:29 +00:00
if (!bPtr->flags.pullsDown && index == bPtr->selectedItemIndex) {
XCopyArea(scr->display, scr->popUpIndicator->pixmap,
bPtr->menuView->window, scr->copyGC, 0, 0,
scr->popUpIndicator->width, scr->popUpIndicator->height,
width-scr->popUpIndicator->width-4,
index*itemHeight+(itemHeight-scr->popUpIndicator->height)/2);
1998-09-29 22:36:29 +00:00
}
}
Pixmap
makeMenuPixmap(PopUpButton *bPtr)
{
Pixmap pixmap;
W_Screen *scr = bPtr->view->screen;
WMMenuItem *item;
WMArrayIterator iter;
int yo, i;
1998-09-29 22:36:29 +00:00
int width, height, itemHeight;
itemHeight = bPtr->view->size.height;
width = bPtr->view->size.width;
height = itemHeight * WMGetArrayItemCount(bPtr->items);
1999-01-06 15:22:33 +00:00
yo = (itemHeight - WMFontHeight(scr->normalFont))/2;
1998-09-29 22:36:29 +00:00
pixmap = XCreatePixmap(scr->display, bPtr->view->window, width, height,
scr->depth);
1999-10-20 03:25:06 +00:00
XFillRectangle(scr->display, pixmap, WMColorGC(scr->gray), 0, 0,
width, height);
i = 0;
WM_ITERATE_ARRAY(bPtr->items, item, iter) {
1998-09-29 22:36:29 +00:00
GC gc;
1999-10-20 03:25:06 +00:00
char *text;
text = WMGetMenuItemTitle(item);
1998-09-29 22:36:29 +00:00
W_DrawRelief(scr, pixmap, 0, i*itemHeight, width, itemHeight,
WRRaised);
1999-10-20 03:25:06 +00:00
if (!WMGetMenuItemEnabled(item))
1999-03-09 14:58:01 +00:00
gc = WMColorGC(scr->darkGray);
1998-09-29 22:36:29 +00:00
else
1999-03-09 14:58:01 +00:00
gc = WMColorGC(scr->black);
1998-09-29 22:36:29 +00:00
W_PaintText(bPtr->menuView, pixmap, scr->normalFont, 6,
i*itemHeight + yo, width, WALeft, gc, False,
1999-10-20 03:25:06 +00:00
text, strlen(text));
1998-09-29 22:36:29 +00:00
if (!bPtr->flags.pullsDown && i == bPtr->selectedItemIndex) {
XCopyArea(scr->display, scr->popUpIndicator->pixmap, pixmap,
scr->copyGC, 0, 0, scr->popUpIndicator->width,
scr->popUpIndicator->height,
width-scr->popUpIndicator->width-4,
i*itemHeight+(itemHeight-scr->popUpIndicator->height)/2);
1999-10-20 03:25:06 +00:00
}
i++;
1998-09-29 22:36:29 +00:00
}
return pixmap;
}
static void
resizeMenu(PopUpButton *bPtr)
{
int height;
height = WMGetArrayItemCount(bPtr->items) * bPtr->view->size.height;
1999-03-09 14:58:01 +00:00
if (height > 0)
W_ResizeView(bPtr->menuView, bPtr->view->size.width, height);
1998-09-29 22:36:29 +00:00
}
static void
popUpMenu(PopUpButton *bPtr)
{
W_Screen *scr = bPtr->view->screen;
Window dummyW;
int x, y;
2001-01-02 14:17:26 +00:00
if (!bPtr->flags.enabled)
return;
1998-09-29 22:36:29 +00:00
if (!bPtr->menuView->flags.realized) {
W_RealizeView(bPtr->menuView);
resizeMenu(bPtr);
}
if (WMGetArrayItemCount(bPtr->items) < 1)
1998-09-29 22:36:29 +00:00
return;
XTranslateCoordinates(scr->display, bPtr->view->window, scr->rootWin,
0, 0, &x, &y, &dummyW);
if (bPtr->flags.pullsDown) {
y += bPtr->view->size.height;
} else {
y -= bPtr->view->size.height*bPtr->selectedItemIndex;
}
W_MoveView(bPtr->menuView, x, y);
XSetWindowBackgroundPixmap(scr->display, bPtr->menuView->window,
makeMenuPixmap(bPtr));
XClearWindow(scr->display, bPtr->menuView->window);
2001-01-02 14:17:26 +00:00
if (W_VIEW_WIDTH(bPtr->menuView) != W_VIEW_WIDTH(bPtr->view))
resizeMenu(bPtr);
1998-09-29 22:36:29 +00:00
W_MapView(bPtr->menuView);
bPtr->highlightedItem = 0;
1999-10-20 03:25:06 +00:00
if (!bPtr->flags.pullsDown && bPtr->selectedItemIndex < 0)
1998-09-29 22:36:29 +00:00
paintMenuEntry(bPtr, bPtr->selectedItemIndex, True);
}
static void
popDownMenu(PopUpButton *bPtr)
{
W_UnmapView(bPtr->menuView);
}
1999-01-06 15:22:33 +00:00
static void
autoScroll(void *data)
{
PopUpButton *bPtr = (PopUpButton*)data;
int scrHeight = WMWidgetScreen(bPtr)->rootView->size.height;
int repeat = 0;
int dy = 0;
if (bPtr->scrollStartY >= scrHeight-1
&& bPtr->menuView->pos.y+bPtr->menuView->size.height >= scrHeight-1) {
1999-01-06 15:22:33 +00:00
repeat = 1;
if (bPtr->menuView->pos.y+bPtr->menuView->size.height-5
<= scrHeight - 1) {
dy = scrHeight - 1
- (bPtr->menuView->pos.y+bPtr->menuView->size.height);
} else
dy = -5;
} else if (bPtr->scrollStartY <= 1 && bPtr->menuView->pos.y < 1) {
repeat = 1;
if (bPtr->menuView->pos.y+5 > 1)
dy = 1 - bPtr->menuView->pos.y;
else
dy = 5;
}
if (repeat) {
int oldItem;
W_MoveView(bPtr->menuView, bPtr->menuView->pos.x,
bPtr->menuView->pos.y + dy);
oldItem = bPtr->highlightedItem;
bPtr->highlightedItem = (bPtr->scrollStartY - bPtr->menuView->pos.y)
/ bPtr->view->size.height;
if (oldItem!=bPtr->highlightedItem) {
WMMenuItem *item;
1999-10-20 03:25:06 +00:00
1999-01-06 15:22:33 +00:00
paintMenuEntry(bPtr, oldItem, False);
if (bPtr->highlightedItem >= 0 &&
bPtr->highlightedItem < WMGetArrayItemCount(bPtr->items)) {
item = WMGetPopUpButtonMenuItem(bPtr, bPtr->highlightedItem);
paintMenuEntry(bPtr, bPtr->highlightedItem,
WMGetMenuItemEnabled(item));
} else {
bPtr->highlightedItem = -1;
}
1999-01-06 15:22:33 +00:00
}
bPtr->timer = WMAddTimerHandler(SCROLL_DELAY, autoScroll, bPtr);
} else {
bPtr->timer = NULL;
}
}
2000-04-13 21:24:28 +00:00
static void
wheelScrollUp(PopUpButton *bPtr)
{
int testIndex = bPtr->selectedItemIndex - 1;
while (testIndex>=0 && !WMGetPopUpButtonItemEnabled(bPtr, testIndex))
testIndex--;
if (testIndex != -1) {
WMSetPopUpButtonSelectedItem(bPtr, testIndex);
if (bPtr->action)
(*bPtr->action)(bPtr, bPtr->clientData);
}
}
static void
wheelScrollDown(PopUpButton *bPtr)
{
int itemCount = WMGetArrayItemCount(bPtr->items);
2000-04-13 21:24:28 +00:00
int testIndex = bPtr->selectedItemIndex + 1;
while (testIndex<itemCount && !WMGetPopUpButtonItemEnabled(bPtr, testIndex))
testIndex++;
if (testIndex != itemCount) {
WMSetPopUpButtonSelectedItem(bPtr, testIndex);
if (bPtr->action)
(*bPtr->action)(bPtr, bPtr->clientData);
}
}
1998-09-29 22:36:29 +00:00
static void
handleActionEvents(XEvent *event, void *data)
{
PopUpButton *bPtr = (PopUpButton*)data;
int oldItem;
1999-01-06 15:22:33 +00:00
int scrHeight = WMWidgetScreen(bPtr)->rootView->size.height;
1998-09-29 22:36:29 +00:00
CHECK_CLASS(data, WC_PopUpButton);
if (WMGetArrayItemCount(bPtr->items) < 1)
1998-09-29 22:36:29 +00:00
return;
switch (event->type) {
/* called for menuView */
1999-01-06 15:22:33 +00:00
case Expose:
1999-10-20 03:25:06 +00:00
paintMenuEntry(bPtr, bPtr->highlightedItem, True);
1999-01-06 15:22:33 +00:00
break;
1998-09-29 22:36:29 +00:00
case LeaveNotify:
bPtr->flags.insideMenu = 0;
if (bPtr->menuView->flags.mapped)
paintMenuEntry(bPtr, bPtr->highlightedItem, False);
bPtr->highlightedItem = -1;
break;
case EnterNotify:
bPtr->flags.insideMenu = 1;
break;
1999-01-06 15:22:33 +00:00
1998-09-29 22:36:29 +00:00
case MotionNotify:
if (bPtr->flags.insideMenu) {
oldItem = bPtr->highlightedItem;
bPtr->highlightedItem = event->xmotion.y / bPtr->view->size.height;
if (oldItem!=bPtr->highlightedItem) {
1999-10-20 03:25:06 +00:00
WMMenuItem *item;
1998-09-29 22:36:29 +00:00
paintMenuEntry(bPtr, oldItem, False);
if (bPtr->highlightedItem >= 0 &&
bPtr->highlightedItem < WMGetArrayItemCount(bPtr->items)) {
item = WMGetPopUpButtonMenuItem(bPtr, bPtr->highlightedItem);
paintMenuEntry(bPtr, bPtr->highlightedItem,
WMGetMenuItemEnabled(item));
} else {
bPtr->highlightedItem = -1;
}
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00
if (event->xmotion.y_root >= scrHeight-1
|| event->xmotion.y_root <= 1) {
bPtr->scrollStartY = event->xmotion.y_root;
if (!bPtr->timer)
autoScroll(bPtr);
} else if (bPtr->timer) {
WMDeleteTimerHandler(bPtr->timer);
bPtr->timer = NULL;
}
1998-09-29 22:36:29 +00:00
}
break;
/* called for bPtr->view */
case ButtonPress:
1999-01-06 15:22:33 +00:00
if (!bPtr->flags.enabled)
break;
2000-04-13 21:40:57 +00:00
if (event->xbutton.button==WINGsConfiguration.mouseWheelUp) {
if (!bPtr->menuView->flags.mapped && !bPtr->flags.pullsDown) {
2000-04-13 21:24:28 +00:00
wheelScrollUp(bPtr);
}
2000-04-13 21:40:57 +00:00
break;
} else if (event->xbutton.button==WINGsConfiguration.mouseWheelDown) {
if (!bPtr->menuView->flags.mapped && !bPtr->flags.pullsDown) {
wheelScrollDown(bPtr);
}
break;
}
popUpMenu(bPtr);
1998-09-29 22:36:29 +00:00
if (!bPtr->flags.pullsDown) {
bPtr->highlightedItem = bPtr->selectedItemIndex;
bPtr->flags.insideMenu = 1;
} else {
bPtr->highlightedItem = -1;
bPtr->flags.insideMenu = 0;
}
XGrabPointer(bPtr->view->screen->display, bPtr->menuView->window,
False, ButtonReleaseMask|ButtonMotionMask|EnterWindowMask
|LeaveWindowMask, GrabModeAsync, GrabModeAsync,
None, None, CurrentTime);
break;
case ButtonRelease:
2000-04-13 21:24:28 +00:00
if (event->xbutton.button==WINGsConfiguration.mouseWheelUp ||
event->xbutton.button==WINGsConfiguration.mouseWheelDown) {
break;
}
1998-09-29 22:36:29 +00:00
XUngrabPointer(bPtr->view->screen->display, event->xbutton.time);
if (!bPtr->flags.pullsDown)
popDownMenu(bPtr);
1999-01-06 15:22:33 +00:00
if (bPtr->timer) {
WMDeleteTimerHandler(bPtr->timer);
bPtr->timer = NULL;
}
1999-10-20 03:25:06 +00:00
if (bPtr->flags.insideMenu && bPtr->highlightedItem>=0) {
WMMenuItem *item;
2000-04-13 21:24:28 +00:00
1999-10-20 03:25:06 +00:00
item = WMGetPopUpButtonMenuItem(bPtr, bPtr->highlightedItem);
2000-04-13 21:24:28 +00:00
1999-10-20 03:25:06 +00:00
if (WMGetMenuItemEnabled(item)) {
1998-09-29 22:36:29 +00:00
int i;
WMSetPopUpButtonSelectedItem(bPtr, bPtr->highlightedItem);
if (bPtr->flags.pullsDown) {
for (i=0; i<MENU_BLINK_COUNT; i++) {
paintMenuEntry(bPtr, bPtr->highlightedItem, False);
XSync(bPtr->view->screen->display, 0);
wusleep(MENU_BLINK_DELAY);
paintMenuEntry(bPtr, bPtr->highlightedItem, True);
XSync(bPtr->view->screen->display, 0);
wusleep(MENU_BLINK_DELAY);
}
}
paintMenuEntry(bPtr, bPtr->highlightedItem, False);
popDownMenu(bPtr);
if (bPtr->action)
(*bPtr->action)(bPtr, bPtr->clientData);
}
}
if (bPtr->menuView->flags.mapped)
popDownMenu(bPtr);
break;
}
}
static void
destroyPopUpButton(PopUpButton *bPtr)
{
1999-01-06 15:22:33 +00:00
if (bPtr->timer) {
WMDeleteTimerHandler(bPtr->timer);
}
1999-10-20 03:25:06 +00:00
WMFreeArray(bPtr->items);
1999-10-20 03:25:06 +00:00
1998-09-29 22:36:29 +00:00
if (bPtr->caption)
1999-10-09 20:07:23 +00:00
wfree(bPtr->caption);
1998-09-29 22:36:29 +00:00
/* have to destroy explicitly because the popup is a toplevel */
W_DestroyView(bPtr->menuView);
1999-10-09 20:07:23 +00:00
wfree(bPtr);
1998-09-29 22:36:29 +00:00
}