mirror of https://github.com/stella-emu/stella.git
improved dirty chain detection
This commit is contained in:
parent
36a3f9843e
commit
3eb1ce9116
|
@ -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;
|
void Dialog::setDirtyChain()
|
||||||
|
{
|
||||||
while(w && !dirty)
|
_dirtyChain = true;
|
||||||
{
|
|
||||||
dirty |= w->needsRedraw();
|
|
||||||
w = w->_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dirty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -440,6 +435,7 @@ void Dialog::drawDialog()
|
||||||
if(isDirty())
|
if(isDirty())
|
||||||
{
|
{
|
||||||
//cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl;
|
//cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl;
|
||||||
|
cerr << "d";
|
||||||
|
|
||||||
if(clearsBackground())
|
if(clearsBackground())
|
||||||
{
|
{
|
||||||
|
@ -458,7 +454,7 @@ void Dialog::drawDialog()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
s.invalidate();
|
s.invalidate();
|
||||||
cerr << "invalidate " << typeid(*this).name() << endl;
|
//cerr << "invalidate " << typeid(*this).name() << endl;
|
||||||
}
|
}
|
||||||
if(hasBorder()) // currently only used by Dialog itself
|
if(hasBorder()) // currently only used by Dialog itself
|
||||||
s.frameRect(_x, _y, _w, _h, kColor);
|
s.frameRect(_x, _y, _w, _h, kColor);
|
||||||
|
@ -471,19 +467,6 @@ void Dialog::drawDialog()
|
||||||
|
|
||||||
// Draw all children
|
// Draw all children
|
||||||
drawChain();
|
drawChain();
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Dialog::drawChain()
|
|
||||||
{
|
|
||||||
Widget* w = _firstWidget;
|
|
||||||
|
|
||||||
while(w)
|
|
||||||
{
|
|
||||||
if(w->needsRedraw())
|
|
||||||
w->draw();
|
|
||||||
w = w->_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw outlines for focused widgets
|
// Draw outlines for focused widgets
|
||||||
// Don't change focus, since this will trigger lost and received
|
// 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)
|
void Dialog::handleText(char text)
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,12 +62,14 @@ class Dialog : public GuiObject
|
||||||
virtual void saveConfig() { }
|
virtual void saveConfig() { }
|
||||||
virtual void setDefaults() { }
|
virtual void setDefaults() { }
|
||||||
|
|
||||||
void tick() override;
|
void setDirty() override;
|
||||||
bool isChainDirty() const override;
|
void setDirtyChain() override;
|
||||||
void redraw(bool force = false);
|
void redraw(bool force = false);
|
||||||
void drawChain() override;
|
void drawChain() override;
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
|
void tick() override;
|
||||||
|
|
||||||
void addFocusWidget(Widget* w) override;
|
void addFocusWidget(Widget* w) override;
|
||||||
void addToFocusList(WidgetArray& list) override;
|
void addToFocusList(WidgetArray& list) override;
|
||||||
void addToFocusList(WidgetArray& list, TabWidget* w, int tabId);
|
void addToFocusList(WidgetArray& list, TabWidget* w, int tabId);
|
||||||
|
|
|
@ -73,7 +73,7 @@ void EditableWidget::tick()
|
||||||
{
|
{
|
||||||
_caretTimer = 0;
|
_caretTimer = 0;
|
||||||
_caretEnabled = !_caretEnabled;
|
_caretEnabled = !_caretEnabled;
|
||||||
_dirty = true;
|
setDirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Widget::tick();
|
Widget::tick();
|
||||||
|
|
|
@ -92,10 +92,12 @@ class GuiObject : public CommandReceiver
|
||||||
|
|
||||||
virtual bool isVisible() const = 0;
|
virtual bool isVisible() const = 0;
|
||||||
|
|
||||||
void setDirty() { _dirty = true; }
|
virtual void setDirty() = 0;
|
||||||
|
virtual void setDirtyChain() = 0;
|
||||||
void clearDirty() { _dirty = false; }
|
void clearDirty() { _dirty = false; }
|
||||||
|
void clearDirtyChain() { _dirtyChain = false; }
|
||||||
bool isDirty() const { return _dirty; }
|
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
|
// The GUI indicates if its underlying surface needs to be redrawn
|
||||||
// and then re-rendered
|
// and then re-rendered
|
||||||
|
@ -152,6 +154,7 @@ class GuiObject : public CommandReceiver
|
||||||
protected:
|
protected:
|
||||||
int _x{0}, _y{0}, _w{0}, _h{0};
|
int _x{0}, _y{0}, _w{0}, _h{0};
|
||||||
bool _dirty{false};
|
bool _dirty{false};
|
||||||
|
bool _dirtyChain{false};
|
||||||
uInt32 _flags{0};
|
uInt32 _flags{0};
|
||||||
|
|
||||||
Widget* _firstWidget{nullptr};
|
Widget* _firstWidget{nullptr};
|
||||||
|
|
|
@ -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
|
// Inform the parent object that its children chain is dirty
|
||||||
Widget* w = _firstWidget;
|
_boss->setDirtyChain();
|
||||||
|
}
|
||||||
|
|
||||||
while(w && !dirty)
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
{
|
void Widget::setDirtyChain()
|
||||||
dirty |= w->needsRedraw();
|
{
|
||||||
w = w->_next;
|
_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())
|
if(isDirty())
|
||||||
{
|
{
|
||||||
cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl;
|
//cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl;
|
||||||
|
cerr << "w";
|
||||||
|
|
||||||
FBSurface& s = _boss->dialog().surface();
|
FBSurface& s = _boss->dialog().surface();
|
||||||
|
|
||||||
|
@ -163,6 +165,10 @@ void Widget::draw()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Widget::drawChain()
|
void Widget::drawChain()
|
||||||
{
|
{
|
||||||
|
// Clear chain *before* drawing, because some widgets may set it again when
|
||||||
|
// being drawn (e.g. RomListWidget)
|
||||||
|
clearDirtyChain();
|
||||||
|
|
||||||
Widget* w = _firstWidget;
|
Widget* w = _firstWidget;
|
||||||
|
|
||||||
while(w)
|
while(w)
|
||||||
|
@ -508,7 +514,6 @@ void ButtonWidget::setBitmap(const uInt32* bitmap, int bmw, int bmh)
|
||||||
_bmh = bmh;
|
_bmh = bmh;
|
||||||
_bmw = bmw;
|
_bmw = bmw;
|
||||||
|
|
||||||
cerr << "setBitmap" << endl;
|
|
||||||
setDirty();
|
setDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,9 @@ class Widget : public GuiObject
|
||||||
virtual bool handleEvent(Event::Type event) { return false; }
|
virtual bool handleEvent(Event::Type event) { return false; }
|
||||||
|
|
||||||
void tick() override;
|
void tick() override;
|
||||||
bool isChainDirty() const override;
|
|
||||||
|
void setDirty() override;
|
||||||
|
void setDirtyChain() override;
|
||||||
void draw() override;
|
void draw() override;
|
||||||
void drawChain() override;
|
void drawChain() override;
|
||||||
void receivedFocus();
|
void receivedFocus();
|
||||||
|
|
Loading…
Reference in New Issue