// // Copyright (C) 1996 Ben Ross // // You may distribute under the terms of the GNU General Public // License as specified in the COPYING file. // // $Id: XeOptionMenu.C,v 1.3 1999/10/21 09:10:05 ben Exp $ #include #include #define DOTWIDTH 10 #define DOTHEIGHT 6 XeOptionMenu::XeOptionMenu(XeObject* parent, const char* name, const char* className) : XeLabel(parent, name, className) { _borderWidth = 2; _justify = XeLabel::XE_JUSTIFY_LEFT; _inMenu = FALSE; _state = -1; _menu = new XeMenu(this, ""); _menu->addCallback(KrPMF(&XeOptionMenu::menuCB, this), XE_CB_ACTIVATE); XGCValues values; ulong valmask; valmask = GCForeground; values.foreground = lookupColour(this, "grey40"); _shadowGC = getGC(this, &values, valmask); values.foreground = lookupColour(this, "grey90"); _rshadowGC = getGC(this, &values, valmask); XSelectInput(gDisplay, _window, (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | ExposureMask)); setLabel("-"); } XeOptionMenu::~XeOptionMenu(void) { delete _menu; } int XeOptionMenu::doEvent(XEvent* theEvent) { switch(theEvent->type) { case Expose: doExpose(); break; case ButtonPress: case ButtonRelease: doButton((XButtonEvent *)theEvent); break; case MotionNotify: doMotion((XMotionEvent *)theEvent); break; default: XeObject::doEvent(theEvent); } return 0; } void XeOptionMenu::setLabel(const char* label) { XeLabel::setLabel(label); doExpose(); if(_autoSize) resize(_width + DOTWIDTH + 4, _height); } void XeOptionMenu::doExpose(void) { XRectangle r1 = { 0, 0, _width, _height }; drawBorder(r1, _borderWidth, _rshadowGC, _shadowGC); r1.x = _width - _borderWidth - DOTWIDTH - 2; r1.y = _height / 2 - DOTWIDTH / 2 + 1; r1.width = DOTWIDTH; r1.height = DOTHEIGHT; drawBorder(r1, 2, _rshadowGC, _shadowGC); drawText(); } void XeOptionMenu::doButton(XButtonEvent* event) { if(event->type == ButtonPress) { XRaiseWindow(gDisplay, _menu->getWindow()); int xroot, yroot; getRootCoords(xroot, yroot); _menu->move(xroot, yroot); _menu->show(); } else if(event->type == ButtonRelease) { _menu->hide(); XFlush(gDisplay); _menu->doSelect(); _inMenu = FALSE; } } void XeOptionMenu::doMotion(XMotionEvent* event) { if(event->x_root >= _menu->x() && event->y_root >= _menu->y() && event->x_root < int(_menu->x() + _menu->width()) && event->y_root < int(_menu->y() + _menu->height())) { int mx = event->x_root - _menu->x(); int my = event->y_root - _menu->y(); _inMenu = TRUE; _menu->doMotion(mx, my); } else if(_inMenu) { _menu->doLeaveNotify(); _inMenu = FALSE; } } void XeOptionMenu::menuCB(const void* data) { XeObject::CBData* cbdata = (XeObject::CBData*)data; XeMenuItem* item = ((XeMenuCBData*)cbdata->callData)->_item; _state = item->index(); setLabel(((XeTextItem*)item)->getLabel()); }