mirror of https://github.com/stella-emu/stella.git
Fix imageRect not being correctly set for fullscreen UI modes.
- This caused incorrectly positioning for ContextMenu - With this fix, the positioning code in ContextMenu and related dialogs becomes a lot less complex
This commit is contained in:
parent
9aa75502b2
commit
087dd1dbb9
|
@ -95,7 +95,7 @@ struct Size
|
|||
Another very wide spread approach to rectangle classes treats (bottom,right)
|
||||
also as a part of the rectangle.
|
||||
|
||||
Coneptually, both are sound, but the approach we use saves many intermediate
|
||||
Conceptually, both are sound, but the approach we use saves many intermediate
|
||||
computations (like computing the height in our case is done by doing this:
|
||||
height = bottom - top;
|
||||
while in the alternate system, it would be
|
||||
|
@ -158,6 +158,18 @@ struct Rect
|
|||
return x >= left && y >= top && x < right && y < bottom;
|
||||
}
|
||||
|
||||
// Tests whether 'r' is completely contained within this rectangle.
|
||||
// If it isn't, then set 'x' and 'y' such that moving 'r' to this
|
||||
// position will make it be contained.
|
||||
bool contains(uInt32& x, uInt32& y, const Rect& r) const {
|
||||
if(r.left < left) x = left;
|
||||
else if(r.right > right) x = r.left - (r.right - right);
|
||||
if(r.top < top) y = top;
|
||||
else if(r.bottom > bottom) y = r.top - (r.bottom - bottom);
|
||||
|
||||
return r.left != x || r.top != y;
|
||||
}
|
||||
|
||||
friend ostream& operator<<(ostream& os, const Rect& r) {
|
||||
os << r.point() << "," << r.size();
|
||||
return os;
|
||||
|
|
|
@ -88,30 +88,31 @@ RomListSettings::RomListSettings(GuiObject* boss, const GUI::Font& font)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RomListSettings::show(uInt32 x, uInt32 y, int data)
|
||||
void RomListSettings::show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int data)
|
||||
{
|
||||
_xorig = x * instance().frameBuffer().hidpiScaleFactor();
|
||||
_yorig = y * instance().frameBuffer().hidpiScaleFactor();
|
||||
_item = data;
|
||||
uInt32 scale = instance().frameBuffer().hidpiScaleFactor();
|
||||
_xorig = bossRect.x() + x * scale;
|
||||
_yorig = bossRect.y() + y * scale;
|
||||
|
||||
// Only show if we're inside the visible area
|
||||
if(!bossRect.contains(_xorig, _yorig))
|
||||
return;
|
||||
|
||||
_item = data;
|
||||
open();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RomListSettings::center()
|
||||
{
|
||||
// Make sure the menu is exactly where it should be, in case the image
|
||||
// offset has changed
|
||||
const Common::Rect& image = instance().frameBuffer().imageRect();
|
||||
const uInt32 scale = instance().frameBuffer().hidpiScaleFactor();
|
||||
uInt32 x = image.x() + _xorig;
|
||||
uInt32 y = image.y() + _yorig;
|
||||
uInt32 tx = image.x() + image.width();
|
||||
uInt32 ty = image.y() + image.height();
|
||||
if(x + _w*scale > tx) x -= (x + _w*scale - tx);
|
||||
if(y + _h*scale > ty) y -= (y + _h*scale - ty);
|
||||
// First set position according to original coordinates
|
||||
surface().setDstPos(_xorig, _yorig);
|
||||
|
||||
surface().setDstPos(x, y);
|
||||
// Now make sure that the entire menu can fit inside the image bounds
|
||||
// If not, we reset its position
|
||||
if(!instance().frameBuffer().imageRect().contains(
|
||||
_xorig, _yorig, surface().dstRect()))
|
||||
surface().setDstPos(_xorig, _yorig);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -36,7 +36,7 @@ class RomListSettings : public Dialog, public CommandSender
|
|||
|
||||
/** Show dialog onscreen at the specified coordinates
|
||||
('data' will be the currently selected line number in RomListWidget) */
|
||||
void show(uInt32 x, uInt32 y, int data = -1);
|
||||
void show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int data = -1);
|
||||
|
||||
/** This dialog uses its own positioning, so we override Dialog::center() */
|
||||
void center() override;
|
||||
|
|
|
@ -248,7 +248,8 @@ void RomListWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
|
|||
// Set selected and add menu at current x,y mouse location
|
||||
_selectedItem = findItem(x, y);
|
||||
scrollToSelected();
|
||||
myMenu->show(x + getAbsX(), y + getAbsY(), _selectedItem);
|
||||
myMenu->show(x + getAbsX(), y + getAbsY(),
|
||||
dialog().surface().dstRect(), _selectedItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -926,13 +926,13 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
|
|||
{
|
||||
// Windowed and fullscreen mode differ only in screen size
|
||||
myWindowedModeList.add(
|
||||
VideoMode(baseWidth, baseHeight, baseWidth, baseHeight, VideoMode::Stretch::Fill)
|
||||
VideoMode(baseWidth, baseHeight, baseWidth, baseHeight, VideoMode::Stretch::None)
|
||||
);
|
||||
for(uInt32 i = 0; i < myFullscreenDisplays.size(); ++i)
|
||||
{
|
||||
myFullscreenModeLists[i].add(
|
||||
VideoMode(baseWidth, baseHeight, myFullscreenDisplays[i].w, myFullscreenDisplays[i].h,
|
||||
VideoMode::Stretch::Fill, "", 1, i)
|
||||
VideoMode::Stretch::None, "", 1, i)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -941,8 +941,6 @@ void FrameBuffer::setAvailableVidModes(uInt32 baseWidth, uInt32 baseHeight)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const FrameBuffer::VideoMode& FrameBuffer::getSavedVidMode(bool fullscreen)
|
||||
{
|
||||
EventHandlerState state = myOSystem.eventHandler().state();
|
||||
|
||||
if(fullscreen)
|
||||
{
|
||||
Int32 i = getCurrentDisplayIndex();
|
||||
|
@ -959,6 +957,7 @@ const FrameBuffer::VideoMode& FrameBuffer::getSavedVidMode(bool fullscreen)
|
|||
// Now select the best resolution depending on the state
|
||||
// UI modes (launcher and debugger) have only one supported resolution
|
||||
// so the 'current' one is the only valid one
|
||||
EventHandlerState state = myOSystem.eventHandler().state();
|
||||
if(state == EventHandlerState::DEBUGGER || state == EventHandlerState::LAUNCHER)
|
||||
myCurrentModeList->setByZoom(1);
|
||||
else // TIA mode
|
||||
|
@ -979,7 +978,7 @@ const FrameBuffer::VideoMode& FrameBuffer::getSavedVidMode(bool fullscreen)
|
|||
//
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBuffer::VideoMode::VideoMode()
|
||||
: stretch(VideoMode::Stretch::Fill),
|
||||
: stretch(VideoMode::Stretch::None),
|
||||
description(""),
|
||||
zoom(1),
|
||||
fsIndex(-1)
|
||||
|
@ -1035,6 +1034,10 @@ FrameBuffer::VideoMode::VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
|
|||
iw = screen.w;
|
||||
ih = screen.h;
|
||||
break;
|
||||
|
||||
case Stretch::None:
|
||||
// Don't do any scaling at all
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1045,6 +1048,7 @@ FrameBuffer::VideoMode::VideoMode(uInt32 iw, uInt32 ih, uInt32 sw, uInt32 sh,
|
|||
{
|
||||
case Stretch::Preserve:
|
||||
case Stretch::Fill:
|
||||
case Stretch::None:
|
||||
screen.w = iw;
|
||||
screen.h = ih;
|
||||
break;
|
||||
|
|
|
@ -57,7 +57,7 @@ class FrameBuffer
|
|||
// 'screen' are the dimensions of the screen itself
|
||||
struct VideoMode
|
||||
{
|
||||
enum class Stretch { Preserve, Fill };
|
||||
enum class Stretch { Preserve, Fill, None };
|
||||
|
||||
Common::Rect image;
|
||||
Common::Size screen;
|
||||
|
|
|
@ -68,14 +68,13 @@ void ContextMenu::addItems(const VariantList& items)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ContextMenu::show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int item)
|
||||
void ContextMenu::show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int item)
|
||||
{
|
||||
const Common::Rect& image = instance().frameBuffer().imageRect();
|
||||
uInt32 scale = instance().frameBuffer().hidpiScaleFactor();
|
||||
_xorig = bossRect.x() + scale * x - image.x();
|
||||
_yorig = bossRect.y() + scale * y - image.y();
|
||||
_xorig = bossRect.x() + x * scale;
|
||||
_yorig = bossRect.y() + y * scale;
|
||||
|
||||
// Only show if we're inside the visible area
|
||||
// Only show menu if we're inside the visible area
|
||||
if(!bossRect.contains(_xorig, _yorig))
|
||||
return;
|
||||
|
||||
|
@ -88,18 +87,14 @@ void ContextMenu::show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int it
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ContextMenu::center()
|
||||
{
|
||||
// Make sure the menu is exactly where it should be, in case the image
|
||||
// offset has changed
|
||||
const Common::Rect& image = instance().frameBuffer().imageRect();
|
||||
recalc(image);
|
||||
uInt32 x = image.x() + _xorig;
|
||||
uInt32 y = image.y() + _yorig;
|
||||
uInt32 tx = image.x() + image.width();
|
||||
uInt32 ty = image.y() + image.height();
|
||||
if(x + _w > tx) x -= (x + _w - tx);
|
||||
if(y + _h > ty) y -= (y + _h - ty);
|
||||
// First set position according to original coordinates
|
||||
surface().setDstPos(_xorig, _yorig);
|
||||
|
||||
surface().setDstPos(x, y);
|
||||
// Now make sure that the entire menu can fit inside the image bounds
|
||||
// If not, we reset its position
|
||||
if(!instance().frameBuffer().imageRect().contains(
|
||||
_xorig, _yorig, surface().dstRect()))
|
||||
surface().setDstPos(_xorig, _yorig);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
Loading…
Reference in New Issue