mirror of https://github.com/stella-emu/stella.git
initial commit for #719
This commit is contained in:
parent
eae7808ddf
commit
e7b7bfa3cd
|
@ -439,7 +439,7 @@ void FrameBuffer::update(bool force)
|
|||
force = force || myOSystem.launcher().needsRedraw();
|
||||
if(force)
|
||||
{
|
||||
clear();
|
||||
//clear();
|
||||
myOSystem.launcher().draw(force);
|
||||
}
|
||||
break; // EventHandlerState::LAUNCHER
|
||||
|
|
|
@ -621,5 +621,5 @@ void ContextMenu::drawDialog()
|
|||
s.drawBitmap(_downImg, ((_w-_x)>>1)-4, (_rowHeight>>1)+y-4, _scrollDnColor, _arrowSize);
|
||||
}
|
||||
|
||||
setDirty();
|
||||
clearDirty();
|
||||
}
|
||||
|
|
|
@ -149,6 +149,35 @@ void Dialog::center()
|
|||
positionAt(instance().settings().getInt("dialogpos"));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::setDirty()
|
||||
{
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Dialog::isDirty() const
|
||||
{
|
||||
return _dirty;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Dialog::isChainDirty() const
|
||||
{
|
||||
bool dirty = false;
|
||||
|
||||
// Check if widget or any subwidgets are dirty
|
||||
Widget* w = _firstWidget;
|
||||
|
||||
while(!dirty && w)
|
||||
{
|
||||
dirty |= w->needsRedraw();
|
||||
w = w->_next;
|
||||
}
|
||||
|
||||
return dirty;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::positionAt(uInt32 pos)
|
||||
{
|
||||
|
@ -192,7 +221,9 @@ void Dialog::positionAt(uInt32 pos)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Dialog::render()
|
||||
{
|
||||
if(!_dirty || !isVisible())
|
||||
//assert(_dirty);
|
||||
|
||||
if(!isVisible() || !needsRedraw())
|
||||
return false;
|
||||
|
||||
// Draw this dialog
|
||||
|
@ -207,7 +238,7 @@ bool Dialog::render()
|
|||
surface->render();
|
||||
});
|
||||
}
|
||||
_dirty = false;
|
||||
//_dirty = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -371,6 +402,10 @@ void Dialog::drawDialog()
|
|||
|
||||
FBSurface& s = surface();
|
||||
|
||||
if(isDirty())
|
||||
{
|
||||
//cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl;
|
||||
|
||||
// Dialog is still on top if e.g a ContextMenu is opened
|
||||
_onTop = parent().myDialogStack.top() == this
|
||||
|| (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this
|
||||
|
@ -388,19 +423,27 @@ void Dialog::drawDialog()
|
|||
_onTop ? kColorTitleText : kColorTitleTextLo);
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
s.invalidate();
|
||||
cerr << "invalidate " << typeid(*this).name() << endl;
|
||||
}
|
||||
if(_flags & Widget::FLAG_BORDER) // currently only used by Dialog itself
|
||||
s.frameRect(_x, _y, _w, _h, _onTop ? kColor : kShadowColor);
|
||||
|
||||
// Make all child widget dirty
|
||||
// Make all child widgets dirty
|
||||
Widget::setDirtyInChain(_firstWidget);
|
||||
|
||||
clearDirty();
|
||||
}
|
||||
|
||||
Widget* w = _firstWidget;
|
||||
Widget::setDirtyInChain(w);
|
||||
|
||||
// Draw all children
|
||||
w = _firstWidget;
|
||||
while(w)
|
||||
{
|
||||
// only redraw changed widgets
|
||||
if(w->needsRedraw())
|
||||
w->draw();
|
||||
w = w->_next;
|
||||
}
|
||||
|
|
|
@ -64,8 +64,9 @@ class Dialog : public GuiObject
|
|||
|
||||
// A dialog being dirty indicates that its underlying surface needs to be
|
||||
// redrawn and then re-rendered; this is taken care of in ::render()
|
||||
void setDirty() override { _dirty = true; }
|
||||
bool isDirty() const { return _dirty; }
|
||||
void setDirty() override;
|
||||
bool isDirty() const override;
|
||||
bool isChainDirty() const override;
|
||||
bool render();
|
||||
|
||||
void addFocusWidget(Widget* w) override;
|
||||
|
@ -235,7 +236,7 @@ class Dialog : public GuiObject
|
|||
|
||||
int _tabID{0};
|
||||
int _flags{0};
|
||||
bool _dirty{false};
|
||||
//bool _dirty{false};
|
||||
uInt32 _max_w{0}; // maximum wanted width
|
||||
uInt32 _max_h{0}; // maximum wanted height
|
||||
|
||||
|
|
|
@ -91,21 +91,32 @@ void DialogContainer::updateTime(uInt64 time)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool DialogContainer::draw(bool full)
|
||||
{
|
||||
cerr << "draw " << full << endl;
|
||||
if(myDialogStack.empty())
|
||||
return false;
|
||||
|
||||
// Make the top dialog dirty if a full redraw is requested
|
||||
if(full)
|
||||
myDialogStack.top()->setDirty();
|
||||
//if(full)
|
||||
// myDialogStack.top()->setDirty();
|
||||
|
||||
// If the top dialog is dirty, then all below it must be redrawn too
|
||||
const bool dirty = needsRedraw();
|
||||
//if(dirty)
|
||||
// myDialogStack.top()->setDirty();
|
||||
|
||||
myDialogStack.applyAll([&](Dialog*& d){
|
||||
if(dirty)
|
||||
d->setDirty();
|
||||
//myDialogStack.applyAll([&](Dialog*& d){
|
||||
// if(dirty)
|
||||
// d->setDirty();
|
||||
// full |= d->render();
|
||||
//});
|
||||
//if(dirty)
|
||||
{
|
||||
myDialogStack.applyAll([&](Dialog*& d) {
|
||||
if(d->needsRedraw())
|
||||
//d->setDirty();
|
||||
full |= d->render();
|
||||
});
|
||||
}
|
||||
|
||||
return full;
|
||||
}
|
||||
|
@ -113,7 +124,9 @@ bool DialogContainer::draw(bool full)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool DialogContainer::needsRedraw() const
|
||||
{
|
||||
return !myDialogStack.empty() ? myDialogStack.top()->isDirty() : false;
|
||||
return !myDialogStack.empty()
|
||||
? myDialogStack.top()->needsRedraw()
|
||||
: false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -133,6 +146,9 @@ int DialogContainer::addDialog(Dialog* d)
|
|||
"Unable to show dialog box; FIX THE CODE");
|
||||
else
|
||||
{
|
||||
// fade out current top dialog
|
||||
if(!myDialogStack.empty())
|
||||
myDialogStack.top()->setDirty();
|
||||
d->setDirty();
|
||||
myDialogStack.push(d);
|
||||
}
|
||||
|
@ -145,8 +161,16 @@ void DialogContainer::removeDialog()
|
|||
if(!myDialogStack.empty())
|
||||
{
|
||||
myDialogStack.pop();
|
||||
// necessary as long as all dialogs share the same surface
|
||||
if(!myDialogStack.empty())
|
||||
myDialogStack.top()->setDirty();
|
||||
{
|
||||
//myDialogStack.top()->setDirty();
|
||||
|
||||
// Mark all dialogs for redraw
|
||||
myDialogStack.applyAll([&](Dialog*& d){
|
||||
d->setDirty();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,6 +78,10 @@ class GuiObject : public CommandReceiver
|
|||
|
||||
virtual bool isVisible() const = 0;
|
||||
virtual void setDirty() = 0;
|
||||
virtual void clearDirty() { _dirty = false; }
|
||||
virtual bool isDirty() const { return _dirty; }
|
||||
virtual bool isChainDirty() const = 0;
|
||||
virtual bool needsRedraw() const { return isDirty() || isChainDirty(); };
|
||||
|
||||
/** Add given widget(s) to the focus list */
|
||||
virtual void addFocusWidget(Widget* w) = 0;
|
||||
|
@ -104,6 +108,7 @@ class GuiObject : public CommandReceiver
|
|||
|
||||
protected:
|
||||
int _x{0}, _y{0}, _w{0}, _h{0};
|
||||
bool _dirty{false};
|
||||
|
||||
Widget* _firstWidget{nullptr};
|
||||
WidgetArray _focusList;
|
||||
|
|
|
@ -315,6 +315,7 @@ void ScrollBarWidget::drawWidget(bool hilite)
|
|||
s.fillRect(_x + 1, _y + _sliderPos - 1, _w - 2, _sliderHeight + 2,
|
||||
onTop ? (hilite && _part == Part::Slider) ? kScrollColorHi : kScrollColor : kColor);
|
||||
}
|
||||
clearDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -275,17 +275,18 @@ void TabWidget::drawWidget(bool hilite)
|
|||
// The tab widget is strange in that it acts as both a widget (obviously)
|
||||
// and a dialog (it contains other widgets). Because of the latter,
|
||||
// it must assume responsibility for refreshing all its children.
|
||||
Widget::setDirtyInChain(_tabs[_activeTab].firstWidget);
|
||||
|
||||
if(isDirty())
|
||||
{
|
||||
FBSurface& s = dialog().surface();
|
||||
bool onTop = _boss->dialog().isOnTop();
|
||||
|
||||
// Iterate over all tabs and draw them
|
||||
int i, x = _x + kTabLeftOffset;
|
||||
for (i = 0; i < int(_tabs.size()); ++i)
|
||||
for(i = 0; i < int(_tabs.size()); ++i)
|
||||
{
|
||||
int tabWidth = _tabs[i].tabWidth ? _tabs[i].tabWidth : _tabWidth;
|
||||
ColorId fontcolor = _tabs[i].enabled && onTop? kTextColor : kColor;
|
||||
ColorId fontcolor = _tabs[i].enabled && onTop ? kTextColor : kColor;
|
||||
int yOffset = (i == _activeTab) ? 0 : 1;
|
||||
s.fillRect(x, _y + 1, tabWidth, _tabHeight - 1,
|
||||
(i == _activeTab)
|
||||
|
@ -308,6 +309,11 @@ void TabWidget::drawWidget(bool hilite)
|
|||
// fill empty right space
|
||||
s.hLine(x - kTabSpacing + 1, _y + _tabHeight, _x + _w - 1, onTop ? kWidColor : kDlgColor);
|
||||
s.hLine(_x, _y + _h - 1, _x + _w - 1, onTop ? kBGColorLo : kColor);
|
||||
|
||||
clearDirty();
|
||||
// Make all child widgets of currently active tab dirty
|
||||
Widget::setDirtyInChain(_tabs[_activeTab].firstWidget);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -56,7 +56,41 @@ void Widget::setDirty()
|
|||
{
|
||||
// A widget being dirty indicates that its parent dialog is dirty
|
||||
// So we inform the parent about it
|
||||
_boss->dialog().setDirty();
|
||||
//_boss->dialog().setDirty();
|
||||
//cerr << "set dirty " << typeid(*this).name() << endl;
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Widget::isDirty() const
|
||||
{
|
||||
string name = typeid(*this).name();
|
||||
if(_dirty && name == "class TabWidget")
|
||||
cerr << "is dirty " << typeid(*this).name() << endl;
|
||||
|
||||
return _dirty;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Widget::isChainDirty() const
|
||||
{
|
||||
string name = typeid(*this).name();
|
||||
if(_dirty && name == "class TabWidget")
|
||||
cerr << "is chain dirty " << typeid(*this).name() << endl;
|
||||
|
||||
bool dirty = false;
|
||||
|
||||
// Check if widget or any subwidgets are dirty
|
||||
Widget* w = _firstWidget;
|
||||
|
||||
while(!dirty && w)
|
||||
{
|
||||
dirty |= w->isDirty();
|
||||
w = w->_next;
|
||||
}
|
||||
|
||||
return dirty;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -65,6 +99,10 @@ void Widget::draw()
|
|||
if(!isVisible() || !_boss->isVisible())
|
||||
return;
|
||||
|
||||
if(isDirty())
|
||||
{
|
||||
//cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl;
|
||||
|
||||
FBSurface& s = _boss->dialog().surface();
|
||||
|
||||
bool onTop = _boss->dialog().isOnTop();
|
||||
|
@ -82,7 +120,7 @@ void Widget::draw()
|
|||
int x = _x, y = _y, w = _w, h = _h;
|
||||
if(hasBorder)
|
||||
{
|
||||
x++; y++; w-=2; h-=2;
|
||||
x++; y++; w -= 2; h -= 2;
|
||||
}
|
||||
s.fillRect(x, y, w, h, !onTop ? _bgcolorlo : (_flags & Widget::FLAG_HILITED) && isEnabled() ? _bgcolorhi : _bgcolor);
|
||||
}
|
||||
|
@ -101,7 +139,7 @@ void Widget::draw()
|
|||
drawWidget((_flags & Widget::FLAG_HILITED) ? true : false);
|
||||
|
||||
// Restore x/y
|
||||
if (hasBorder)
|
||||
if(hasBorder)
|
||||
{
|
||||
_x -= 4;
|
||||
_y -= 4;
|
||||
|
@ -111,14 +149,17 @@ void Widget::draw()
|
|||
|
||||
_x = oldX;
|
||||
_y = oldY;
|
||||
}
|
||||
|
||||
// Draw all children
|
||||
Widget* w = _firstWidget;
|
||||
while(w)
|
||||
{
|
||||
if(w->needsRedraw())
|
||||
w->draw();
|
||||
w = w->_next;
|
||||
}
|
||||
clearDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -290,6 +331,7 @@ void Widget::setDirtyInChain(Widget* start)
|
|||
{
|
||||
while(start)
|
||||
{
|
||||
//cerr << "setDirtyInChain " << typeid(*start).name() << endl;
|
||||
start->setDirty();
|
||||
start = start->_next;
|
||||
}
|
||||
|
@ -345,8 +387,6 @@ void StaticTextWidget::drawWidget(bool hilite)
|
|||
bool onTop = _boss->dialog().isOnTop();
|
||||
s.drawString(_font, _label, _x, _y, _w,
|
||||
isEnabled() && onTop ? _textcolor : kColor, _align, 0, true, _shadowcolor);
|
||||
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -454,6 +494,7 @@ void ButtonWidget::setBitmap(const uInt32* bitmap, int bmw, int bmh)
|
|||
_bmh = bmh;
|
||||
_bmw = bmw;
|
||||
|
||||
cerr << "setBitmap" << endl;
|
||||
setDirty();
|
||||
}
|
||||
|
||||
|
@ -474,8 +515,6 @@ void ButtonWidget::drawWidget(bool hilite)
|
|||
!(isEnabled() && onTop) ? _textcolorlo :
|
||||
hilite ? _textcolorhi : _textcolor,
|
||||
_bmw, _bmh);
|
||||
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -635,8 +674,6 @@ void CheckboxWidget::drawWidget(bool hilite)
|
|||
// Finally draw the label
|
||||
s.drawString(_font, _label, _x + prefixSize(_font), _y + _textY, _w,
|
||||
onTop && isEnabled() ? kTextColor : kColor);
|
||||
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -652,7 +689,7 @@ SliderWidget::SliderWidget(GuiObject* boss, const GUI::Font& font,
|
|||
_valueLabelWidth(valueLabelWidth),
|
||||
_forceLabelSign(forceLabelSign)
|
||||
{
|
||||
_flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE;
|
||||
_flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE | Widget::FLAG_CLEARBG;;
|
||||
_bgcolor = kDlgColor;
|
||||
_bgcolorhi = kDlgColor;
|
||||
|
||||
|
@ -870,8 +907,6 @@ void SliderWidget::drawWidget(bool hilite)
|
|||
if(_valueLabelWidth > 0)
|
||||
s.drawString(_font, _valueLabel + _valueUnit, _x + _w - _valueLabelWidth, _y + 2,
|
||||
_valueLabelWidth, isEnabled() ? kTextColor : kColor);
|
||||
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -83,6 +83,8 @@ class Widget : public GuiObject
|
|||
virtual bool handleEvent(Event::Type event) { return false; }
|
||||
|
||||
void setDirty() override;
|
||||
bool isDirty() const override;
|
||||
bool isChainDirty() const override;
|
||||
void draw() override;
|
||||
void receivedFocus();
|
||||
void lostFocus();
|
||||
|
|
Loading…
Reference in New Issue