mirror of https://github.com/stella-emu/stella.git
Time Machine dialog now resizes correctly:
- in 2x mode, it takes up the maximum amount of space - in larger modes, it takes up the same relative amount of space: ~80% width
This commit is contained in:
parent
f4db8e4816
commit
6c5bddcdf8
|
@ -48,6 +48,15 @@ class FixedStack
|
|||
T pop() { return std::move(_stack[--_size]); }
|
||||
uInt32 size() const { return _size; }
|
||||
|
||||
void replace(const T& oldItem, const T& newItem) {
|
||||
for(uInt32 i = 0; i < _size; ++i) {
|
||||
if(_stack[i] == oldItem) {
|
||||
_stack[i] = newItem;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the given function to every item in the stack
|
||||
// We do it this way so the stack API can be preserved,
|
||||
// and no access to individual elements is allowed outside
|
||||
|
|
|
@ -2181,6 +2181,7 @@ void EventHandler::setEventState(EventHandlerState state)
|
|||
break;
|
||||
|
||||
case EventHandlerState::TIMEMACHINE:
|
||||
myOSystem.timeMachine().requestResize();
|
||||
myOverlay = &myOSystem.timeMachine();
|
||||
enableTextEvents(true);
|
||||
break;
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "Dialog.hxx"
|
||||
#include "Widget.hxx"
|
||||
#include "TabWidget.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "Console.hxx"
|
||||
#include "Vec.hxx"
|
||||
|
||||
/*
|
||||
|
@ -728,16 +730,25 @@ Widget* Dialog::TabFocus::getNewFocus()
|
|||
bool Dialog::getResizableBounds(uInt32& w, uInt32& h) const
|
||||
{
|
||||
const GUI::Rect& r = instance().frameBuffer().imageRect();
|
||||
|
||||
double scaleFactor = 0.8;
|
||||
if(instance().hasConsole())
|
||||
{
|
||||
bool ntsc = instance().console().about().InitialFrameRate == "60";
|
||||
uInt32 aspect = instance().settings().getInt(ntsc ?"tia.aspectn" : "tia.aspectp");
|
||||
scaleFactor = aspect / 100.0;
|
||||
}
|
||||
|
||||
if(r.width() <= FrameBuffer::kFBMinW || r.height() <= FrameBuffer::kFBMinH)
|
||||
{
|
||||
w = uInt32(0.8 * FrameBuffer::kTIAMinW) * 2;
|
||||
w = uInt32(scaleFactor * FrameBuffer::kTIAMinW) * 2;
|
||||
h = FrameBuffer::kTIAMinH * 2;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = std::max(uInt32(0.8 * r.width()), uInt32(FrameBuffer::kFBMinW));
|
||||
h = std::max(uInt32(0.8 * r.height()), uInt32(FrameBuffer::kFBMinH));
|
||||
w = std::max(uInt32(scaleFactor * r.width()), uInt32(FrameBuffer::kFBMinW));
|
||||
h = std::max(uInt32(scaleFactor * r.height()), uInt32(FrameBuffer::kFBMinH));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,10 +72,11 @@ class Dialog : public GuiObject
|
|||
/** Returns the base surface associated with this dialog. */
|
||||
FBSurface& surface() const { return *_surface; }
|
||||
|
||||
/** Adds a surface to this dialog, which is rendered on top of the
|
||||
base surface whenever the base surface is re-rendered. Since
|
||||
the surface render() call will always occur in such a case, the
|
||||
surface should call setVisible() to enable/disable its output.
|
||||
/**
|
||||
Adds a surface to this dialog, which is rendered on top of the
|
||||
base surface whenever the base surface is re-rendered. Since
|
||||
the surface render() call will always occur in such a case, the
|
||||
surface should call setVisible() to enable/disable its output.
|
||||
*/
|
||||
void addSurface(shared_ptr<FBSurface> surface);
|
||||
|
||||
|
@ -83,6 +84,12 @@ class Dialog : public GuiObject
|
|||
void clearFlags(int flags) { _flags &= ~flags; setDirty(); }
|
||||
int getFlags() const { return _flags; }
|
||||
|
||||
/**
|
||||
Determine the maximum bounds based on the given width and height.
|
||||
Returns whether or not a large font can be used within these bounds.
|
||||
*/
|
||||
bool getResizableBounds(uInt32& w, uInt32& h) const;
|
||||
|
||||
protected:
|
||||
virtual void draw() override { }
|
||||
void releaseFocus() override;
|
||||
|
@ -110,11 +117,6 @@ class Dialog : public GuiObject
|
|||
|
||||
void processCancelWithoutWidget(bool state) { _processCancel = state; }
|
||||
|
||||
/** Determine the maximum bounds based on the given width and height
|
||||
Returns whether or not a large font can be used within these bounds.
|
||||
*/
|
||||
bool getResizableBounds(uInt32& w, uInt32& h) const;
|
||||
|
||||
private:
|
||||
void buildCurrentFocusList(int tabID = -1);
|
||||
bool handleNavEvent(Event::Type e);
|
||||
|
|
|
@ -119,7 +119,7 @@ void DialogContainer::addDialog(Dialog* d)
|
|||
const GUI::Rect& r = myOSystem.frameBuffer().imageRect();
|
||||
if(uInt32(d->getWidth()) > r.width() || uInt32(d->getHeight()) > r.height())
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
"Unable to show dialog box; resize current window");
|
||||
"Unable to show dialog box; FIX THE CODE");
|
||||
else
|
||||
myDialogStack.push(d);
|
||||
}
|
||||
|
|
|
@ -134,6 +134,14 @@ class DialogContainer
|
|||
*/
|
||||
const Dialog* baseDialog() const { return myBaseDialog; }
|
||||
|
||||
/**
|
||||
Inform the container that it should resize according to the current
|
||||
screen dimensions. We make this virtual, since the container may or
|
||||
may not choose to do a resize, and even if it does, *how* it does it
|
||||
is determined by the specific container.
|
||||
*/
|
||||
virtual void requestResize() { }
|
||||
|
||||
private:
|
||||
void reset();
|
||||
|
||||
|
|
|
@ -22,8 +22,37 @@
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
TimeMachine::TimeMachine(OSystem& osystem)
|
||||
: DialogContainer(osystem)
|
||||
: DialogContainer(osystem),
|
||||
myWidth(FrameBuffer::kFBMinW)
|
||||
{
|
||||
myBaseDialog = new TimeMachineDialog(myOSystem, *this,
|
||||
FrameBuffer::kFBMinW, FrameBuffer::kFBMinH);
|
||||
myBaseDialog = new TimeMachineDialog(myOSystem, *this, myWidth);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TimeMachine::requestResize()
|
||||
{
|
||||
uInt32 w, h;
|
||||
myBaseDialog->getResizableBounds(w, h);
|
||||
|
||||
// If dialog is too large for given area, we need to resize it
|
||||
// Otherwise, make it 80% of the allowable width
|
||||
int newWidth = myWidth;
|
||||
if(w < FrameBuffer::kFBMinW)
|
||||
newWidth = w;
|
||||
else if(myBaseDialog->getWidth() != 0.8 * w)
|
||||
newWidth = 0.8 * w;
|
||||
|
||||
// Only re-create when absolutely necessary
|
||||
if(myWidth != newWidth)
|
||||
{
|
||||
myWidth = newWidth;
|
||||
Dialog* oldPtr = myBaseDialog;
|
||||
delete myBaseDialog;
|
||||
myBaseDialog = new TimeMachineDialog(myOSystem, *this, myWidth);
|
||||
Dialog* newPtr = myBaseDialog;
|
||||
|
||||
// Update the container stack; it may contain a reference to the old pointer
|
||||
if(oldPtr != newPtr)
|
||||
myDialogStack.replace(oldPtr, newPtr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,15 @@ class TimeMachine : public DialogContainer
|
|||
TimeMachine(OSystem& osystem);
|
||||
virtual ~TimeMachine() = default;
|
||||
|
||||
/**
|
||||
This dialog has an adjustable size. We need to make sure the
|
||||
dialog can fit within the given bounds.
|
||||
*/
|
||||
void requestResize() override;
|
||||
|
||||
private:
|
||||
int myWidth;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
TimeMachine() = delete;
|
||||
|
|
|
@ -36,7 +36,7 @@ using Common::Base;
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
||||
int max_w, int max_h)
|
||||
int width)
|
||||
: Dialog(osystem, parent)
|
||||
{
|
||||
const int BUTTON_W = 16, BUTTON_H = 14;
|
||||
|
@ -136,7 +136,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
|||
int xpos, ypos;
|
||||
|
||||
// Set real dimensions
|
||||
_w = 20 * (buttonWidth + BUTTON_GAP) + 20;
|
||||
_w = width; // Parent determines our width (based on window size)
|
||||
_h = V_BORDER * 2 + rowHeight + buttonHeight + 2;
|
||||
|
||||
this->clearFlags(WIDGET_CLEARBG); // does only work combined with blending (0..100)!
|
||||
|
|
|
@ -28,7 +28,7 @@ class TimeLineWidget;
|
|||
class TimeMachineDialog : public Dialog
|
||||
{
|
||||
public:
|
||||
TimeMachineDialog(OSystem& osystem, DialogContainer& parent, int max_w, int max_h);
|
||||
TimeMachineDialog(OSystem& osystem, DialogContainer& parent, int width);
|
||||
virtual ~TimeMachineDialog() = default;
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue