diff options
| author | Dana Jansens <danakj@orodu.net> | 2003-02-16 11:59:12 +0000 |
|---|---|---|
| committer | Dana Jansens <danakj@orodu.net> | 2003-02-16 11:59:12 +0000 |
| commit | 7a41f7730dfa7e5733720f98f89c5a5906f1e786 (patch) | |
| tree | 17c99ac6c1d5cc88109d1013fc638303a3f5450c /otk/messagedialog.cc | |
| parent | f325abe4e454f3c413ad91e6145b8a8c458c8758 (diff) | |
add otk::MessageDialog
Diffstat (limited to 'otk/messagedialog.cc')
| -rw-r--r-- | otk/messagedialog.cc | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/otk/messagedialog.cc b/otk/messagedialog.cc new file mode 100644 index 00000000..df004347 --- /dev/null +++ b/otk/messagedialog.cc @@ -0,0 +1,168 @@ +// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- + +#include "config.h" + +#include "messagedialog.hh" +#include "assassin.hh" +#include "button.hh" +#include "label.hh" +#include "display.hh" +#include "property.hh" +#include "eventdispatcher.hh" +#include "timer.hh" + +#include <algorithm> + +namespace otk { + +DialogButton MessageDialog::_default_result("", false); + +class DialogButtonWidget : public Button { + MessageDialog *_dia; + const DialogButton &_res; +public: + DialogButtonWidget(Widget *parent, MessageDialog *dia, + const DialogButton &b) + : Button(parent), + _dia(dia), + _res(b) + { + assert(dia); + setBevel(1); + setMaxSize(Size(0,0)); + setText(b.label()); + setHighlighted(b.isDefault()); + show(); + } + + virtual void buttonPressHandler(const XButtonEvent &e) { + // limit to the left button + if (e.button == Button1) + Button::buttonPressHandler(e); + } + virtual void clickHandler(unsigned int) { + _dia->setResult(_res); + _dia->hide(); + } +}; + +MessageDialog::MessageDialog(int screen, EventDispatcher *ed, ustring title, + ustring caption) + : Widget(screen, ed, Widget::Vertical) +{ + init(title, caption); +} + +MessageDialog::MessageDialog(EventDispatcher *ed, ustring title, + ustring caption) + : Widget(DefaultScreen(**display), ed, Widget::Vertical) +{ + init(title, caption); +} + +MessageDialog::MessageDialog(Widget *parent, ustring title, ustring caption) + : Widget(parent, Widget::Vertical) +{ + init(title, caption); +} + +void MessageDialog::init(const ustring &title, const ustring &caption) +{ + _label = new Label(this); + _label->show(); + _label->setHighlighted(true); + _button_holder = new Widget(this, Widget::Horizontal); + _button_holder->show(); + _return = XKeysymToKeycode(**display, XStringToKeysym("Return")); + _escape = XKeysymToKeycode(**display, XStringToKeysym("Escape")); + _result = &_default_result; + + setEventMask(eventMask() | KeyPressMask); + _label->setText(caption); + if (title.utf8()) + otk::Property::set(window(), otk::Property::atoms.net_wm_name, + otk::Property::utf8, title); + otk::Property::set(window(), otk::Property::atoms.wm_name, + otk::Property::ascii, otk::ustring(title.c_str(), false)); + + // set WM Protocols on the window + Atom protocols[2]; + protocols[0] = Property::atoms.wm_protocols; + protocols[1] = Property::atoms.wm_delete_window; + XSetWMProtocols(**display, window(), protocols, 2); +} + +MessageDialog::~MessageDialog() +{ + if (visible()) hide(); + delete _button_holder; + delete _label; +} + +const DialogButton& MessageDialog::run() +{ + show(); + + while (visible()) { + dispatcher()->dispatchEvents(); + if (visible()) + Timer::dispatchTimers(); // fire pending events + } + return *_result; +} + +void MessageDialog::show() +{ + std::vector<DialogButton>::const_iterator it, end = _buttons.end(); + for (it = _buttons.begin(); it != end; ++it) + _button_widgets.push_back(new DialogButtonWidget(_button_holder, + this, *it)); + + XSizeHints size; + size.flags = PMinSize; + size.min_width = minSize().width(); + size.min_height = minSize().height(); + XSetWMNormalHints(**display, window(), &size); + + Size dest = area().size(); + if (dest.width() < 200 || dest.height() < 100) { + if (dest.width() < 200 && dest.height() < 100) dest = Size(200, 100); + else if (dest.width() < 200) dest = Size(200, dest.height()); + else dest = Size(dest.width(), 100); + resize(dest); + } + + Widget::show(); +} + +void MessageDialog::hide() +{ + Widget::hide(); + std::for_each(_button_widgets.begin(), _button_widgets.end(), + PointerAssassin()); +} + +void MessageDialog::keyPressHandler(const XKeyEvent &e) +{ + if (e.keycode == _return) { + std::vector<DialogButton>::const_iterator it, end = _buttons.end(); + for (it = _buttons.begin(); it != end; ++it) + if (it->isDefault()) { + _result = &(*it); + break; + } + hide(); + } else if (e.keycode == _escape) { + hide(); + } +} + +void MessageDialog::clientMessageHandler(const XClientMessageEvent &e) +{ + EventHandler::clientMessageHandler(e); + if (e.message_type == Property::atoms.wm_protocols && + static_cast<Atom>(e.data.l[0]) == Property::atoms.wm_delete_window) + hide(); +} + +} |
