add otk::MessageDialog
This commit is contained in:
parent
f325abe4e4
commit
7a41f7730d
8 changed files with 244 additions and 2 deletions
|
@ -37,6 +37,7 @@ surface.lo
|
|||
rendertexture.lo
|
||||
rendertest
|
||||
renderstyle.lo
|
||||
messagedialog.lo
|
||||
rendercontrol.lo
|
||||
rendercolor.lo
|
||||
otk.py
|
||||
|
|
|
@ -11,7 +11,7 @@ libotk_la_SOURCES=rendercontrol.cc truerendercontrol.cc surface.cc util.cc \
|
|||
display.cc font.cc screeninfo.cc property.cc timer.cc \
|
||||
eventdispatcher.cc eventhandler.cc ustring.cc \
|
||||
widget.cc application.cc label.cc appwidget.cc button.cc \
|
||||
otk.cc
|
||||
otk.cc messagedialog.cc
|
||||
|
||||
#focuswidget.cc focuslabel.cc
|
||||
|
||||
|
@ -21,7 +21,7 @@ includeotk_HEADERS=application.hh appwidget.hh assassin.hh button.hh \
|
|||
rect.hh rendercolor.hh rendercontrol.hh renderstyle.hh \
|
||||
rendertexture.hh screeninfo.hh size.hh strut.hh surface.hh \
|
||||
timer.hh truerendercontrol.hh ustring.hh util.hh widget.hh \
|
||||
../config.h
|
||||
messagedialog.hh ../config.h
|
||||
|
||||
EXTRA_DIST = otk.pc.in
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ void Button::release(unsigned int mouse_button)
|
|||
|
||||
styleChanged(*RenderStyle::style(screen()));
|
||||
refresh();
|
||||
|
||||
clickHandler(_mouse_button);
|
||||
}
|
||||
|
||||
void Button::buttonPressHandler(const XButtonEvent &e)
|
||||
|
|
|
@ -20,6 +20,8 @@ public:
|
|||
virtual void buttonPressHandler(const XButtonEvent &e);
|
||||
virtual void buttonReleaseHandler(const XButtonEvent &e);
|
||||
|
||||
virtual void clickHandler(unsigned int button) {(void)button;}
|
||||
|
||||
virtual void styleChanged(const RenderStyle &style);
|
||||
|
||||
private:
|
||||
|
|
168
otk/messagedialog.cc
Normal file
168
otk/messagedialog.cc
Normal file
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
66
otk/messagedialog.hh
Normal file
66
otk/messagedialog.hh
Normal file
|
@ -0,0 +1,66 @@
|
|||
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
|
||||
#ifndef __messagedialog_hh
|
||||
#define __messagedialog_hh
|
||||
|
||||
#include "widget.hh"
|
||||
#include "ustring.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace otk {
|
||||
|
||||
class Button;
|
||||
class Label;
|
||||
|
||||
class DialogButton {
|
||||
ustring _label;
|
||||
bool _default;
|
||||
public:
|
||||
DialogButton(char *label) : _label(label), _default(false)
|
||||
{}
|
||||
DialogButton(ustring label) : _label(label), _default(false)
|
||||
{}
|
||||
DialogButton(ustring label, bool def) : _label(label), _default(def)
|
||||
{}
|
||||
inline const ustring& label() const { return _label; }
|
||||
inline const bool& isDefault() const { return _default; }
|
||||
};
|
||||
|
||||
class MessageDialog : public Widget {
|
||||
public:
|
||||
MessageDialog(int screen, EventDispatcher *ed, ustring title,
|
||||
ustring caption);
|
||||
MessageDialog(EventDispatcher *ed, ustring title, ustring caption);
|
||||
MessageDialog(Widget *parent, ustring title, ustring caption);
|
||||
virtual ~MessageDialog();
|
||||
|
||||
virtual void addButton(const DialogButton &b) { _buttons.push_back(b); }
|
||||
|
||||
virtual const DialogButton& run();
|
||||
|
||||
virtual void show();
|
||||
virtual void hide();
|
||||
|
||||
virtual const DialogButton& result() const { return *_result; }
|
||||
virtual void setResult(const DialogButton &result) { _result = &result; }
|
||||
|
||||
virtual void keyPressHandler(const XKeyEvent &e);
|
||||
virtual void clientMessageHandler(const XClientMessageEvent &e);
|
||||
|
||||
private:
|
||||
static DialogButton _default_result;
|
||||
|
||||
void init(const ustring &title, const ustring &caption);
|
||||
|
||||
std::vector<DialogButton> _buttons;
|
||||
std::vector<Button *> _button_widgets;
|
||||
Label *_label;
|
||||
Widget *_button_holder;
|
||||
KeyCode _return;
|
||||
KeyCode _escape;
|
||||
const DialogButton *_result;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __messagedialog_hh
|
|
@ -15,6 +15,7 @@
|
|||
#include "rendercolor.hh"
|
||||
#include "display.hh"
|
||||
#include "font.hh"
|
||||
#include "messagedialog.hh"
|
||||
#include "rendercontrol.hh"
|
||||
#include "size.hh"
|
||||
#include "point.hh"
|
||||
|
|
|
@ -100,6 +100,8 @@ protected:
|
|||
void createWindow(bool overrideredir);
|
||||
|
||||
RenderTexture *_texture;
|
||||
|
||||
EventDispatcher *dispatcher() const { return _dispatcher; }
|
||||
|
||||
private:
|
||||
void internal_moveresize(int x, int y, int w, int h);
|
||||
|
|
Loading…
Reference in a new issue