Skip to content

Commit

Permalink
libdeng2|Shell: Improvements in the widget framework
Browse files Browse the repository at this point in the history
  • Loading branch information
skyjake committed Jan 30, 2013
1 parent 36769b6 commit fd106c1
Show file tree
Hide file tree
Showing 13 changed files with 117 additions and 30 deletions.
6 changes: 6 additions & 0 deletions doomsday/libdeng2/include/de/widgets/widget.h
Expand Up @@ -46,6 +46,10 @@ class DENG2_PUBLIC Widget
void setName(String const &name);
bool hasRoot() const;
RootWidget &root() const;
bool hasFocus() const;
bool isHidden() const;
inline void hide() { show(false); }
void show(bool doShow = true);

// Tree organization.
void clear();
Expand All @@ -60,11 +64,13 @@ class DENG2_PUBLIC Widget
void notifyTree(void (Widget::*notifyFunc)());
void notifyTreeReversed(void (Widget::*notifyFunc)());
bool dispatchEvent(Event const *event, bool (Widget::*memberFunc)(Event const *));
void redraw();

// Events.
virtual void initialize();
virtual void viewResized();
virtual void update();
virtual void drawIfVisible();
virtual void draw();
virtual bool handleEvent(Event const *event);

Expand Down
9 changes: 7 additions & 2 deletions doomsday/libdeng2/src/widgets/rootwidget.cpp
Expand Up @@ -40,7 +40,7 @@ struct RootWidget::Instance

~Instance()
{
releaseRef(viewRect);
delete viewRect;
}

Vector2i viewSize() const
Expand Down Expand Up @@ -118,13 +118,18 @@ void RootWidget::initialize()

void RootWidget::draw()
{
notifyTree(&Widget::draw);
notifyTree(&Widget::drawIfVisible);

Rule::markRulesValid(); // All done for this frame.
}

bool RootWidget::processEvent(Event const *event)
{
if(focus() && focus()->handleEvent(event))
{
// The focused widget ate the event.
return true;
}
return dispatchEvent(event, &Widget::handleEvent);
}

Expand Down
33 changes: 32 additions & 1 deletion doomsday/libdeng2/src/widgets/widget.cpp
Expand Up @@ -29,13 +29,14 @@ struct Widget::Instance
Widget &self;
String name;
Widget *parent;
bool hidden;

typedef QList<Widget *> Children;
typedef QMap<String, Widget *> NamedChildren;
Children children;
NamedChildren index;

Instance(Widget &w, String const &n) : self(w), name(n), parent(0)
Instance(Widget &w, String const &n) : self(w), name(n), parent(0), hidden(false)
{}

~Instance()
Expand Down Expand Up @@ -113,6 +114,25 @@ RootWidget &Widget::root() const
throw NotFoundError("Widget::root", "No root widget found");
}

bool Widget::hasFocus() const
{
return hasRoot() && root().focus() == this;
}

bool Widget::isHidden() const
{
for(Widget const *w = this; w != 0; w = w->d->parent)
{
if(w->d->hidden) return true;
}
return false;
}

void Widget::show(bool doShow)
{
d->hidden = doShow;
}

