diff options
| author | Felix Domke <tmbinc@elitedvb.net> | 2005-01-09 16:29:34 +0000 |
|---|---|---|
| committer | Felix Domke <tmbinc@elitedvb.net> | 2005-01-09 16:29:34 +0000 |
| commit | ba02fb4aced5868d047a5bffbd2ed87583daee4d (patch) | |
| tree | bcfea66b1f7fd2212539a99abc074de1424ac9a0 /lib/gui | |
| parent | 2494509cd031727d92c6556089c99711d16d8af9 (diff) | |
| download | enigma2-ba02fb4aced5868d047a5bffbd2ed87583daee4d.tar.gz enigma2-ba02fb4aced5868d047a5bffbd2ed87583daee4d.zip | |
- add more python stuff
- fix some gui/gdi
- add eslider
- improve windowstyle
Diffstat (limited to 'lib/gui')
| -rw-r--r-- | lib/gui/Makefile.am | 2 | ||||
| -rw-r--r-- | lib/gui/ebutton.cpp | 14 | ||||
| -rw-r--r-- | lib/gui/ebutton.h | 2 | ||||
| -rw-r--r-- | lib/gui/elabel.cpp | 15 | ||||
| -rw-r--r-- | lib/gui/eslider.cpp | 56 | ||||
| -rw-r--r-- | lib/gui/eslider.h | 24 | ||||
| -rw-r--r-- | lib/gui/ewidget.cpp | 81 | ||||
| -rw-r--r-- | lib/gui/ewidget.h | 19 | ||||
| -rw-r--r-- | lib/gui/ewidgetdesktop.cpp | 5 | ||||
| -rw-r--r-- | lib/gui/ewidgetdesktop.h | 1 | ||||
| -rw-r--r-- | lib/gui/ewindow.cpp | 35 | ||||
| -rw-r--r-- | lib/gui/ewindow.h | 2 | ||||
| -rw-r--r-- | lib/gui/ewindowstyle.cpp | 53 | ||||
| -rw-r--r-- | lib/gui/ewindowstyle.h | 16 |
14 files changed, 291 insertions, 34 deletions
diff --git a/lib/gui/Makefile.am b/lib/gui/Makefile.am index a686e1ca..1b175c9a 100644 --- a/lib/gui/Makefile.am +++ b/lib/gui/Makefile.am @@ -5,5 +5,5 @@ INCLUDES = \ noinst_LIBRARIES = libenigma_gui.a libenigma_gui_a_SOURCES = \ - ebutton.cpp elabel.cpp ewidget.cpp ewidgetdesktop.cpp ewindow.cpp ewindowstyle.cpp + ebutton.cpp elabel.cpp eslider.cpp ewidget.cpp ewidgetdesktop.cpp ewindow.cpp ewindowstyle.cpp diff --git a/lib/gui/ebutton.cpp b/lib/gui/ebutton.cpp index 5c136abd..effcf1f6 100644 --- a/lib/gui/ebutton.cpp +++ b/lib/gui/ebutton.cpp @@ -6,13 +6,25 @@ eButton::eButton(eWidget *parent): eLabel(parent) void eButton::push() { - selected(); +// selected(); } int eButton::event(int event, void *data, void *data2) { switch (event) { + case evtPaint: + { + gPainter &painter = *(gPainter*)data2; + ePtr<eWindowStyle> style; + + getStyle(style); + + eLabel::event(event, data, data2); + style->drawButtonFrame(painter, eRect(ePoint(0, 0), size())); + + return 0; + } default: break; } diff --git a/lib/gui/ebutton.h b/lib/gui/ebutton.h index 31c9cb3c..25087077 100644 --- a/lib/gui/ebutton.h +++ b/lib/gui/ebutton.h @@ -7,7 +7,7 @@ class eButton: public eLabel { public: eButton(eWidget *parent); - Signal0<void> selected; +// Signal0<void> selected; void push(); protected: diff --git a/lib/gui/elabel.cpp b/lib/gui/elabel.cpp index f133b661..f9dcf31b 100644 --- a/lib/gui/elabel.cpp +++ b/lib/gui/elabel.cpp @@ -11,15 +11,18 @@ int eLabel::event(int event, void *data, void *data2) { case evtPaint: { + ePtr<eWindowStyle> style; + + getStyle(style); + + eWidget::event(event, data, data2); + gPainter &painter = *(gPainter*)data2; - ePtr<gFont> fnt = new gFont("Arial", 70); + ePtr<gFont> fnt = new gFont("Arial", 14); painter.setFont(fnt); - painter.setBackgroundColor(gColor(0x10)); - painter.setForegroundColor(gColor(0x1f)); - painter.clear(); - painter.setBackgroundColor(gColor(0x1f)); - painter.setForegroundColor(gColor(0x10)); + style->setForegroundStyle(painter); painter.renderText(eRect(0, 0, size().width(), size().height()), m_text); + return 0; } case evtChangedText: diff --git a/lib/gui/eslider.cpp b/lib/gui/eslider.cpp new file mode 100644 index 00000000..20b3ab47 --- /dev/null +++ b/lib/gui/eslider.cpp @@ -0,0 +1,56 @@ +#include <lib/gui/eslider.h> + +eSlider::eSlider(eWidget *parent): eWidget(parent) +{ +} + +int eSlider::event(int event, void *data, void *data2) +{ + switch (event) + { + case evtPaint: + { + ePtr<eWindowStyle> style; + gPainter &painter = *(gPainter*)data2; + + + getStyle(style); + style->paintBackground(painter, ePoint(0, 0), size()); + style->setForegroundStyle(painter); + painter.fill(m_currently_filled); + + return 0; + } + case evtChangedSlider: + { + + int num_pix = 0; + if (m_min < m_max) + num_pix = size().width() * m_value / (m_max - m_min); + gRegion old_currently_filled = m_currently_filled; + m_currently_filled = eRect(0, 0, num_pix, size().height()); + + // redraw what *was* filled before and now isn't. + invalidate(m_currently_filled - old_currently_filled); + // redraw what wasn't filled before and is now. + invalidate(old_currently_filled - m_currently_filled); + + return 0; + } + default: + return eWidget::event(event, data, data2); + } +} + +void eSlider::setValue(int value) +{ + m_value = value; + event(evtChangedSlider); +} + +void eSlider::setRange(int min, int max) +{ + m_min = min; + m_max = max; + event(evtChangedSlider); +} diff --git a/lib/gui/eslider.h b/lib/gui/eslider.h new file mode 100644 index 00000000..5b7b59f0 --- /dev/null +++ b/lib/gui/eslider.h @@ -0,0 +1,24 @@ +#ifndef __lib_gui_eslider_h +#define __lib_gui_eslider_h + +#include <lib/gui/ewidget.h> + +class eSlider: public eWidget +{ +public: + eSlider(eWidget *parent); + void setValue(int val); + void setRange(int min, int max); +protected: + int event(int event, void *data=0, void *data2=0); +private: + enum eSliderEvent + { + evtChangedSlider = evtUserWidget + }; + int m_min, m_max, m_value; + + gRegion m_currently_filled; +}; + +#endif diff --git a/lib/gui/ewidget.cpp b/lib/gui/ewidget.cpp index 89fbfe95..3ebac357 100644 --- a/lib/gui/ewidget.cpp +++ b/lib/gui/ewidget.cpp @@ -3,34 +3,68 @@ extern void dumpRegion(const gRegion ®ion); -eWidget::eWidget(eWidget *parent): m_parent(parent) +eWidget::eWidget(eWidget *parent): m_parent(parent ? parent->child() : 0) { m_vis = 0; m_desktop = 0; - if (parent) + if (m_parent) m_vis = wVisShow; - if (parent) - parent->m_childs.push_back(this); + if (m_parent) + { + m_parent->m_childs.push_back(this); + m_parent->getStyle(m_style); + } } void eWidget::move(ePoint pos) { + if (m_position == pos) + return; + m_position = pos; + /* we invalidate before and after the move to + cause a correct redraw. The area which is + included both before and after isn't redrawn + twice because a invalidate doesn't immediately + redraws the region. */ + invalidate(); event(evtChangedPosition); + recalcClipRegionsWhenVisible(); + invalidate(); } void eWidget::resize(eSize size) { + /* same strategy as with move: we first check if + the size changed at all, and if it did, we + invalidate both the old and new area. + TODO: check if either the old or new area + fits into the other completely, and invalidate + only once. */ + eSize old_size = m_size; event(evtWillChangeSize, &size); + if (old_size == m_size) + return; + + invalidate(); event(evtChangedSize); + recalcClipRegionsWhenVisible(); + invalidate(); } void eWidget::invalidate(const gRegion ®ion) { - gRegion res = /* region & */ m_visible_with_childs; + /* we determine the area to redraw, and re-position this + area to the absolute position, and then call the + desktop's invalidate() with that, which adds this + area into the dirty region. */ + gRegion res = m_visible_with_childs; + if (region.valid()) + res &= region; + if (res.empty()) return; @@ -103,10 +137,14 @@ void eWidget::destruct() eWidget::~eWidget() { + if (m_parent) + m_parent->m_childs.remove(this); + /* destroy all childs */ ePtrList<eWidget>::iterator i(m_childs.begin()); while (i != m_childs.end()) { + (*i)->m_parent = 0; delete *i; i = m_childs.erase(i); } @@ -129,24 +167,45 @@ void eWidget::doPaint(gPainter &painter, const gRegion &r) /* check if there's anything for us to paint */ region &= m_visible_region; - painter.resetClip(region); - event(evtPaint, ®ion, &painter); + if (!region.empty()) + { + painter.resetClip(region); + event(evtPaint, ®ion, &painter); + } painter.moveOffset(-position()); } +void eWidget::recalcClipRegionsWhenVisible() +{ + eWidget *t = this; + do + { + if (!(t->m_vis & wVisShow)) + break; + if (t->m_desktop) + { + t->m_desktop->recalcClipRegions(); + break; + } + t = t->m_parent; + assert(t); + } while(1); +} + int eWidget::event(int event, void *data, void *data2) { switch (event) { case evtPaint: { - static int counter = 0x18; gPainter &painter = *(gPainter*)data2; -// eDebug("eWidget::evtPaint %d", counter); + +// eDebug("eWidget::evtPaint"); // dumpRegion(*(gRegion*)data); - painter.setBackgroundColor(gColor(++counter)); - painter.clear(); + ePtr<eWindowStyle> style; + if (!getStyle(style)) + style->paintBackground(painter, ePoint(0, 0), size()); break; } case evtKey: diff --git a/lib/gui/ewidget.h b/lib/gui/ewidget.h index a551b8a3..fa8cd8ca 100644 --- a/lib/gui/ewidget.h +++ b/lib/gui/ewidget.h @@ -3,6 +3,9 @@ #include <lib/gdi/grc.h> /* for gRegion */ #include <lib/base/eptrlist.h> /* for eSmartPtrList */ +#include <lib/gui/ewindowstyle.h> /* for eWindowStyle */ + +class eWindowStyle; class eWidget { @@ -17,11 +20,21 @@ public: eSize size() const { return m_size; } void invalidate(const gRegion ®ion = gRegion::invalidRegion()); + + /* the window were to attach childs to. Normally, this + is "this", but it can be overridden in case a widget + has a "client area", which is implemented as a child + widget. eWindow overrides this, for example. */ + virtual eWidget *child() { return this; } void show(); void hide(); void destruct(); + + int getStyle(ePtr<eWindowStyle> &style) { if (!m_style) return 1; style = m_style; return 0; } + void setStyle(eWindowStyle *style) { m_style = style; } + private: eWidgetDesktop *m_desktop; @@ -33,12 +46,14 @@ private: int m_vis; ePtrList<eWidget> m_childs; - eWidget *m_parent; ePoint m_position; eSize m_size; + eWidget *m_parent; + ePtr<eWindowStyle> m_style; void doPaint(gPainter &painter, const gRegion ®ion); + void recalcClipRegionsWhenVisible(); protected: virtual ~eWidget(); public: @@ -63,4 +78,6 @@ public: virtual int event(int event, void *data = 0, void *data2 = 0); }; +extern eWidgetDesktop *getDesktop(); + #endif diff --git a/lib/gui/ewidgetdesktop.cpp b/lib/gui/ewidgetdesktop.cpp index 10c92b71..ff913680 100644 --- a/lib/gui/ewidgetdesktop.cpp +++ b/lib/gui/ewidgetdesktop.cpp @@ -11,6 +11,11 @@ void eWidgetDesktop::addRootWidget(eWidget *root, int top) root->m_desktop = this; } +void eWidgetDesktop::removeRootWidget(eWidget *root) +{ + m_root.remove(root); +} + void eWidgetDesktop::calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible) { /* start with our clip region, clipped with the parent's */ diff --git a/lib/gui/ewidgetdesktop.h b/lib/gui/ewidgetdesktop.h index 197693f8..42e6b61e 100644 --- a/lib/gui/ewidgetdesktop.h +++ b/lib/gui/ewidgetdesktop.h @@ -16,6 +16,7 @@ public: eWidgetDesktop(eSize screen); ~eWidgetDesktop(); void addRootWidget(eWidget *root, int top); + void removeRootWidget(eWidget *root); void recalcClipRegions(); void invalidate(const gRegion ®ion); diff --git a/lib/gui/ewindow.cpp b/lib/gui/ewindow.cpp index 1afee2ee..630a8aa3 100644 --- a/lib/gui/ewindow.cpp +++ b/lib/gui/ewindow.cpp @@ -5,10 +5,18 @@ eWindow::eWindow(eWidgetDesktop *desktop): eWidget(0) { + setStyle(new eWindowStyleSimple()); + + /* we are the parent for the child window. */ + /* as we are in the constructor, this is thread safe. */ + m_child = this; m_child = new eWidget(this); desktop->addRootWidget(this, 0); - - m_style = new eWindowStyleSimple(); +} + +eWindow::~eWindow() +{ + getDesktop()->removeRootWidget(this); } void eWindow::setTitle(const std::string &string) @@ -25,18 +33,25 @@ int eWindow::event(int event, void *data, void *data2) { case evtWillChangeSize: { - const eSize &new_size = *static_cast<eSize*>(data); - eDebug("eWindow::evtWillChangeSize to %d %d", new_size.width(), new_size.height()); - if (m_style) - m_style->handleNewSize(this, new_size); + ePtr<eWindowStyle> style; + if (!getStyle(style)) + { + const eSize &new_size = *static_cast<eSize*>(data); + eDebug("eWindow::evtWillChangeSize to %d %d", new_size.width(), new_size.height()); + style->handleNewSize(this, new_size); + } break; } case evtPaint: { - gPainter &painter = *static_cast<gPainter*>(data2); - painter.setBackgroundColor(gColor(0x18)); - painter.clear(); - break; + ePtr<eWindowStyle> style; + if (!getStyle(style)) + { + gPainter &painter = *static_cast<gPainter*>(data2); + style->paintWindowDecoration(this, painter, m_title); + } else + eDebug("no style :("); + return 0; } default: break; diff --git a/lib/gui/ewindow.h b/lib/gui/ewindow.h index 671a0079..f5bcd51a 100644 --- a/lib/gui/ewindow.h +++ b/lib/gui/ewindow.h @@ -11,6 +11,7 @@ class eWindow: public eWidget friend class eWindowStyle; public: eWindow(eWidgetDesktop *desktop); + ~eWindow(); void setTitle(const std::string &string); eWidget *child() { return m_child; } protected: @@ -22,7 +23,6 @@ protected: private: std::string m_title; eWidget *m_child; - ePtr<eWindowStyle> m_style; }; #endif diff --git a/lib/gui/ewindowstyle.cpp b/lib/gui/ewindowstyle.cpp index 932a3102..778291c7 100644 --- a/lib/gui/ewindowstyle.cpp +++ b/lib/gui/ewindowstyle.cpp @@ -3,11 +3,23 @@ #include <lib/gui/ewindow.h> #include <lib/gui/ewindowstyle.h> + +eWindowStyle::~eWindowStyle() {} + DEFINE_REF(eWindowStyleSimple); eWindowStyleSimple::eWindowStyleSimple() { - m_border_left = m_border_right = m_border_top = m_border_bottom = 10; + m_border_left = m_border_right = m_border_bottom = 1; + m_border_top = 30; + + m_fnt = new gFont("Arial", 25); + + m_border_color_tl = gColor(0x14); + m_border_color_br = gColor(0x1c); + m_title_color_back = gColor(0x20); + m_title_color = gColor(0x2f); + m_background_color = gColor(0x18); } void eWindowStyleSimple::handleNewSize(eWindow *wnd, const eSize &size) @@ -21,3 +33,42 @@ void eWindowStyleSimple::handleNewSize(eWindow *wnd, const eSize &size) child->move(ePoint(m_border_left, m_border_top)); child->resize(eSize(size.width() - m_border_left - m_border_right, size.height() - m_border_top - m_border_bottom)); } + +void eWindowStyleSimple::paintWindowDecoration(eWindow *wnd, gPainter &painter, const std::string &title) +{ + painter.setBackgroundColor(m_title_color_back); + painter.setForegroundColor(m_title_color); + painter.clear(); + painter.setFont(m_fnt); + painter.renderText(eRect(1, 1, wnd->size().width() - 2, m_border_top - 2), title); + + eRect frame(ePoint(0, 0), wnd->size()); + painter.setForegroundColor(m_border_color_tl); + painter.line(frame.topLeft1(), frame.topRight1()); + painter.line(frame.topRight1(), frame.bottomRight1()); + painter.setForegroundColor(m_border_color_br); + painter.line(frame.bottomRight1(), frame.bottomLeft1()); + painter.line(frame.bottomLeft1(), frame.topLeft1()); +} + +void eWindowStyleSimple::paintBackground(gPainter &painter, const ePoint &offset, const eSize &size) +{ + eDebug("eWindowStyleSimple::paintBackground"); + painter.setBackgroundColor(m_background_color); + painter.clear(); +} + +void eWindowStyleSimple::setForegroundStyle(gPainter &painter) +{ + painter.setForegroundColor(gColor(0x1F)); +} + +void eWindowStyleSimple::drawButtonFrame(gPainter &painter, const eRect &frame) +{ + painter.setForegroundColor(m_border_color_tl); + painter.line(frame.topLeft1(), frame.topRight1()); + painter.line(frame.topRight1(), frame.bottomRight1()); + painter.setForegroundColor(m_border_color_br); + painter.line(frame.bottomRight1(), frame.bottomLeft1()); + painter.line(frame.bottomLeft1(), frame.topLeft1()); +} diff --git a/lib/gui/ewindowstyle.h b/lib/gui/ewindowstyle.h index 02f155af..d5da5a34 100644 --- a/lib/gui/ewindowstyle.h +++ b/lib/gui/ewindowstyle.h @@ -3,6 +3,7 @@ class eWindow; class eSize; +class gFont; #include <lib/base/object.h> @@ -10,15 +11,28 @@ class eWindowStyle: public iObject { public: virtual void handleNewSize(eWindow *wnd, const eSize &size) = 0; + virtual void paintWindowDecoration(eWindow *wnd, gPainter &painter, const std::string &title) = 0; + virtual void paintBackground(gPainter &painter, const ePoint &offset, const eSize &size) = 0; + virtual void setForegroundStyle(gPainter &painter) = 0; + virtual void drawButtonFrame(gPainter &painter, const eRect &frame) = 0; + virtual ~eWindowStyle() = 0; }; class eWindowStyleSimple: public eWindowStyle { DECLARE_REF; +private: + ePtr<gFont> m_fnt; + gColor m_border_color_tl, m_border_color_br, m_title_color_back, m_title_color, m_background_color; + + int m_border_top, m_border_left, m_border_right, m_border_bottom; public: eWindowStyleSimple(); void handleNewSize(eWindow *wnd, const eSize &size); - int m_border_top, m_border_left, m_border_right, m_border_bottom; + void paintWindowDecoration(eWindow *wnd, gPainter &painter, const std::string &title); + void paintBackground(gPainter &painter, const ePoint &offset, const eSize &size); + void setForegroundStyle(gPainter &painter); + void drawButtonFrame(gPainter &painter, const eRect &frame); }; #endif |
