summaryrefslogtreecommitdiff
path: root/otk/messagedialog.cc
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2003-02-16 11:59:12 +0000
committerDana Jansens <danakj@orodu.net>2003-02-16 11:59:12 +0000
commit7a41f7730dfa7e5733720f98f89c5a5906f1e786 (patch)
tree17c99ac6c1d5cc88109d1013fc638303a3f5450c /otk/messagedialog.cc
parentf325abe4e454f3c413ad91e6145b8a8c458c8758 (diff)
add otk::MessageDialog
Diffstat (limited to 'otk/messagedialog.cc')
-rw-r--r--otk/messagedialog.cc168
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();
+}
+
+}