void Widget::clear()
{
d->clear();
Expand Down Expand Up @@ -195,6 +215,9 @@ void Widget::notifyTreeReversed(void (Widget::*notifyFunc)())

bool Widget::dispatchEvent(Event const *event, bool (Widget::*memberFunc)(Event const *))
{
// Hidden widgets do not get events.
if(isHidden()) return false;

// Tree is traversed in reverse order.
for(int i = d->children.size() - 1; i >= 0; --i)
{
Expand Down Expand Up @@ -227,6 +250,14 @@ void Widget::viewResized()
void Widget::update()
{}

void Widget::drawIfVisible()
{
if(!isHidden())
{
draw();
}
}

void Widget::draw()
{}

Expand Down
2 changes: 1 addition & 1 deletion doomsday/libshell/include/de/shell/lineeditwidget.h
Expand Up @@ -58,7 +58,7 @@ class LIBSHELL_PUBLIC LineEditWidget : public TextWidget
void setCursor(int index);
int cursor() const;

Vector2i cursorPosition();
Vector2i cursorPosition() const;

bool handleControlKey(int key);

Expand Down
3 changes: 3 additions & 0 deletions doomsday/libshell/include/de/shell/textcanvas.h
Expand Up @@ -105,6 +105,7 @@ class LIBSHELL_PUBLIC TextCanvas
Size size() const;
int width() const;
int height() const;
Rectanglei rect() const;

void resize(Size const &newSize);

Expand Down Expand Up @@ -140,6 +141,8 @@ class LIBSHELL_PUBLIC TextCanvas

void drawText(Vector2i const &pos, String const &text, Char::Attribs const &attribs = Char::DefaultAttributes);

void drawLineRect(Rectanglei const &rect, Char::Attribs const &attribs = Char::DefaultAttributes);

/**
* Draws the contents of a canvas onto this canvas.
*
Expand Down
9 changes: 8 additions & 1 deletion doomsday/libshell/include/de/shell/textwidget.h
Expand Up @@ -83,6 +83,11 @@ class LIBSHELL_PUBLIC TextWidget : public QObject, public Widget
*/
TextCanvas &targetCanvas() const;

/**
* Requests the root widget to redraw all the user interface.
*/
void redraw();

/**
* Draw this widget and all its children, and show the target canvas
* afterwards. Use this in special cases for faster redrawing of portions
Expand All @@ -101,13 +106,15 @@ class LIBSHELL_PUBLIC TextWidget : public QObject, public Widget

RectangleRule &rule();

RectangleRule const &rule() const;

/**
* Returns the position of the cursor for the widget. If the widget
* has focus, this is where the cursor will be positioned.
*
* @return Cursor position.
*/
virtual Vector2i cursorPosition();
virtual Vector2i cursorPosition() const;

/**
* Adds a new action for the widget. During event processing actions are
Expand Down
9 changes: 3 additions & 6 deletions doomsday/libshell/src/labelwidget.cpp
Expand Up @@ -49,22 +49,19 @@ void LabelWidget::setLabel(String const &text, TextCanvas::Char::Attribs attribs
{
d->label = text;
d->attribs = attribs;

if(hasRoot()) root().requestDraw();
redraw();
}

void LabelWidget::setAttribs(TextCanvas::Char::Attribs const &attribs)
{
d->attribs = attribs;

if(hasRoot()) root().requestDraw();
redraw();
}

void LabelWidget::setAlignment(Alignment align)
{
d->align = align;

if(hasRoot()) root().requestDraw();
redraw();
}

String LabelWidget::label() const
Expand Down
1 change: 1 addition & 0 deletions doomsday/libshell/src/libshell.cpp
Expand Up @@ -20,5 +20,6 @@

namespace de {
namespace shell {

} // namespace shell
} // namespace de
5 changes: 3 additions & 2 deletions doomsday/libshell/src/lineeditwidget.cpp
Expand Up @@ -228,7 +228,7 @@ void LineEditWidget::setPrompt(String const &promptText)
}
}

Vector2i LineEditWidget::cursorPosition()
Vector2i LineEditWidget::cursorPosition() const
{
de::Rectanglei pos = rule().recti();
return pos.topLeft + Vector2i(d->prompt.size(), 0) + d->lineCursorPos();
Expand All @@ -247,7 +247,8 @@ void LineEditWidget::draw()
// Temporary buffer for drawing.
TextCanvas buf(pos.size());

TextCanvas::Char::Attribs attr = TextCanvas::Char::Reverse;
TextCanvas::Char::Attribs attr =
(hasFocus()? TextCanvas::Char::Reverse : TextCanvas::Char::DefaultAttributes);
buf.clear(TextCanvas::Char(' ', attr));

buf.drawText(Vector2i(0, 0), d->prompt, attr | TextCanvas::Char::Bold);
Expand Down
31 changes: 31 additions & 0 deletions doomsday/libshell/src/textcanvas.cpp
Expand Up @@ -121,6 +121,11 @@ int TextCanvas::height() const
return d->size.y;
}

Rectanglei TextCanvas::rect() const
{
return Rectanglei(Vector2i(0, 0), size());
}

void TextCanvas::resize(Size const &newSize)
{
d->resize(newSize);
Expand Down Expand Up @@ -186,6 +191,32 @@ void TextCanvas::drawText(Vector2i const &pos, String const &text, Char::Attribs
}
}

void TextCanvas::drawLineRect(Rectanglei const &rect, Char::Attribs const &attribs)
{
Char const corner('+', attribs);
Char const hEdge ('-', attribs);
Char const vEdge ('|', attribs);

// Horizontal edges.
for(int x = 1; x < rect.width() - 1; ++x)
{
put(rect.topLeft + Vector2i(x, 0), hEdge);
put(rect.bottomLeft() + Vector2i(x, -1), hEdge);
}

// Vertical edges.
for(int y = 1; y < rect.width() - 1; ++y)
{
put(rect.topLeft + Vector2i(0, y), vEdge);
put(rect.topRight() + Vector2i(-1, y), vEdge);
}

put(rect.topLeft, corner);
put(rect.topRight() - Vector2i(1, 0), corner);
put(rect.bottomRight - Vector2i(1, 1), corner);
put(rect.bottomLeft() - Vector2i(0, 1), corner);
}

void TextCanvas::draw(TextCanvas const &canvas, Coord const &topLeft)
{
for(int y = 0; y < canvas.d->size.y; ++y)
Expand Down
29 changes: 22 additions & 7 deletions doomsday/libshell/src/textwidget.cpp
Expand Up @@ -35,7 +35,7 @@ struct TextWidget::Instance

~Instance()
{
releaseRef(rule);
delete rule;
foreach(Action *act, actions) delete act;
}
};
Expand Down Expand Up @@ -70,17 +70,26 @@ TextCanvas &TextWidget::targetCanvas() const
return *d->canvas;
}

void TextWidget::redraw()
{
if(hasRoot()) root().requestDraw();
}

void TextWidget::drawAndShow()
{
draw();
notifyTree(&Widget::draw);
targetCanvas().show();
if(!isHidden())
{
draw();
notifyTree(&Widget::drawIfVisible);
targetCanvas().show();
}
}

void TextWidget::setRule(RectangleRule *rule)
{
releaseRef(d->rule);
d->rule = holdRef(rule);
DENG2_ASSERT(rule != 0);
delete d->rule;
d->rule = rule;
}

RectangleRule &TextWidget::rule()
Expand All @@ -89,7 +98,13 @@ RectangleRule &TextWidget::rule()
return *d->rule;
}

Vector2i TextWidget::cursorPosition()
RectangleRule const &TextWidget::rule() const
{
DENG2_ASSERT(d->rule != 0);
return *d->rule;
}

Vector2i TextWidget::cursorPosition() const
{
return Vector2i(floor(rule().left()->value()),
floor(rule().top()->value()));
Expand Down
5 changes: 0 additions & 5 deletions doomsday/tools/shell/shell-text/src/logwidget.cpp
Expand Up @@ -160,8 +160,3 @@ void LogWidget::draw()

targetCanvas().draw(buf, pos.topLeft);
}

void LogWidget::redraw()
{
drawAndShow();
}
5 changes: 0 additions & 5 deletions doomsday/tools/shell/shell-text/src/logwidget.h
Expand Up @@ -24,8 +24,6 @@

class LogWidget : public de::shell::TextWidget
{
Q_OBJECT

public:
LogWidget(de::String const &name = "");
virtual ~LogWidget();
Expand All @@ -38,9 +36,6 @@ class LogWidget : public de::shell::TextWidget

void draw();

public slots:
void redraw();

private:
struct Instance;
Instance *d;
Expand Down

0 comments on commit fd106c1

Please sign in to comment.