1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
5 #include "messagedialog.hh"
10 #include "property.hh"
11 #include "eventdispatcher.hh"
18 class DialogButtonWidget : public Button {
21 DialogButtonWidget(Widget *parent, MessageDialog *dia,
22 const DialogButton &b)
28 setMaxSize(Size(0,0));
30 setHighlighted(b.isDefault());
34 virtual void buttonPressHandler(const XButtonEvent &e) {
35 // limit to the left button
36 if (e.button == Button1)
37 Button::buttonPressHandler(e);
39 virtual void clickHandler(unsigned int) {
40 _dia->setResult(DialogButton(text(), isHighlighted()));
45 MessageDialog::MessageDialog(int screen, EventDispatcher *ed, ustring title,
47 : Widget(screen, ed, Widget::Vertical),
53 MessageDialog::MessageDialog(EventDispatcher *ed, ustring title,
55 : Widget(DefaultScreen(**display), ed, Widget::Vertical),
61 MessageDialog::MessageDialog(Widget *parent, ustring title, ustring caption)
62 : Widget(parent, Widget::Vertical),
68 void MessageDialog::init(const ustring &title, const ustring &caption)
70 _label = new Label(this);
72 _label->setHighlighted(true);
73 _button_holder = new Widget(this, Widget::Horizontal);
74 _button_holder->show();
75 _return = XKeysymToKeycode(**display, XStringToKeysym("Return"));
76 _escape = XKeysymToKeycode(**display, XStringToKeysym("Escape"));
78 setEventMask(eventMask() | KeyPressMask);
79 _label->setText(caption);
81 otk::Property::set(window(), otk::Property::atoms.net_wm_name,
82 otk::Property::utf8, title);
83 otk::Property::set(window(), otk::Property::atoms.wm_name,
84 otk::Property::ascii, otk::ustring(title.c_str(), false));
86 // set WM Protocols on the window
88 protocols[0] = Property::atoms.wm_protocols;
89 protocols[1] = Property::atoms.wm_delete_window;
90 XSetWMProtocols(**display, window(), protocols, 2);
93 MessageDialog::~MessageDialog()
95 if (visible()) hide();
96 delete _button_holder;
100 const DialogButton& MessageDialog::run()
106 dispatcher()->dispatchEvents();
108 Timer::dispatchTimers(); // fire pending events
113 void MessageDialog::addButton(const DialogButton &b)
115 _button_widgets.push_back(new DialogButtonWidget(_button_holder,
119 void MessageDialog::focus()
122 XSetInputFocus(**display, window(), None, CurrentTime);
125 void MessageDialog::show()
130 r = parent()->area();
132 r = Rect(Point(0, 0), display->screenInfo(screen())->size());
135 size.flags = PMinSize | PPosition | PWinGravity;
136 size.min_width = minSize().width();
137 size.min_height = minSize().height();
138 size.win_gravity = CenterGravity;
140 Size dest = minSize();
141 if (dest.width() < 200 || dest.height() < 100) {
142 if (dest.width() < 200 && dest.height() < 100) dest = Size(200, 100);
143 else if (dest.width() < 200) dest = Size(200, dest.height());
144 else dest = Size(dest.width(), 100);
148 // center it above its parent
149 move(Point(r.x() + (r.width() - dest.width()) / 2,
150 r.y() + (r.height() - dest.height()) / 2));
152 XSetWMNormalHints(**display, window(), &size);
157 void MessageDialog::hide()
160 std::for_each(_button_widgets.begin(), _button_widgets.end(),
164 void MessageDialog::keyPressHandler(const XKeyEvent &e)
166 if (e.keycode == _return) {
167 std::vector<Button *>::const_iterator it, end = _button_widgets.end();
168 for (it = _button_widgets.begin(); it != end; ++it)
169 if ((*it)->isHighlighted()) {
170 _result = DialogButton((*it)->text(), true);
174 } else if (e.keycode == _escape) {
179 void MessageDialog::clientMessageHandler(const XClientMessageEvent &e)
181 EventHandler::clientMessageHandler(e);
182 if (e.message_type == Property::atoms.wm_protocols &&
183 static_cast<Atom>(e.data.l[0]) == Property::atoms.wm_delete_window)