improved dirty chain detection

This commit is contained in:
thrust26 2020-11-14 12:07:44 +01:00
parent 36a3f9843e
commit 3eb1ce9116
6 changed files with 56 additions and 44 deletions

View File

@ -147,20 +147,15 @@ void Dialog::setPosition()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Dialog::isChainDirty() const
void Dialog::setDirty()
{
bool dirty = false;
_dirty = true;
}
// Recursively check if dialog or any chick dialogs or widgets are dirty
Widget* w = _firstWidget;
while(w && !dirty)
{
dirty |= w->needsRedraw();
w = w->_next;
}
return dirty;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::setDirtyChain()
{
_dirtyChain = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -440,6 +435,7 @@ void Dialog::drawDialog()
if(isDirty())
{
//cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl;
cerr << "d";
if(clearsBackground())
{
@ -458,7 +454,7 @@ void Dialog::drawDialog()
}
else {
s.invalidate();
cerr << "invalidate " << typeid(*this).name() << endl;
//cerr << "invalidate " << typeid(*this).name() << endl;
}
if(hasBorder()) // currently only used by Dialog itself
s.frameRect(_x, _y, _w, _h, kColor);
@ -471,19 +467,6 @@ void Dialog::drawDialog()
// Draw all children
drawChain();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::drawChain()
{
Widget* w = _firstWidget;
while(w)
{
if(w->needsRedraw())
w->draw();
w = w->_next;
}
// Draw outlines for focused widgets
// Don't change focus, since this will trigger lost and received
@ -497,6 +480,23 @@ void Dialog::drawChain()
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::drawChain()
{
// Clear chain *before* drawing, because some widgets may set it again when
// being drawn (e.g. RomListWidget)
clearDirtyChain();
Widget* w = _firstWidget;
while(w)
{
if(w->needsRedraw())
w->draw();
w = w->_next;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::handleText(char text)
{

View File

@ -62,12 +62,14 @@ class Dialog : public GuiObject
virtual void saveConfig() { }
virtual void setDefaults() { }
void tick() override;
bool isChainDirty() const override;
void setDirty() override;
void setDirtyChain() override;
void redraw(bool force = false);
void drawChain() override;
void render();
void tick() override;
void addFocusWidget(Widget* w) override;
void addToFocusList(WidgetArray& list) override;
void addToFocusList(WidgetArray& list, TabWidget* w, int tabId);

View File

@ -73,7 +73,7 @@ void EditableWidget::tick()
{
_caretTimer = 0;
_caretEnabled = !_caretEnabled;
_dirty = true;
setDirty();
}
}
Widget::tick();

View File

@ -92,10 +92,12 @@ class GuiObject : public CommandReceiver
virtual bool isVisible() const = 0;
void setDirty() { _dirty = true; }
virtual void setDirty() = 0;
virtual void setDirtyChain() = 0;
void clearDirty() { _dirty = false; }
void clearDirtyChain() { _dirtyChain = false; }
bool isDirty() const { return _dirty; }
virtual bool isChainDirty() const = 0;
bool isChainDirty() const { return _dirtyChain; }
// The GUI indicates if its underlying surface needs to be redrawn
// and then re-rendered
@ -152,6 +154,7 @@ class GuiObject : public CommandReceiver
protected:
int _x{0}, _y{0}, _w{0}, _h{0};
bool _dirty{false};
bool _dirtyChain{false};
uInt32 _flags{0};
Widget* _firstWidget{nullptr};

View File

@ -52,20 +52,21 @@ Widget::~Widget()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Widget::isChainDirty() const
void Widget::setDirty()
{
bool dirty = false;
_dirty = true;
// Recursively check if widget or any child dialogs or widgets are dirty
Widget* w = _firstWidget;
// Inform the parent object that its children chain is dirty
_boss->setDirtyChain();
}
while(w && !dirty)
{
dirty |= w->needsRedraw();
w = w->_next;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Widget::setDirtyChain()
{
_dirtyChain = true;
return dirty;
// Inform the parent object that its children chain is dirty
_boss->setDirtyChain();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -98,7 +99,8 @@ void Widget::draw()
if(isDirty())
{
cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl;
//cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl;
cerr << "w";
FBSurface& s = _boss->dialog().surface();
@ -163,6 +165,10 @@ void Widget::draw()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Widget::drawChain()
{
// Clear chain *before* drawing, because some widgets may set it again when
// being drawn (e.g. RomListWidget)
clearDirtyChain();
Widget* w = _firstWidget;
while(w)
@ -508,7 +514,6 @@ void ButtonWidget::setBitmap(const uInt32* bitmap, int bmw, int bmh)
_bmh = bmh;
_bmw = bmw;
cerr << "setBitmap" << endl;
setDirty();
}

View File

@ -70,7 +70,9 @@ class Widget : public GuiObject
virtual bool handleEvent(Event::Type event) { return false; }
void tick() override;
bool isChainDirty() const override;
void setDirty() override;
void setDirtyChain() override;
void draw() override;
void drawChain() override;
void receivedFocus();