mirror of https://github.com/stella-emu/stella.git
Merge remote-tracking branch 'remotes/origin/feature/improve_ui_redraws'
This commit is contained in:
commit
39b94d74e1
8
Makefile
8
Makefile
|
@ -48,11 +48,11 @@ endif
|
|||
CXXFLAGS+= -Wall -Wextra -Wno-unused-parameter
|
||||
|
||||
ifdef HAVE_GCC
|
||||
CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14
|
||||
CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14
|
||||
endif
|
||||
|
||||
ifdef HAVE_CLANG
|
||||
CXXFLAGS+= -Wno-multichar -Wunused -fno-rtti -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14
|
||||
CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++14
|
||||
endif
|
||||
|
||||
ifdef CLANG_WARNINGS
|
||||
|
@ -81,8 +81,8 @@ else
|
|||
endif
|
||||
|
||||
ifdef RELEASE
|
||||
CXXFLAGS += -flto
|
||||
LDFLAGS += -flto
|
||||
CXXFLAGS += -flto -fno-rtti
|
||||
LDFLAGS += -flto -fno-rtti
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
|
|
|
@ -45,6 +45,8 @@ EventHandlerSDL2::EventHandlerSDL2(OSystem& osystem)
|
|||
}
|
||||
Logger::debug("EventHandlerSDL2::EventHandlerSDL2 SDL_INIT_JOYSTICK");
|
||||
#endif
|
||||
|
||||
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -104,41 +104,49 @@ const Common::Rect& FBSurfaceSDL2::dstRect() const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::setSrcPos(uInt32 x, uInt32 y)
|
||||
{
|
||||
if(x != static_cast<uInt32>(mySrcR.x) || y != static_cast<uInt32>(mySrcR.y))
|
||||
{
|
||||
setSrcPosInternal(x, y);
|
||||
if(setSrcPosInternal(x, y))
|
||||
reinitializeBlitter();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::setSrcSize(uInt32 w, uInt32 h)
|
||||
{
|
||||
if(w != static_cast<uInt32>(mySrcR.w) || h != static_cast<uInt32>(mySrcR.h))
|
||||
{
|
||||
setSrcSizeInternal(w, h);
|
||||
if(setSrcSizeInternal(w, h))
|
||||
reinitializeBlitter();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::setSrcRect(const Common::Rect& r)
|
||||
{
|
||||
const bool posChanged = setSrcPosInternal(r.x(), r.y()),
|
||||
sizeChanged = setSrcSizeInternal(r.w(), r.h());
|
||||
|
||||
if(posChanged || sizeChanged)
|
||||
reinitializeBlitter();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::setDstPos(uInt32 x, uInt32 y)
|
||||
{
|
||||
if(x != static_cast<uInt32>(myDstR.x) || y != static_cast<uInt32>(myDstR.y))
|
||||
{
|
||||
setDstPosInternal(x, y);
|
||||
if(setDstPosInternal(x, y))
|
||||
reinitializeBlitter();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::setDstSize(uInt32 w, uInt32 h)
|
||||
{
|
||||
if(w != static_cast<uInt32>(myDstR.w) || h != static_cast<uInt32>(myDstR.h))
|
||||
{
|
||||
setDstSizeInternal(w, h);
|
||||
if(setDstSizeInternal(w, h))
|
||||
reinitializeBlitter();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::setDstRect(const Common::Rect& r)
|
||||
{
|
||||
const bool posChanged = setDstPosInternal(r.x(), r.y()),
|
||||
sizeChanged = setDstSizeInternal(r.w(), r.h());
|
||||
|
||||
if(posChanged || sizeChanged)
|
||||
reinitializeBlitter();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -176,6 +184,22 @@ void FBSurfaceSDL2::invalidate()
|
|||
SDL_FillRect(mySurface, nullptr, 0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
||||
{
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
// Clear the rectangle
|
||||
SDL_Rect tmp;
|
||||
tmp.x = x;
|
||||
tmp.y = y;
|
||||
tmp.w = w;
|
||||
tmp.h = h;
|
||||
// Note: Transparency has to be 0 to clear the rectangle foreground
|
||||
// without affecting the background display.
|
||||
SDL_FillRect(mySurface, &tmp, 0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceSDL2::free()
|
||||
{
|
||||
|
|
|
@ -48,13 +48,18 @@ class FBSurfaceSDL2 : public FBSurface
|
|||
const Common::Rect& dstRect() const override;
|
||||
void setSrcPos(uInt32 x, uInt32 y) override;
|
||||
void setSrcSize(uInt32 w, uInt32 h) override;
|
||||
void setSrcRect(const Common::Rect& r) override;
|
||||
void setDstPos(uInt32 x, uInt32 y) override;
|
||||
void setDstSize(uInt32 w, uInt32 h) override;
|
||||
void setDstRect(const Common::Rect& r) override;
|
||||
|
||||
void setVisible(bool visible) override;
|
||||
|
||||
void translateCoords(Int32& x, Int32& y) const override;
|
||||
bool render() override;
|
||||
void invalidate() override;
|
||||
void invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) override;
|
||||
|
||||
void free() override;
|
||||
void reload() override;
|
||||
void resize(uInt32 width, uInt32 height) override;
|
||||
|
@ -65,21 +70,41 @@ class FBSurfaceSDL2 : public FBSurface
|
|||
void applyAttributes() override;
|
||||
|
||||
private:
|
||||
inline void setSrcPosInternal(uInt32 x, uInt32 y) {
|
||||
inline bool setSrcPosInternal(uInt32 x, uInt32 y) {
|
||||
if(x != static_cast<uInt32>(mySrcR.x) || y != static_cast<uInt32>(mySrcR.y))
|
||||
{
|
||||
mySrcR.x = x; mySrcR.y = y;
|
||||
mySrcGUIR.moveTo(x, y);
|
||||
return true;
|
||||
}
|
||||
inline void setSrcSizeInternal(uInt32 w, uInt32 h) {
|
||||
return false;
|
||||
}
|
||||
inline bool setSrcSizeInternal(uInt32 w, uInt32 h) {
|
||||
if(w != static_cast<uInt32>(mySrcR.w) || h != static_cast<uInt32>(mySrcR.h))
|
||||
{
|
||||
mySrcR.w = w; mySrcR.h = h;
|
||||
mySrcGUIR.setWidth(w); mySrcGUIR.setHeight(h);
|
||||
return true;
|
||||
}
|
||||
inline void setDstPosInternal(uInt32 x, uInt32 y) {
|
||||
return false;
|
||||
}
|
||||
inline bool setDstPosInternal(uInt32 x, uInt32 y) {
|
||||
if(x != static_cast<uInt32>(myDstR.x) || y != static_cast<uInt32>(myDstR.y))
|
||||
{
|
||||
myDstR.x = x; myDstR.y = y;
|
||||
myDstGUIR.moveTo(x, y);
|
||||
return true;
|
||||
}
|
||||
inline void setDstSizeInternal(uInt32 w, uInt32 h) {
|
||||
return false;
|
||||
}
|
||||
inline bool setDstSizeInternal(uInt32 w, uInt32 h) {
|
||||
if(w != static_cast<uInt32>(myDstR.w) || h != static_cast<uInt32>(myDstR.h))
|
||||
{
|
||||
myDstR.w = w; myDstR.h = h;
|
||||
myDstGUIR.setWidth(w); myDstGUIR.setHeight(h);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void createSurface(uInt32 width, uInt32 height, const uInt32* data);
|
||||
|
@ -101,7 +126,7 @@ class FBSurfaceSDL2 : public FBSurface
|
|||
{ScalingInterpolation::none};
|
||||
|
||||
SDL_Surface* mySurface{nullptr};
|
||||
SDL_Rect mySrcR{0, 0, 0, 0}, myDstR{0, 0, 0, 0};
|
||||
SDL_Rect mySrcR{-1, -1, -1, -1}, myDstR{-1, -1, -1, -1};
|
||||
|
||||
bool myIsVisible{true};
|
||||
bool myIsStatic{false};
|
||||
|
|
|
@ -267,7 +267,7 @@ void PNGLibrary::toggleContinuousSnapshots(bool perFrame)
|
|||
buf << "Enabling snapshots in " << interval << " second intervals";
|
||||
interval *= uInt32(myOSystem.frameRate());
|
||||
}
|
||||
myOSystem.frameBuffer().showMessage(buf.str());
|
||||
myOSystem.frameBuffer().showTextMessage(buf.str());
|
||||
setContinuousSnapInterval(interval);
|
||||
}
|
||||
else
|
||||
|
@ -276,7 +276,7 @@ void PNGLibrary::toggleContinuousSnapshots(bool perFrame)
|
|||
buf << "Disabling snapshots, generated "
|
||||
<< (mySnapCounter / mySnapInterval)
|
||||
<< " files";
|
||||
myOSystem.frameBuffer().showMessage(buf.str());
|
||||
myOSystem.frameBuffer().showTextMessage(buf.str());
|
||||
setContinuousSnapInterval(0);
|
||||
}
|
||||
}
|
||||
|
@ -378,7 +378,7 @@ void PNGLibrary::takeSnapshot(uInt32 number)
|
|||
// Re-enable old messages
|
||||
myOSystem.frameBuffer().enableMessages(true);
|
||||
}
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -69,7 +69,7 @@ void PaletteHandler::cyclePalette(int direction)
|
|||
const string palette = toPaletteName(PaletteType(type));
|
||||
const string message = MESSAGES[type] + " palette";
|
||||
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
|
||||
setPalette(palette);
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ void PaletteHandler::showAdjustableMessage()
|
|||
const float value =
|
||||
myOSystem.console().timing() == ConsoleTiming::pal ? myPhasePAL : myPhaseNTSC;
|
||||
buf << std::fixed << std::setprecision(1) << value << DEGREE;
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
myOSystem.frameBuffer().showGaugeMessage(
|
||||
"Palette phase shift", buf.str(), value,
|
||||
(isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) - MAX_PHASE_SHIFT,
|
||||
(isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT) + MAX_PHASE_SHIFT);
|
||||
|
@ -122,7 +122,7 @@ void PaletteHandler::showAdjustableMessage()
|
|||
const float value = *myAdjustables[myCurrentAdjustable].value;
|
||||
|
||||
buf << std::fixed << std::setprecision(1) << value << DEGREE;
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
myOSystem.frameBuffer().showGaugeMessage(
|
||||
msg.str(), buf.str(), value, -MAX_RGB_SHIFT, +MAX_RGB_SHIFT);
|
||||
}
|
||||
else
|
||||
|
@ -131,7 +131,7 @@ void PaletteHandler::showAdjustableMessage()
|
|||
? scaleRGBTo100(*myAdjustables[myCurrentAdjustable].value)
|
||||
: scaleTo100(*myAdjustables[myCurrentAdjustable].value);
|
||||
buf << value << "%";
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
myOSystem.frameBuffer().showGaugeMessage(
|
||||
msg.str(), buf.str(), value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,8 +44,8 @@ struct Point
|
|||
if(c != 'x')
|
||||
x = y = 0;
|
||||
}
|
||||
bool operator==(const Point & p) const { return x == p.x && y == p.y; }
|
||||
bool operator!=(const Point & p) const { return x != p.x || y != p.y; }
|
||||
bool operator==(const Point& p) const { return x == p.x && y == p.y; }
|
||||
bool operator!=(const Point& p) const { return !(*this == p); }
|
||||
|
||||
friend ostream& operator<<(ostream& os, const Point& p) {
|
||||
os << p.x << "x" << p.y;
|
||||
|
@ -75,11 +75,11 @@ struct Size
|
|||
}
|
||||
|
||||
bool operator==(const Size& s) const { return w == s.w && h == s.h; }
|
||||
bool operator!=(const Size& s) const { return w != s.w || h != s.h; }
|
||||
bool operator<(const Size& s) const { return w < s.w && h < s.h; }
|
||||
bool operator<=(const Size& s) const { return w <= s.w && h <= s.h; }
|
||||
bool operator>(const Size& s) const { return w > s.w || h > s.h; }
|
||||
bool operator>=(const Size& s) const { return w >= s.w || h >= s.h; }
|
||||
bool operator< (const Size& s) const { return w < s.w && h < s.h; }
|
||||
bool operator> (const Size& s) const { return w > s.w || h > s.h; }
|
||||
bool operator!=(const Size& s) const { return !(*this == s); }
|
||||
bool operator<=(const Size& s) const { return !(*this > s); }
|
||||
bool operator>=(const Size& s) const { return !(*this < s); }
|
||||
|
||||
friend ostream& operator<<(ostream& os, const Size& s) {
|
||||
os << s.w << "x" << s.h;
|
||||
|
@ -175,6 +175,11 @@ struct Rect
|
|||
return r.left != x || r.top != y;
|
||||
}
|
||||
|
||||
bool operator==(const Rect& r) const {
|
||||
return top == r.top && left == r.left && bottom == r.bottom && right == r.right;
|
||||
}
|
||||
bool operator!=(const Rect& r) const { return !(*this == r); }
|
||||
|
||||
friend ostream& operator<<(ostream& os, const Rect& r) {
|
||||
os << r.point() << "," << r.size();
|
||||
return os;
|
||||
|
|
|
@ -181,7 +181,7 @@ uInt32 RewindManager::rewindStates(uInt32 numStates)
|
|||
|
||||
if(myOSystem.eventHandler().state() != EventHandlerState::TIMEMACHINE
|
||||
&& myOSystem.eventHandler().state() != EventHandlerState::PLAYBACK)
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,7 @@ uInt32 RewindManager::unwindStates(uInt32 numStates)
|
|||
|
||||
if(myOSystem.eventHandler().state() != EventHandlerState::TIMEMACHINE
|
||||
&& myOSystem.eventHandler().state() != EventHandlerState::PLAYBACK)
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ bool SoundSDL2::toggleMute()
|
|||
string message = "Sound ";
|
||||
message += enabled ? "unmuted" : "muted";
|
||||
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
|
||||
//ostringstream strval;
|
||||
//uInt32 volume;
|
||||
|
@ -282,7 +282,7 @@ void SoundSDL2::adjustVolume(int direction)
|
|||
strval << percent << "%";
|
||||
else
|
||||
strval << "Off";
|
||||
myOSystem.frameBuffer().showMessage("Volume", strval.str(), percent);
|
||||
myOSystem.frameBuffer().showGaugeMessage("Volume", strval.str(), percent);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -132,9 +132,9 @@ void StateManager::toggleTimeMachine()
|
|||
|
||||
myActiveMode = myActiveMode == Mode::TimeMachine ? Mode::Off : Mode::TimeMachine;
|
||||
if(myActiveMode == Mode::TimeMachine)
|
||||
myOSystem.frameBuffer().showMessage("Time Machine enabled");
|
||||
myOSystem.frameBuffer().showTextMessage("Time Machine enabled");
|
||||
else
|
||||
myOSystem.frameBuffer().showMessage("Time Machine disabled");
|
||||
myOSystem.frameBuffer().showTextMessage("Time Machine disabled");
|
||||
myOSystem.settings().setValue(devSettings ? "dev.timemachine" : "plr.timemachine", myActiveMode == Mode::TimeMachine);
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ void StateManager::loadState(int slot)
|
|||
{
|
||||
buf.str("");
|
||||
buf << "Can't open/load from state file " << slot;
|
||||
myOSystem.frameBuffer().showMessage(buf.str());
|
||||
myOSystem.frameBuffer().showTextMessage(buf.str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -239,7 +239,7 @@ void StateManager::loadState(int slot)
|
|||
buf << "Invalid data in state " << slot << " file";
|
||||
}
|
||||
|
||||
myOSystem.frameBuffer().showMessage(buf.str());
|
||||
myOSystem.frameBuffer().showTextMessage(buf.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,7 @@ void StateManager::saveState(int slot)
|
|||
{
|
||||
buf.str("");
|
||||
buf << "Can't open/save to state file " << slot;
|
||||
myOSystem.frameBuffer().showMessage(buf.str());
|
||||
myOSystem.frameBuffer().showTextMessage(buf.str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -274,7 +274,7 @@ void StateManager::saveState(int slot)
|
|||
catch(...)
|
||||
{
|
||||
buf << "Error saving state " << slot;
|
||||
myOSystem.frameBuffer().showMessage(buf.str());
|
||||
myOSystem.frameBuffer().showTextMessage(buf.str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -292,7 +292,7 @@ void StateManager::saveState(int slot)
|
|||
else
|
||||
buf << "Error saving state " << slot;
|
||||
|
||||
myOSystem.frameBuffer().showMessage(buf.str());
|
||||
myOSystem.frameBuffer().showTextMessage(buf.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,7 +307,7 @@ void StateManager::changeState(int direction)
|
|||
buf << "Changed to state slot " << myCurrentSlot;
|
||||
else
|
||||
buf << "State slot " << myCurrentSlot;
|
||||
myOSystem.frameBuffer().showMessage(buf.str());
|
||||
myOSystem.frameBuffer().showTextMessage(buf.str());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -318,7 +318,7 @@ void StateManager::toggleAutoSlot()
|
|||
// Print appropriate message
|
||||
ostringstream buf;
|
||||
buf << "Automatic slot change " << (autoSlot ? "enabled" : "disabled");
|
||||
myOSystem.frameBuffer().showMessage(buf.str());
|
||||
myOSystem.frameBuffer().showTextMessage(buf.str());
|
||||
|
||||
myOSystem.settings().setValue("autoslot", autoSlot);
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ void Cartridge3EWidget::loadConfig()
|
|||
myBankWidgets[1]->setSelectedIndex(bank - myCart.romBankCount(), oldBank != bank);
|
||||
}
|
||||
|
||||
CartDebugWidget::loadConfig();
|
||||
CartDebugWidget::loadConfig(); // Intentionally calling grand-parent method
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -67,11 +67,11 @@ class CartRamWidget : public Widget, public CommandSender
|
|||
int x, int y, int w, int h,
|
||||
CartDebugWidget& cartDebug);
|
||||
~InternalRamWidget() override = default;
|
||||
string getLabel(int addr) const override;
|
||||
|
||||
private:
|
||||
uInt8 getValue(int addr) const override;
|
||||
void setValue(int addr, uInt8 value) override;
|
||||
string getLabel(int addr) const override;
|
||||
|
||||
void fillList(uInt32 start, uInt32 size, IntArray& alist,
|
||||
IntArray& vlist, BoolArray& changed) const override;
|
||||
|
|
|
@ -85,18 +85,19 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
|
|||
_w = lwidth + myPCGrid->getWidth() + myPCLabel->getWidth() + 20;
|
||||
|
||||
// Create labels showing the source of data for SP/A/X/Y registers
|
||||
const std::array<string, 4> labels = { "SP", "A", "X", "Y" };
|
||||
xpos += myCpuGridBinValue->getWidth() + 20;
|
||||
int src_y = ypos, src_w = (max_w - xpos + x) - 10;
|
||||
for(int i = 0; i < 4; ++i)
|
||||
{
|
||||
myCpuDataSrc[i] = new EditTextWidget(boss, nfont, xpos, src_y, src_w, fontHeight + 1);
|
||||
myCpuDataSrc[i]->setToolTip("Source label of last load into " + labels[i] + ".");
|
||||
myCpuDataSrc[i]->setEditable(false, true);
|
||||
src_y += fontHeight + 2;
|
||||
}
|
||||
|
||||
// Add labels for other CPU registers
|
||||
xpos = x;
|
||||
const std::array<string, 4> labels = { "SP ", "A ", "X ", "Y " };
|
||||
for(int row = 0; row < 4; ++row)
|
||||
{
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + row*lineHeight + 2,
|
||||
|
@ -109,10 +110,10 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
|
|||
{
|
||||
new StaticTextWidget(boss, lfont, myCpuGridDecValue->getLeft() - fontWidth,
|
||||
ypos + row * lineHeight + 2,
|
||||
lwidth - 2, fontHeight, "#");
|
||||
fontWidth, fontHeight, "#");
|
||||
new StaticTextWidget(boss, lfont, myCpuGridBinValue->getLeft() - fontWidth,
|
||||
ypos + row * lineHeight + 2,
|
||||
lwidth - 2, fontHeight, "%");
|
||||
fontWidth, fontHeight, "%");
|
||||
}
|
||||
|
||||
// Create a bitfield widget for changing the processor status
|
||||
|
@ -139,10 +140,9 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
|
|||
xpos = myCpuDataSrc[0]->getLeft();
|
||||
new StaticTextWidget(boss, lfont, xpos - fontWidth * 4.5, ypos + 2, "Dest");
|
||||
myCpuDataDest = new EditTextWidget(boss, nfont, xpos, ypos, src_w, fontHeight + 1);
|
||||
myCpuDataDest->setToolTip("Destination label of last store.");
|
||||
myCpuDataDest->setEditable(false, true);
|
||||
|
||||
|
||||
|
||||
_h = ypos + myPSRegister->getHeight() - y;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "RamWidget.hxx"
|
||||
#include "DataGridRamWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
DataGridRamWidget::DataGridRamWidget(GuiObject* boss, const RamWidget& ram,
|
||||
const GUI::Font& font,
|
||||
int x, int y, int cols, int rows,
|
||||
int colchars, int bits,
|
||||
Common::Base::Fmt base,
|
||||
bool useScrollbar)
|
||||
: DataGridWidget(boss, font, x, y, cols, rows, colchars,
|
||||
bits, base, useScrollbar),
|
||||
_ram(ram)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string DataGridRamWidget::getToolTip(const Common::Point& pos) const
|
||||
{
|
||||
const int idx = getToolTipIndex(pos);
|
||||
|
||||
if(idx < 0)
|
||||
return EmptyString;
|
||||
|
||||
const Int32 addr = _addrList[idx];
|
||||
const string label = _ram.getLabel(addr);
|
||||
const string tip = DataGridWidget::getToolTip(pos);
|
||||
|
||||
if(label.empty())
|
||||
return tip;
|
||||
|
||||
ostringstream buf;
|
||||
|
||||
buf << _ram.getLabel(addr) << '\n' << tip;
|
||||
|
||||
return buf.str();
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#ifndef DATA_GRID_RAM_WIDGET_HXX
|
||||
#define DATA_GRID_RAM_WIDGET_HXX
|
||||
|
||||
class RamWidget;
|
||||
|
||||
#include "DataGridWidget.hxx"
|
||||
#include "Base.hxx"
|
||||
|
||||
class DataGridRamWidget : public DataGridWidget
|
||||
{
|
||||
public:
|
||||
DataGridRamWidget(GuiObject* boss, const RamWidget& ram,
|
||||
const GUI::Font& font,
|
||||
int x, int y, int cols, int rows,
|
||||
int colchars, int bits,
|
||||
Common::Base::Fmt format = Common::Base::Fmt::_DEFAULT,
|
||||
bool useScrollbar = false);
|
||||
~DataGridRamWidget() override = default;
|
||||
|
||||
string getToolTip(const Common::Point& pos) const override;
|
||||
|
||||
private:
|
||||
const RamWidget& _ram;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
DataGridRamWidget() = delete;
|
||||
DataGridRamWidget(const DataGridRamWidget&) = delete;
|
||||
DataGridRamWidget(DataGridRamWidget&&) = delete;
|
||||
DataGridRamWidget& operator=(const DataGridRamWidget&) = delete;
|
||||
DataGridRamWidget& operator=(DataGridRamWidget&&) = delete;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "Widget.hxx"
|
||||
#include "Dialog.hxx"
|
||||
#include "ToolTip.hxx"
|
||||
#include "Font.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "Debugger.hxx"
|
||||
|
@ -45,6 +46,7 @@ DataGridWidget::DataGridWidget(GuiObject* boss, const GUI::Font& font,
|
|||
_base(base)
|
||||
{
|
||||
_flags = Widget::FLAG_ENABLED | Widget::FLAG_RETAIN_FOCUS | Widget::FLAG_WANTS_RAWDATA;
|
||||
_editMode = false;
|
||||
|
||||
// Make sure all lists contain some default values
|
||||
_hiliteList.clear();
|
||||
|
@ -239,20 +241,6 @@ void DataGridWidget::setRange(int lower, int upper)
|
|||
_upperBound = std::min(1 << _bits, upper);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DataGridWidget::handleMouseEntered()
|
||||
{
|
||||
setFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DataGridWidget::handleMouseLeft()
|
||||
{
|
||||
clearFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DataGridWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
|
||||
{
|
||||
|
@ -307,6 +295,7 @@ void DataGridWidget::handleMouseWheel(int x, int y, int direction)
|
|||
else if(direction < 0)
|
||||
incrementCell();
|
||||
}
|
||||
dialog().tooltip().hide();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -504,6 +493,7 @@ bool DataGridWidget::handleKeyDown(StellaKey key, StellaMod mod)
|
|||
sendCommand(DataGridWidget::kSelectionChangedCmd, _selectedItem, _id);
|
||||
|
||||
setDirty();
|
||||
dialog().tooltip().hide();
|
||||
}
|
||||
|
||||
_currentKeyDown = key;
|
||||
|
@ -583,6 +573,49 @@ void DataGridWidget::handleCommand(CommandSender* sender, int cmd,
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int DataGridWidget::getToolTipIndex(const Common::Point& pos) const
|
||||
{
|
||||
const int col = (pos.x - getAbsX()) / _colWidth;
|
||||
const int row = (pos.y - getAbsY()) / _rowHeight;
|
||||
|
||||
if(row >= 0 && row < _rows && col >= 0 && col < _cols)
|
||||
return row * _cols + col;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string DataGridWidget::getToolTip(const Common::Point& pos) const
|
||||
{
|
||||
const int idx = getToolTipIndex(pos);
|
||||
|
||||
if(idx < 0)
|
||||
return EmptyString;
|
||||
|
||||
const Int32 val = _valueList[idx];
|
||||
ostringstream buf;
|
||||
|
||||
buf << _toolTipText
|
||||
<< "$" << Common::Base::toString(val, Common::Base::Fmt::_16)
|
||||
<< " = #" << val;
|
||||
if(val < 0x100)
|
||||
{
|
||||
if(val >= 0x80)
|
||||
buf << '/' << -(0x100 - val);
|
||||
buf << " = %" << Common::Base::toString(val, Common::Base::Fmt::_2);
|
||||
}
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool DataGridWidget::changedToolTip(const Common::Point& oldPos,
|
||||
const Common::Point& newPos) const
|
||||
{
|
||||
return getToolTipIndex(oldPos) != getToolTipIndex(newPos);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DataGridWidget::drawWidget(bool hilite)
|
||||
{
|
||||
|
|
|
@ -84,6 +84,9 @@ class DataGridWidget : public EditableWidget
|
|||
|
||||
void setCrossed(bool enable) { _crossGrid = enable; }
|
||||
|
||||
string getToolTip(const Common::Point& pos) const override;
|
||||
bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override;
|
||||
|
||||
protected:
|
||||
void drawWidget(bool hilite) override;
|
||||
|
||||
|
@ -98,11 +101,12 @@ class DataGridWidget : public EditableWidget
|
|||
void receivedFocusWidget() override;
|
||||
void lostFocusWidget() override;
|
||||
|
||||
bool hasToolTip() const override { return true; }
|
||||
int getToolTipIndex(const Common::Point& pos) const;
|
||||
|
||||
void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleMouseUp(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleMouseWheel(int x, int y, int direction) override;
|
||||
void handleMouseEntered() override;
|
||||
void handleMouseLeft() override;
|
||||
bool handleText(char text) override;
|
||||
bool handleKeyDown(StellaKey key, StellaMod mod) override;
|
||||
bool handleKeyUp(StellaKey key, StellaMod mod) override;
|
||||
|
@ -128,7 +132,6 @@ class DataGridWidget : public EditableWidget
|
|||
BoolArray _changedList;
|
||||
BoolArray _hiliteList;
|
||||
|
||||
bool _editMode{false};
|
||||
int _selectedItem{0};
|
||||
StellaKey _currentKeyDown{KBDK_UNKNOWN};
|
||||
string _backupString;
|
||||
|
@ -148,6 +151,7 @@ class DataGridWidget : public EditableWidget
|
|||
|
||||
void enableEditMode(bool state) { _editMode = state; }
|
||||
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
DataGridWidget() = delete;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "Cart.hxx"
|
||||
#include "Widget.hxx"
|
||||
#include "Dialog.hxx"
|
||||
#include "ToolTip.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "StellaKeys.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
|
@ -406,6 +407,7 @@ void DebuggerDialog::createFont()
|
|||
break;
|
||||
}
|
||||
}
|
||||
tooltip().setFont(*myNFont);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -76,7 +76,7 @@ class DebuggerDialog : public Dialog
|
|||
void saveConfig() override;
|
||||
|
||||
private:
|
||||
void center() override { positionAt(0); }
|
||||
void setPosition() override { positionAt(0); }
|
||||
void loadConfig() override;
|
||||
void handleKeyDown(StellaKey key, StellaMod mod, bool repeated) override;
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "DataGridWidget.hxx"
|
||||
#include "DataGridRamWidget.hxx"
|
||||
#include "EditTextWidget.hxx"
|
||||
#include "GuiObject.hxx"
|
||||
#include "InputTextDialog.hxx"
|
||||
|
@ -54,7 +54,7 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
|
|||
// Add RAM grid (with scrollbar)
|
||||
int xpos = x + _font.getStringWidth("xxxx");
|
||||
bool useScrollbar = ramsize / numrows > 16;
|
||||
myRamGrid = new DataGridWidget(_boss, _nfont, xpos, ypos,
|
||||
myRamGrid = new DataGridRamWidget(_boss, *this, _nfont, xpos, ypos,
|
||||
16, myNumRows, 2, 8, Common::Base::Fmt::_16, useScrollbar);
|
||||
myRamGrid->setTarget(this);
|
||||
myRamGrid->setID(kRamGridID);
|
||||
|
|
|
@ -22,6 +22,7 @@ class GuiObject;
|
|||
class ButtonWidget;
|
||||
class DataGridWidget;
|
||||
class DataGridOpsWidget;
|
||||
class DataGridRamWidget;
|
||||
class EditTextWidget;
|
||||
class StaticTextWidget;
|
||||
class InputTextDialog;
|
||||
|
@ -41,11 +42,12 @@ class RamWidget : public Widget, public CommandSender
|
|||
void setOpsWidget(DataGridOpsWidget* w);
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
|
||||
virtual string getLabel(int addr) const = 0;
|
||||
|
||||
private:
|
||||
// To be implemented by derived classes
|
||||
virtual uInt8 getValue(int addr) const = 0;
|
||||
virtual void setValue(int addr, uInt8 value) = 0;
|
||||
virtual string getLabel(int addr) const = 0;
|
||||
|
||||
virtual void fillList(uInt32 start, uInt32 size,
|
||||
IntArray& alist, IntArray& vlist,
|
||||
|
@ -97,7 +99,7 @@ class RamWidget : public Widget, public CommandSender
|
|||
StaticTextWidget* myRamStart{nullptr};
|
||||
std::array<StaticTextWidget*, 16> myRamLabels{nullptr};
|
||||
|
||||
DataGridWidget* myRamGrid{nullptr};
|
||||
DataGridRamWidget* myRamGrid{nullptr};
|
||||
DataGridWidget* myHexValue{nullptr};
|
||||
DataGridWidget* myDecValue{nullptr};
|
||||
DataGridWidget* myBinValue{nullptr};
|
||||
|
|
|
@ -36,10 +36,11 @@ class RiotRamWidget : public RamWidget
|
|||
int x, int y, int w);
|
||||
~RiotRamWidget() override = default;
|
||||
|
||||
string getLabel(int addr) const override;
|
||||
|
||||
private:
|
||||
uInt8 getValue(int addr) const override;
|
||||
void setValue(int addr, uInt8 value) override;
|
||||
string getLabel(int addr) const override;
|
||||
|
||||
void fillList(uInt32 start, uInt32 size, IntArray& alist,
|
||||
IntArray& vlist, BoolArray& changed) const override;
|
||||
|
|
|
@ -66,11 +66,13 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont,
|
|||
on.push_back("1");
|
||||
}
|
||||
|
||||
StringList labels;
|
||||
|
||||
#define CREATE_IO_REGS(desc, bits, bitsID, editable) \
|
||||
t = new StaticTextWidget(boss, lfont, xpos, ypos+2, lwidth, fontHeight,\
|
||||
desc, TextAlign::Left); \
|
||||
desc); \
|
||||
xpos += t->getWidth() + 5; \
|
||||
bits = new ToggleBitWidget(boss, nfont, xpos, ypos, 8, 1); \
|
||||
bits = new ToggleBitWidget(boss, nfont, xpos, ypos, 8, 1, 1, labels); \
|
||||
bits->setTarget(this); \
|
||||
bits->setID(bitsID); \
|
||||
if(editable) addFocusWidget(bits); else bits->setEditable(false); \
|
||||
|
@ -78,6 +80,7 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont,
|
|||
bits->setList(off, on);
|
||||
|
||||
// SWCHA bits in 'poke' mode
|
||||
labels.clear();
|
||||
CREATE_IO_REGS("SWCHA(W)", mySWCHAWriteBits, kSWCHABitsID, true)
|
||||
col = xpos + 20; // remember this for adding widgets to the second column
|
||||
|
||||
|
@ -87,10 +90,20 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont,
|
|||
|
||||
// SWCHA bits in 'peek' mode
|
||||
xpos = 10; ypos += lineHeight + 5;
|
||||
labels.clear();
|
||||
labels.push_back("P0 right");
|
||||
labels.push_back("P0 left");
|
||||
labels.push_back("P0 down");
|
||||
labels.push_back("P0 up");
|
||||
labels.push_back("P1 right");
|
||||
labels.push_back("P1 left");
|
||||
labels.push_back("P1 down");
|
||||
labels.push_back("P1 up");
|
||||
CREATE_IO_REGS("SWCHA(R)", mySWCHAReadBits, kSWCHARBitsID, true)
|
||||
|
||||
// SWCHB bits in 'poke' mode
|
||||
xpos = 10; ypos += 2 * lineHeight;
|
||||
labels.clear();
|
||||
CREATE_IO_REGS("SWCHB(W)", mySWCHBWriteBits, kSWCHBBitsID, true)
|
||||
|
||||
// SWBCNT bits
|
||||
|
@ -99,6 +112,15 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont,
|
|||
|
||||
// SWCHB bits in 'peek' mode
|
||||
xpos = 10; ypos += lineHeight + 5;
|
||||
labels.clear();
|
||||
labels.push_back("P1 difficulty");
|
||||
labels.push_back("P0 difficulty");
|
||||
labels.push_back("");
|
||||
labels.push_back("");
|
||||
labels.push_back("Color/B+W");
|
||||
labels.push_back("");
|
||||
labels.push_back("Select");
|
||||
labels.push_back("Reset");
|
||||
CREATE_IO_REGS("SWCHB(R)", mySWCHBReadBits, kSWCHBRBitsID, true)
|
||||
|
||||
// Timer registers (R/W)
|
||||
|
|
|
@ -100,7 +100,7 @@ void RomListSettings::show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RomListSettings::center()
|
||||
void RomListSettings::setPosition()
|
||||
{
|
||||
// First set position according to original coordinates
|
||||
surface().setDstPos(_xorig, _yorig);
|
||||
|
|
|
@ -38,8 +38,8 @@ class RomListSettings : public Dialog, public CommandSender
|
|||
('data' will be the currently selected line number in RomListWidget) */
|
||||
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;
|
||||
/** This dialog uses its own positioning, so we override Dialog::setPosition() */
|
||||
void setPosition() override;
|
||||
|
||||
private:
|
||||
uInt32 _xorig{0}, _yorig{0};
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "Debugger.hxx"
|
||||
#include "DiStella.hxx"
|
||||
#include "Widget.hxx"
|
||||
#include "Dialog.hxx"
|
||||
#include "ToolTip.hxx"
|
||||
#include "StellaKeys.hxx"
|
||||
#include "FBSurface.hxx"
|
||||
#include "Font.hxx"
|
||||
|
@ -39,6 +41,9 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont,
|
|||
_textcolor = kTextColor;
|
||||
_textcolorhi = kTextColor;
|
||||
|
||||
_editMode = false;
|
||||
_dyText = -1; // fixes the vertical position of selected text
|
||||
|
||||
_cols = w / _fontWidth;
|
||||
_rows = h / _lineHeight;
|
||||
|
||||
|
@ -242,6 +247,7 @@ 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();
|
||||
dialog().tooltip().hide();
|
||||
myMenu->show(x + getAbsX(), y + getAbsY(),
|
||||
dialog().surface().dstRect(), _selectedItem);
|
||||
}
|
||||
|
@ -282,20 +288,6 @@ void RomListWidget::handleMouseWheel(int x, int y, int direction)
|
|||
myScrollBar->handleMouseWheel(x, y, direction);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RomListWidget::handleMouseEntered()
|
||||
{
|
||||
setFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RomListWidget::handleMouseLeft()
|
||||
{
|
||||
clearFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool RomListWidget::handleText(char text)
|
||||
{
|
||||
|
@ -454,6 +446,79 @@ void RomListWidget::lostFocusWidget()
|
|||
abortEditMode();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Common::Point RomListWidget::getToolTipIndex(const Common::Point& pos) const
|
||||
{
|
||||
const Common::Rect& r = getEditRect();
|
||||
const int col = (pos.x - r.x() - getAbsX()) / _font.getMaxCharWidth();
|
||||
const int row = (pos.y - getAbsY()) / _lineHeight;
|
||||
|
||||
if(col < 0 || col >= 8
|
||||
|| row < 0 || row + _currentPos >= int(myDisasm->list.size()))
|
||||
return Common::Point(-1, -1);
|
||||
else
|
||||
return Common::Point(col, row + _currentPos);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string RomListWidget::getToolTip(const Common::Point& pos) const
|
||||
{
|
||||
const Common::Point& idx = getToolTipIndex(pos);
|
||||
|
||||
if(idx.y < 0)
|
||||
return EmptyString;
|
||||
|
||||
const string bytes = myDisasm->list[idx.y].bytes;
|
||||
|
||||
if(static_cast<Int32>(bytes.length()) < idx.x + 1)
|
||||
return EmptyString;
|
||||
|
||||
Int32 val;
|
||||
if(bytes.length() == 8 && bytes[2] != ' ')
|
||||
{
|
||||
// Binary value
|
||||
val = static_cast<Int32>(stol(bytes, nullptr, 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 1..3 hex values
|
||||
if(idx.x == 2)
|
||||
// Skip gap after first byte
|
||||
return EmptyString;
|
||||
|
||||
string valStr;
|
||||
|
||||
if(idx.x < 2 || bytes.length() < 8)
|
||||
// 1 or 2 hex bytes, get one hex byte
|
||||
valStr = bytes.substr((idx.x / 3) * 3, 2);
|
||||
else
|
||||
// 3 hex bytes, get two rightmost hex bytes
|
||||
valStr = bytes.substr(6, 2) + bytes.substr(3, 2);
|
||||
|
||||
val = static_cast<Int32>(stol(valStr, nullptr, 16));
|
||||
}
|
||||
ostringstream buf;
|
||||
|
||||
buf << _toolTipText
|
||||
<< "$" << Common::Base::toString(val, Common::Base::Fmt::_16)
|
||||
<< " = #" << val;
|
||||
if(val < 0x100)
|
||||
{
|
||||
if(val >= 0x80)
|
||||
buf << '/' << -(0x100 - val);
|
||||
buf << " = %" << Common::Base::toString(val, Common::Base::Fmt::_2);
|
||||
}
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool RomListWidget::changedToolTip(const Common::Point& oldPos,
|
||||
const Common::Point& newPos) const
|
||||
{
|
||||
return getToolTipIndex(oldPos) != getToolTipIndex(newPos);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RomListWidget::drawWidget(bool hilite)
|
||||
{
|
||||
|
@ -480,20 +545,20 @@ void RomListWidget::drawWidget(bool hilite)
|
|||
codeDisasmW = actualWidth;
|
||||
|
||||
xpos = _x + CheckboxWidget::boxSize(_font) + 10; ypos = _y + 2;
|
||||
for (i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++, ypos += _lineHeight)
|
||||
for(i = 0, pos = _currentPos; i < _rows && pos < len; i++, pos++, ypos += _lineHeight)
|
||||
{
|
||||
ColorId bytesColor = textColor;
|
||||
|
||||
// Draw checkboxes for correct lines (takes scrolling into account)
|
||||
// Mark checkboxes dirty for correct lines (takes scrolling into account)
|
||||
myCheckList[i]->setState(instance().debugger().
|
||||
checkBreakPoint(dlist[pos].address,
|
||||
instance().debugger().cartDebug().getBank(dlist[pos].address)));
|
||||
|
||||
myCheckList[i]->setDirty();
|
||||
// draw immediately, because chain order is not deterministic
|
||||
myCheckList[i]->draw();
|
||||
|
||||
// Draw highlighted item in a frame
|
||||
if (_highlightedItem == pos)
|
||||
if(_highlightedItem == pos)
|
||||
s.frameRect(_x + l.x() - 3, ypos - 1, _w - l.x(), _lineHeight, onTop ? kWidColorHi : kBGColorLo);
|
||||
|
||||
// Draw the selected item inverted, on a highlighted background.
|
||||
|
@ -514,8 +579,8 @@ void RomListWidget::drawWidget(bool hilite)
|
|||
|
||||
// Bytes are only editable if they represent code, graphics, or accessible data
|
||||
// Otherwise, the disassembly should get all remaining space
|
||||
if(dlist[pos].type & (Device::CODE|Device::GFX|Device::PGFX|
|
||||
Device::COL|Device::PCOL|Device::BCOL|Device::DATA))
|
||||
if(dlist[pos].type & (Device::CODE | Device::GFX | Device::PGFX |
|
||||
Device::COL | Device::PCOL | Device::BCOL | Device::DATA))
|
||||
{
|
||||
if(dlist[pos].type == Device::CODE)
|
||||
{
|
||||
|
@ -523,7 +588,7 @@ void RomListWidget::drawWidget(bool hilite)
|
|||
s.drawString(_font, dlist[pos].disasm.substr(0, 7), xpos + _labelWidth, ypos,
|
||||
7 * _fontWidth, textColor);
|
||||
// Draw operand
|
||||
if (dlist[pos].disasm.length() > 8)
|
||||
if(dlist[pos].disasm.length() > 8)
|
||||
s.drawString(_font, dlist[pos].disasm.substr(8), xpos + _labelWidth + 7 * _fontWidth, ypos,
|
||||
codeDisasmW - 7 * _fontWidth, textColor);
|
||||
// Draw cycle count
|
||||
|
@ -542,7 +607,7 @@ void RomListWidget::drawWidget(bool hilite)
|
|||
|
||||
// Draw bytes
|
||||
{
|
||||
if (_selectedItem == pos && _editMode)
|
||||
if(_selectedItem == pos && _editMode)
|
||||
{
|
||||
adjustOffset();
|
||||
s.drawString(_font, editString(), _x + r.x(), ypos, r.w(), textColor,
|
||||
|
@ -580,8 +645,8 @@ Common::Rect RomListWidget::getEditRect() const
|
|||
{
|
||||
const int yoffset = std::max(0, (_selectedItem - _currentPos) * _lineHeight);
|
||||
|
||||
return Common::Rect(2 + _w - _bytesWidth, 1 + yoffset,
|
||||
_w, _lineHeight + yoffset);
|
||||
return Common::Rect(2 + _w - _bytesWidth, 1 + yoffset + 1,
|
||||
_w, _lineHeight + yoffset + 1);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -594,6 +659,7 @@ void RomListWidget::startEditMode()
|
|||
return;
|
||||
|
||||
_editMode = true;
|
||||
dialog().tooltip().hide();
|
||||
switch(myDisasm->list[_selectedItem].type)
|
||||
{
|
||||
case Device::GFX:
|
||||
|
|
|
@ -56,12 +56,13 @@ class RomListWidget : public EditableWidget
|
|||
void setSelected(int item);
|
||||
void setHighlighted(int item);
|
||||
|
||||
string getToolTip(const Common::Point& pos) const override;
|
||||
bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override;
|
||||
|
||||
protected:
|
||||
void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleMouseUp(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleMouseWheel(int x, int y, int direction) override;
|
||||
void handleMouseEntered() override;
|
||||
void handleMouseLeft() override;
|
||||
bool handleText(char text) override;
|
||||
bool handleKeyDown(StellaKey key, StellaMod mod) override;
|
||||
bool handleKeyUp(StellaKey key, StellaMod mod) override;
|
||||
|
@ -79,11 +80,15 @@ class RomListWidget : public EditableWidget
|
|||
void endEditMode() override;
|
||||
void abortEditMode() override;
|
||||
void lostFocusWidget() override;
|
||||
|
||||
bool hasToolTip() const override { return true; }
|
||||
|
||||
void scrollToSelected() { scrollToCurrent(_selectedItem); }
|
||||
void scrollToHighlighted() { scrollToCurrent(_highlightedItem); }
|
||||
|
||||
private:
|
||||
void scrollToCurrent(int item);
|
||||
Common::Point getToolTipIndex(const Common::Point& pos) const;
|
||||
|
||||
private:
|
||||
unique_ptr<RomListSettings> myMenu;
|
||||
|
@ -96,7 +101,6 @@ class RomListWidget : public EditableWidget
|
|||
int _currentPos{0}; // position of first line in visible window
|
||||
int _selectedItem{-1};
|
||||
int _highlightedItem{-1};
|
||||
bool _editMode{false};
|
||||
StellaKey _currentKeyDown{KBDK_UNKNOWN};
|
||||
Common::Base::Fmt _base{Common::Base::Fmt::_DEFAULT}; // base used during editing
|
||||
|
||||
|
|
|
@ -90,10 +90,6 @@ void RomWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
|||
case RomListWidget::kBPointChangedCmd:
|
||||
// 'data' is the line in the disassemblylist to be accessed
|
||||
toggleBreak(data);
|
||||
// Refresh the romlist, since the breakpoint may not have
|
||||
// actually changed
|
||||
myRomList->setDirty();
|
||||
myRomList->draw();
|
||||
break;
|
||||
|
||||
case RomListWidget::kRomChangedCmd:
|
||||
|
@ -199,7 +195,7 @@ void RomWidget::runtoPC(int disasm_line)
|
|||
ostringstream command;
|
||||
command << "runtopc #" << address;
|
||||
string msg = instance().debugger().run(command.str());
|
||||
instance().frameBuffer().showMessage(msg);
|
||||
instance().frameBuffer().showTextMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,30 +60,35 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont,
|
|||
xpos = x;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cycls" : "F. Cycls");
|
||||
myFrameCycles = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myFrameCycles->setToolTip("CPU cycles executed this frame.");
|
||||
myFrameCycles->setEditable(false, true);
|
||||
|
||||
// Left: WSync Cycles
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "WSync Cycls" : "WSync C.");
|
||||
myWSyncCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myWSyncCylces->setToolTip("CPU cycles used for WSYNC this frame.");
|
||||
myWSyncCylces->setEditable(false, true);
|
||||
|
||||
// Left: Timer Cycles
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Timer Cycls" : "Timer C.");
|
||||
myTimerCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myTimerCylces->setToolTip("CPU cycles roughly used for INTIM reads this frame.");
|
||||
myTimerCylces->setEditable(false, true);
|
||||
|
||||
// Left: Total Cycles
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Total");
|
||||
myTotalCycles = new EditTextWidget(boss, nfont, xpos + lwidth8, ypos - 1, twidth, lineHeight);
|
||||
myTotalCycles->setToolTip("Total CPU cycles executed for this session (E notation).");
|
||||
myTotalCycles->setEditable(false, true);
|
||||
|
||||
// Left: Delta Cycles
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Delta");
|
||||
myDeltaCycles = new EditTextWidget(boss, nfont, xpos + lwidth8, ypos - 1, twidth, lineHeight);
|
||||
myDeltaCycles->setToolTip("CPU cycles executed since last debug break.");
|
||||
myDeltaCycles->setEditable(false, true);
|
||||
|
||||
// Right column
|
||||
|
@ -93,6 +98,7 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont,
|
|||
// Right: Frame Count
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cnt." : "Frame");
|
||||
myFrameCount = new EditTextWidget(boss, nfont, xpos + lwidthR, ypos - 1, fwidth, lineHeight);
|
||||
myFrameCount->setToolTip("Total number of frames executed this session.");
|
||||
myFrameCount->setEditable(false, true);
|
||||
|
||||
lwidth = lfont.getStringWidth(longstr ? "Color Clock " : "Pixel Pos ") + LGAP;
|
||||
|
@ -102,28 +108,33 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont,
|
|||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scanline" : "Scn Ln");
|
||||
myScanlineCountLast = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myScanlineCountLast->setToolTip("Number of scanlines of last frame.");
|
||||
myScanlineCountLast->setEditable(false, true);
|
||||
myScanlineCount = new EditTextWidget(boss, nfont,
|
||||
xpos + lwidth - myScanlineCountLast->getWidth() - 2, ypos - 1,
|
||||
fwidth, lineHeight);
|
||||
myScanlineCount->setToolTip("Current scanline of this frame.");
|
||||
myScanlineCount->setEditable(false, true);
|
||||
|
||||
// Right: Scan Cycle
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scan Cycle" : "Scn Cycle");
|
||||
myScanlineCycles = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myScanlineCycles->setToolTip("CPU cycles in current scanline.");
|
||||
myScanlineCycles->setEditable(false, true);
|
||||
|
||||
// Right: Pixel Pos
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Pixel Pos");
|
||||
myPixelPosition = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myPixelPosition->setToolTip("Pixel position in current scanline.");
|
||||
myPixelPosition->setEditable(false, true);
|
||||
|
||||
// Right: Color Clock
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Color Clock" : "Color Clk");
|
||||
myColorClocks = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myColorClocks->setToolTip("Color clocks in current scanline.");
|
||||
myColorClocks->setEditable(false, true);
|
||||
|
||||
// Calculate actual dimensions
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "FBSurface.hxx"
|
||||
#include "Widget.hxx"
|
||||
#include "GuiObject.hxx"
|
||||
#include "Dialog.hxx"
|
||||
#include "ToolTip.hxx"
|
||||
#include "ContextMenu.hxx"
|
||||
#include "TiaZoomWidget.hxx"
|
||||
#include "Debugger.hxx"
|
||||
|
@ -55,6 +57,7 @@ TiaOutputWidget::TiaOutputWidget(GuiObject* boss, const GUI::Font& font,
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TiaOutputWidget::loadConfig()
|
||||
{
|
||||
setEnabled(true);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
|
@ -92,10 +95,10 @@ void TiaOutputWidget::saveSnapshot(int execDepth, const string& execPrefix)
|
|||
message = e.what();
|
||||
}
|
||||
if (execDepth == 0) {
|
||||
instance().frameBuffer().showMessage(message);
|
||||
instance().frameBuffer().showTextMessage(message);
|
||||
}
|
||||
#else
|
||||
instance().frameBuffer().showMessage("PNG image saving not supported");
|
||||
instance().frameBuffer().showTextMessage("PNG image saving not supported");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -110,6 +113,7 @@ void TiaOutputWidget::handleMouseDown(int x, int y, MouseButton b, int clickCoun
|
|||
myClickX = x;
|
||||
myClickY = y;
|
||||
|
||||
dialog().tooltip().hide();
|
||||
// Add menu at current x,y mouse location
|
||||
myMenu->show(x + getAbsX(), y + getAbsY(), dialog().surface().dstRect());
|
||||
}
|
||||
|
@ -135,7 +139,7 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in
|
|||
{
|
||||
command << "scanline #" << lines;
|
||||
string message = instance().debugger().parser().run(command.str());
|
||||
instance().frameBuffer().showMessage(message);
|
||||
instance().frameBuffer().showTextMessage(message);
|
||||
}
|
||||
}
|
||||
else if(rmb == "bp")
|
||||
|
@ -144,7 +148,7 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in
|
|||
int scanline = myClickY + startLine;
|
||||
command << "breakif _scan==#" << scanline;
|
||||
string message = instance().debugger().parser().run(command.str());
|
||||
instance().frameBuffer().showMessage(message);
|
||||
instance().frameBuffer().showTextMessage(message);
|
||||
}
|
||||
else if(rmb == "zoom")
|
||||
{
|
||||
|
@ -158,6 +162,51 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Common::Point TiaOutputWidget::getToolTipIndex(const Common::Point& pos) const
|
||||
{
|
||||
const Int32 width = instance().console().tia().width();
|
||||
const Int32 height = instance().console().tia().height();
|
||||
const int col = (pos.x - 1 - getAbsX()) >> 1;
|
||||
const int row = pos.y - 1 - getAbsY();
|
||||
|
||||
if(col < 0 || col >= width || row < 0 || row >= height)
|
||||
return Common::Point(-1, -1);
|
||||
else
|
||||
return Common::Point(col, row);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string TiaOutputWidget::getToolTip(const Common::Point& pos) const
|
||||
{
|
||||
const Common::Point& idx = getToolTipIndex(pos);
|
||||
|
||||
if(idx.x < 0)
|
||||
return EmptyString;
|
||||
|
||||
const uInt32 height = instance().console().tia().height();
|
||||
// limit to 274 lines (PAL default without scaling)
|
||||
const uInt32 yStart = height <= FrameManager::Metrics::baseHeightPAL
|
||||
? 0 : (height - FrameManager::Metrics::baseHeightPAL) >> 1;
|
||||
const Int32 i = idx.x + (yStart + idx.y) * instance().console().tia().width();
|
||||
uInt8* tiaOutputBuffer = instance().console().tia().outputBuffer();
|
||||
ostringstream buf;
|
||||
|
||||
buf << _toolTipText
|
||||
<< "X: #" << idx.x
|
||||
<< "\nY: #" << idx.y
|
||||
<< "\nC: $" << Common::Base::toString(tiaOutputBuffer[i], Common::Base::Fmt::_16);
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool TiaOutputWidget::changedToolTip(const Common::Point& oldPos,
|
||||
const Common::Point& newPos) const
|
||||
{
|
||||
return getToolTipIndex(oldPos) != getToolTipIndex(newPos);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TiaOutputWidget::drawWidget(bool hilite)
|
||||
{
|
||||
|
|
|
@ -47,6 +47,13 @@ class TiaOutputWidget : public Widget, public CommandSender
|
|||
bool handleKeyDown(StellaKey key, StellaMod mod) override;
|
||||
bool handleKeyUp(StellaKey key, StellaMod mod) override;
|
||||
*/
|
||||
string getToolTip(const Common::Point& pos) const override;
|
||||
bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override;
|
||||
|
||||
protected:
|
||||
bool hasToolTip() const override { return true; }
|
||||
Common::Point getToolTipIndex(const Common::Point& pos) const;
|
||||
|
||||
private:
|
||||
unique_ptr<ContextMenu> myMenu;
|
||||
TiaZoomWidget* myZoom{nullptr};
|
||||
|
|
|
@ -563,7 +563,7 @@ TiaWidget::TiaWidget(GuiObject* boss, const GUI::Font& lfont,
|
|||
new StaticTextWidget(boss, lfont, xpos, ypos+2, 2*fontWidth, fontHeight,
|
||||
"PF", TextAlign::Left);
|
||||
xpos += 2*fontWidth + 5;
|
||||
myPF[0] = new TogglePixelWidget(boss, nfont, xpos, ypos+1, 4, 1);
|
||||
myPF[0] = new TogglePixelWidget(boss, nfont, xpos, ypos+1, 4, 1, 4);
|
||||
myPF[0]->setTarget(this);
|
||||
myPF[0]->setID(kPF0ID);
|
||||
addFocusWidget(myPF[0]);
|
||||
|
@ -919,10 +919,14 @@ void TiaWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
|||
|
||||
case kRefP0ID:
|
||||
tia.refP0(myRefP0->getState() ? 1 : 0);
|
||||
myGRP0->setIntState(myGRP0->getIntState(), !myRefP0->getState());
|
||||
myGRP0Old->setIntState(myGRP0Old->getIntState(), !myRefP0->getState());
|
||||
break;
|
||||
|
||||
case kRefP1ID:
|
||||
tia.refP1(myRefP1->getState() ? 1 : 0);
|
||||
myGRP1->setIntState(myGRP1->getIntState(), !myRefP1->getState());
|
||||
myGRP1Old->setIntState(myGRP1Old->getIntState(), !myRefP1->getState());
|
||||
break;
|
||||
|
||||
case kDelP0ID:
|
||||
|
@ -1043,8 +1047,8 @@ void TiaWidget::loadConfig()
|
|||
myGRP0Old->setColor(kBGColorLo);
|
||||
myGRP0Old->setCrossed(true);
|
||||
}
|
||||
myGRP0->setIntState(state.gr[TiaState::P0], false);
|
||||
myGRP0Old->setIntState(state.gr[TiaState::P0+2], false);
|
||||
myGRP0->setIntState(state.gr[TiaState::P0], state.ref[TiaState::P0]);
|
||||
myGRP0Old->setIntState(state.gr[TiaState::P0+2], state.ref[TiaState::P0]);
|
||||
|
||||
// posP0
|
||||
myPosP0->setList(0, state.pos[TiaState::P0],
|
||||
|
@ -1079,8 +1083,8 @@ void TiaWidget::loadConfig()
|
|||
myGRP1Old->setColor(kBGColorLo);
|
||||
myGRP1Old->setCrossed(true);
|
||||
}
|
||||
myGRP1->setIntState(state.gr[TiaState::P1], false);
|
||||
myGRP1Old->setIntState(state.gr[TiaState::P1+2], false);
|
||||
myGRP1->setIntState(state.gr[TiaState::P1], state.ref[TiaState::P1]);
|
||||
myGRP1Old->setIntState(state.gr[TiaState::P1+2], state.ref[TiaState::P1]);
|
||||
|
||||
// posP1
|
||||
myPosP1->setList(0, state.pos[TiaState::P1],
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "FBSurface.hxx"
|
||||
#include "Widget.hxx"
|
||||
#include "GuiObject.hxx"
|
||||
#include "Dialog.hxx"
|
||||
#include "ToolTip.hxx"
|
||||
#include "ContextMenu.hxx"
|
||||
#include "FrameManager.hxx"
|
||||
#include "TiaZoomWidget.hxx"
|
||||
|
@ -127,6 +129,7 @@ void TiaZoomWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
|
|||
}
|
||||
else if(b == MouseButton::RIGHT)
|
||||
{
|
||||
dialog().tooltip().hide();
|
||||
// Add menu at current x,y mouse location
|
||||
myMenu->show(x + getAbsX(), y + getAbsY(), dialog().surface().dstRect());
|
||||
}
|
||||
|
@ -141,6 +144,8 @@ void TiaZoomWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TiaZoomWidget::handleMouseWheel(int x, int y, int direction)
|
||||
{
|
||||
dialog().tooltip().hide();
|
||||
|
||||
// zoom towards mouse position
|
||||
myClickX = x;
|
||||
myClickY = y;
|
||||
|
@ -178,19 +183,11 @@ void TiaZoomWidget::handleMouseMoved(int x, int y)
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TiaZoomWidget::handleMouseEntered()
|
||||
{
|
||||
setFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TiaZoomWidget::handleMouseLeft()
|
||||
{
|
||||
clearFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
myMouseMoving = false;
|
||||
Widget::handleMouseLeft();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -262,7 +259,7 @@ void TiaZoomWidget::handleCommand(CommandSender* sender, int cmd, int data, int
|
|||
{
|
||||
command << "scanline #" << lines;
|
||||
string message = instance().debugger().parser().run(command.str());
|
||||
instance().frameBuffer().showMessage(message);
|
||||
instance().frameBuffer().showTextMessage(message);
|
||||
}
|
||||
}
|
||||
else if(rmb == "bp")
|
||||
|
@ -271,7 +268,7 @@ void TiaZoomWidget::handleCommand(CommandSender* sender, int cmd, int data, int
|
|||
int scanline = myClickY / myZoomLevel + myOffY + startLine;
|
||||
command << "breakif _scan==#" << scanline;
|
||||
string message = instance().debugger().parser().run(command.str());
|
||||
instance().frameBuffer().showMessage(message);
|
||||
instance().frameBuffer().showTextMessage(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -282,6 +279,47 @@ void TiaZoomWidget::handleCommand(CommandSender* sender, int cmd, int data, int
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Common::Point TiaZoomWidget::getToolTipIndex(const Common::Point& pos) const
|
||||
{
|
||||
const Int32 width = instance().console().tia().width() * 2;
|
||||
const Int32 height = instance().console().tia().height();
|
||||
const int col = (pos.x - 1 - getAbsX()) / (myZoomLevel << 1) + (myOffX >> 1);
|
||||
const int row = (pos.y - 1 - getAbsY()) / myZoomLevel + myOffY;
|
||||
|
||||
if(col < 0 || col >= width || row < 0 || row >= height)
|
||||
return Common::Point(-1, -1);
|
||||
else
|
||||
return Common::Point(col, row);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string TiaZoomWidget::getToolTip(const Common::Point& pos) const
|
||||
{
|
||||
const Common::Point& idx = getToolTipIndex(pos);
|
||||
|
||||
if(idx.x < 0)
|
||||
return EmptyString;
|
||||
|
||||
const Int32 i = idx.x + idx.y * instance().console().tia().width();
|
||||
uInt8* tiaOutputBuffer = instance().console().tia().outputBuffer();
|
||||
ostringstream buf;
|
||||
|
||||
buf << _toolTipText
|
||||
<< "X: #" << idx.x
|
||||
<< "\nY: #" << idx.y
|
||||
<< "\nC: $" << Common::Base::toString(tiaOutputBuffer[i], Common::Base::Fmt::_16);
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool TiaZoomWidget::changedToolTip(const Common::Point& oldPos,
|
||||
const Common::Point& newPos) const
|
||||
{
|
||||
return getToolTipIndex(oldPos) != getToolTipIndex(newPos);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TiaZoomWidget::drawWidget(bool hilite)
|
||||
{
|
||||
|
|
|
@ -34,8 +34,12 @@ class TiaZoomWidget : public Widget, public CommandSender
|
|||
void loadConfig() override;
|
||||
void setPos(int x, int y);
|
||||
|
||||
string getToolTip(const Common::Point& pos) const override;
|
||||
bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override;
|
||||
|
||||
protected:
|
||||
void handleMouseEntered() override;
|
||||
bool hasToolTip() const override { return true; }
|
||||
Common::Point getToolTipIndex(const Common::Point& pos) const;
|
||||
|
||||
private:
|
||||
void zoom(int level);
|
||||
|
|
|
@ -25,8 +25,10 @@
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
ToggleBitWidget::ToggleBitWidget(GuiObject* boss, const GUI::Font& font,
|
||||
int x, int y, int cols, int rows, int colchars)
|
||||
: ToggleWidget(boss, font, x, y, cols, rows, 1)
|
||||
int x, int y, int cols, int rows, int colchars,
|
||||
const StringList& labels)
|
||||
: ToggleWidget(boss, font, x, y, cols, rows),
|
||||
_labelList(labels)
|
||||
{
|
||||
_rowHeight = font.getLineHeight();
|
||||
_colWidth = colchars * font.getMaxCharWidth() + 8;
|
||||
|
@ -47,6 +49,13 @@ ToggleBitWidget::ToggleBitWidget(GuiObject* boss, const GUI::Font& font,
|
|||
_h = _rowHeight * rows + 1;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
ToggleBitWidget::ToggleBitWidget(GuiObject* boss, const GUI::Font& font,
|
||||
int x, int y, int cols, int rows, int colchars)
|
||||
: ToggleBitWidget(boss, font, x, y, cols, rows, colchars, StringList())
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ToggleBitWidget::setList(const StringList& off, const StringList& on)
|
||||
{
|
||||
|
@ -69,6 +78,27 @@ void ToggleBitWidget::setState(const BoolArray& state, const BoolArray& changed)
|
|||
setDirty();
|
||||
}
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string ToggleBitWidget::getToolTip(const Common::Point& pos) const
|
||||
{
|
||||
const Common::Point& idx = getToolTipIndex(pos);
|
||||
|
||||
if(idx.y < 0)
|
||||
return EmptyString;
|
||||
|
||||
const string tip = ToggleWidget::getToolTip(pos);
|
||||
|
||||
if(idx.x < static_cast<int>(_labelList.size()))
|
||||
{
|
||||
const string label = _labelList[idx.x];
|
||||
|
||||
if(!label.empty())
|
||||
return tip + "\n" + label;
|
||||
}
|
||||
return tip;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ToggleBitWidget::drawWidget(bool hilite)
|
||||
{
|
||||
|
|
|
@ -26,17 +26,23 @@ class ToggleBitWidget : public ToggleWidget
|
|||
public:
|
||||
ToggleBitWidget(GuiObject* boss, const GUI::Font& font,
|
||||
int x, int y, int cols, int rows, int colchars = 1);
|
||||
ToggleBitWidget(GuiObject* boss, const GUI::Font& font,
|
||||
int x, int y, int cols, int rows, int colchars,
|
||||
const StringList& labels);
|
||||
~ToggleBitWidget() override = default;
|
||||
|
||||
void setList(const StringList& off, const StringList& on);
|
||||
void setState(const BoolArray& state, const BoolArray& changed);
|
||||
|
||||
string getToolTip(const Common::Point& pos) const override;
|
||||
|
||||
protected:
|
||||
void drawWidget(bool hilite) override;
|
||||
|
||||
protected:
|
||||
StringList _offList;
|
||||
StringList _onList;
|
||||
StringList _labelList;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
TogglePixelWidget::TogglePixelWidget(GuiObject* boss, const GUI::Font& font,
|
||||
int x, int y, int cols, int rows)
|
||||
: ToggleWidget(boss, font, x, y, cols, rows, 1)
|
||||
int x, int y, int cols, int rows,
|
||||
int shiftBits)
|
||||
: ToggleWidget(boss, font, x, y, cols, rows, shiftBits)
|
||||
{
|
||||
_rowHeight = _colWidth = font.getLineHeight();
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@ class TogglePixelWidget : public ToggleWidget
|
|||
{
|
||||
public:
|
||||
TogglePixelWidget(GuiObject* boss, const GUI::Font& font,
|
||||
int x, int y, int cols, int rows);
|
||||
int x, int y, int cols = 1, int rows = 1,
|
||||
int shiftBits = 0);
|
||||
~TogglePixelWidget() override = default;
|
||||
|
||||
void setColor(ColorId color) { _pixelColor = color; }
|
||||
|
@ -35,14 +36,13 @@ class TogglePixelWidget : public ToggleWidget
|
|||
|
||||
void setState(const BoolArray& state);
|
||||
|
||||
void setIntState(int value, bool swap);
|
||||
void setIntState(int value, bool swap = false);
|
||||
int getIntState();
|
||||
|
||||
void setCrossed(bool enable) { _crossBits = enable; }
|
||||
|
||||
private:
|
||||
ColorId _pixelColor{kNone}, _backgroundColor{kDlgColor};
|
||||
bool _swapBits{false};
|
||||
bool _crossBits{false};
|
||||
|
||||
private:
|
||||
|
|
|
@ -16,44 +16,26 @@
|
|||
//============================================================================
|
||||
|
||||
#include "OSystem.hxx"
|
||||
#include "Base.hxx"
|
||||
#include "StellaKeys.hxx"
|
||||
#include "Widget.hxx"
|
||||
#include "Dialog.hxx"
|
||||
#include "ToolTip.hxx"
|
||||
#include "ToggleWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
ToggleWidget::ToggleWidget(GuiObject* boss, const GUI::Font& font,
|
||||
int x, int y, int cols, int rows,
|
||||
int clicksToChange)
|
||||
int x, int y, int cols, int rows, int shiftBits)
|
||||
: Widget(boss, font, x, y, 16, 16),
|
||||
CommandSender(boss),
|
||||
_rows(rows),
|
||||
_cols(cols),
|
||||
_currentRow(0),
|
||||
_currentCol(0),
|
||||
_rowHeight(0),
|
||||
_colWidth(0),
|
||||
_selectedItem(0),
|
||||
_clicksToChange(clicksToChange),
|
||||
_editable(true)
|
||||
_shiftBits(shiftBits)
|
||||
{
|
||||
_flags = Widget::FLAG_ENABLED | Widget::FLAG_CLEARBG | Widget::FLAG_RETAIN_FOCUS |
|
||||
Widget::FLAG_WANTS_RAWDATA;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ToggleWidget::handleMouseEntered()
|
||||
{
|
||||
setFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ToggleWidget::handleMouseLeft()
|
||||
{
|
||||
clearFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ToggleWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
|
||||
{
|
||||
|
@ -71,6 +53,7 @@ void ToggleWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
|
|||
_selectedItem = newSelectedItem;
|
||||
_currentRow = _selectedItem / _cols;
|
||||
_currentCol = _selectedItem - (_currentRow * _cols);
|
||||
dialog().tooltip().hide();
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +66,7 @@ void ToggleWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount)
|
|||
|
||||
// If this was a double click and the mouse is still over the selected item,
|
||||
// send the double click command
|
||||
if (clickCount == _clicksToChange && (_selectedItem == findItem(x, y)))
|
||||
if (clickCount == 1 && (_selectedItem == findItem(x, y)))
|
||||
{
|
||||
_stateList[_selectedItem] = !_stateList[_selectedItem];
|
||||
_changedList[_selectedItem] = !_changedList[_selectedItem];
|
||||
|
@ -202,6 +185,7 @@ bool ToggleWidget::handleKeyDown(StellaKey key, StellaMod mod)
|
|||
_stateList[_selectedItem] = !_stateList[_selectedItem];
|
||||
_changedList[_selectedItem] = !_changedList[_selectedItem];
|
||||
sendCommand(ToggleWidget::kItemDataChangedCmd, _selectedItem, _id);
|
||||
dialog().tooltip().hide();
|
||||
}
|
||||
|
||||
setDirty();
|
||||
|
@ -223,3 +207,56 @@ void ToggleWidget::handleCommand(CommandSender* sender, int cmd,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Common::Point ToggleWidget::getToolTipIndex(const Common::Point& pos) const
|
||||
{
|
||||
const int col = (pos.x - getAbsX()) / _colWidth;
|
||||
const int row = (pos.y - getAbsY()) / _rowHeight;
|
||||
|
||||
if(row >= 0 && row < _rows && col >= 0 && col < _cols)
|
||||
return Common::Point(col, row);
|
||||
else
|
||||
return Common::Point(-1, -1);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string ToggleWidget::getToolTip(const Common::Point& pos) const
|
||||
{
|
||||
const int idx = getToolTipIndex(pos).y * _cols;
|
||||
|
||||
if(idx < 0)
|
||||
return EmptyString;
|
||||
|
||||
Int32 val = 0;
|
||||
ostringstream buf;
|
||||
|
||||
if(_swapBits)
|
||||
for(int col = _cols - 1; col >= 0; --col)
|
||||
{
|
||||
val <<= 1;
|
||||
val += _stateList[idx + col];
|
||||
}
|
||||
else
|
||||
for(int col = 0; col < _cols; ++col)
|
||||
{
|
||||
val <<= 1;
|
||||
val += _stateList[idx + col];
|
||||
}
|
||||
val <<= _shiftBits;
|
||||
|
||||
buf << _toolTipText
|
||||
<< "$" << Common::Base::toString(val, Common::Base::Fmt::_16)
|
||||
<< " = #" << val;
|
||||
if(val < 0x100)
|
||||
buf << " = %" << Common::Base::toString(val, Common::Base::Fmt::_2);
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool ToggleWidget::changedToolTip(const Common::Point& oldPos,
|
||||
const Common::Point& newPos) const
|
||||
{
|
||||
return getToolTipIndex(oldPos) != getToolTipIndex(newPos);
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@ class ToggleWidget : public Widget, public CommandSender
|
|||
|
||||
public:
|
||||
ToggleWidget(GuiObject* boss, const GUI::Font& font,
|
||||
int x, int y, int cols, int rows,
|
||||
int clicksToChange = 2);
|
||||
int x, int y, int cols = 1, int rows = 1,
|
||||
int shiftBits = 0);
|
||||
~ToggleWidget() override = default;
|
||||
|
||||
const BoolArray& getState() { return _stateList; }
|
||||
|
@ -46,18 +46,24 @@ class ToggleWidget : public Widget, public CommandSender
|
|||
void setEditable(bool editable) { _editable = editable; }
|
||||
bool isEditable() const { return _editable; }
|
||||
|
||||
protected:
|
||||
string getToolTip(const Common::Point& pos) const override;
|
||||
bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override;
|
||||
|
||||
protected:
|
||||
int _rows;
|
||||
int _cols;
|
||||
int _currentRow;
|
||||
int _currentCol;
|
||||
int _rowHeight; // explicitly set in child classes
|
||||
int _colWidth; // explicitly set in child classes
|
||||
int _selectedItem;
|
||||
int _clicksToChange; // number of clicks to register a change
|
||||
bool _editable;
|
||||
bool hasToolTip() const override { return true; }
|
||||
Common::Point getToolTipIndex(const Common::Point& pos) const;
|
||||
|
||||
protected:
|
||||
int _rows{0};
|
||||
int _cols{0};
|
||||
int _currentRow{0};
|
||||
int _currentCol{0};
|
||||
int _rowHeight{0}; // explicitly set in child classes
|
||||
int _colWidth{0}; // explicitly set in child classes
|
||||
int _selectedItem{0};
|
||||
bool _editable{true};
|
||||
bool _swapBits{false};
|
||||
int _shiftBits{0}; // shift bits for tooltip display
|
||||
|
||||
BoolArray _stateList;
|
||||
BoolArray _changedList;
|
||||
|
@ -68,8 +74,6 @@ class ToggleWidget : public Widget, public CommandSender
|
|||
|
||||
void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleMouseUp(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleMouseEntered() override;
|
||||
void handleMouseLeft() override;
|
||||
bool handleKeyDown(StellaKey key, StellaMod mod) override;
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ MODULE_OBJS := \
|
|||
src/debugger/gui/CartDebugWidget.o \
|
||||
src/debugger/gui/CpuWidget.o \
|
||||
src/debugger/gui/DataGridOpsWidget.o \
|
||||
src/debugger/gui/DataGridRamWidget.o \
|
||||
src/debugger/gui/DataGridWidget.o \
|
||||
src/debugger/gui/DebuggerDialog.o \
|
||||
src/debugger/gui/DelayQueueWidget.o \
|
||||
|
|
|
@ -476,7 +476,7 @@ void Console::setFormat(uInt32 format, bool force)
|
|||
initializeAudio(); // ensure that audio synthesis is set up to match emulation rate
|
||||
myOSystem.resetFps(); // Reset FPS measurement
|
||||
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
|
||||
// Let the other devices know about the console change
|
||||
mySystem->consoleChanged(myConsoleTiming);
|
||||
|
@ -493,10 +493,10 @@ void Console::toggleColorLoss(bool toggle)
|
|||
|
||||
string message = string("PAL color-loss ") +
|
||||
(colorloss ? "enabled" : "disabled");
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
}
|
||||
else
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
myOSystem.frameBuffer().showTextMessage(
|
||||
"PAL color-loss not available in non PAL modes");
|
||||
}
|
||||
|
||||
|
@ -521,7 +521,7 @@ void Console::toggleInter(bool toggle)
|
|||
ostringstream ss;
|
||||
|
||||
ss << "Interpolation " << (enabled ? "enabled" : "disabled");
|
||||
myOSystem.frameBuffer().showMessage(ss.str());
|
||||
myOSystem.frameBuffer().showTextMessage(ss.str());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -539,7 +539,7 @@ void Console::toggleTurbo()
|
|||
|
||||
ostringstream ss;
|
||||
ss << "Turbo mode " << (!enabled ? "enabled" : "disabled");
|
||||
myOSystem.frameBuffer().showMessage(ss.str());
|
||||
myOSystem.frameBuffer().showTextMessage(ss.str());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -564,7 +564,7 @@ void Console::changeSpeed(int direction)
|
|||
ostringstream val;
|
||||
|
||||
val << formatSpeed(speed) << "%";
|
||||
myOSystem.frameBuffer().showMessage("Emulation speed", val.str(), speed, MIN_SPEED, MAX_SPEED);
|
||||
myOSystem.frameBuffer().showGaugeMessage("Emulation speed", val.str(), speed, MIN_SPEED, MAX_SPEED);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -574,13 +574,13 @@ void Console::togglePhosphor()
|
|||
{
|
||||
myProperties.set(PropType::Display_Phosphor, "NO");
|
||||
myOSystem.frameBuffer().tiaSurface().enablePhosphor(false);
|
||||
myOSystem.frameBuffer().showMessage("Phosphor effect disabled");
|
||||
myOSystem.frameBuffer().showTextMessage("Phosphor effect disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
myProperties.set(PropType::Display_Phosphor, "YES");
|
||||
myOSystem.frameBuffer().tiaSurface().enablePhosphor(true);
|
||||
myOSystem.frameBuffer().showMessage("Phosphor effect enabled");
|
||||
myOSystem.frameBuffer().showTextMessage("Phosphor effect enabled");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -605,7 +605,7 @@ void Console::changePhosphor(int direction)
|
|||
val.str("");
|
||||
val << "Off";
|
||||
}
|
||||
myOSystem.frameBuffer().showMessage("Phosphor blend", val.str(), blend);
|
||||
myOSystem.frameBuffer().showGaugeMessage("Phosphor blend", val.str(), blend);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -699,7 +699,7 @@ void Console::changeVerticalCenter(int direction)
|
|||
if (vcenter != myTIA->vcenter()) myTIA->setVcenter(vcenter);
|
||||
|
||||
val << (vcenter ? vcenter > 0 ? "+" : "" : " ") << vcenter << "px";
|
||||
myOSystem.frameBuffer().showMessage("V-Center", val.str(), vcenter,
|
||||
myOSystem.frameBuffer().showGaugeMessage("V-Center", val.str(), vcenter,
|
||||
myTIA->minVcenter(), myTIA->maxVcenter());
|
||||
}
|
||||
|
||||
|
@ -729,7 +729,7 @@ void Console::changeVSizeAdjust(int direction)
|
|||
|
||||
val << (newAdjustVSize ? newAdjustVSize > 0 ? "+" : "" : " ")
|
||||
<< newAdjustVSize << "%";
|
||||
myOSystem.frameBuffer().showMessage("V-Size", val.str(), newAdjustVSize, -5, 5);
|
||||
myOSystem.frameBuffer().showGaugeMessage("V-Size", val.str(), newAdjustVSize, -5, 5);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -746,7 +746,7 @@ void Console::toggleCorrectAspectRatio(bool toggle)
|
|||
const string& message = string("Correct aspect ratio ") +
|
||||
(enabled ? "enabled" : "disabled");
|
||||
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -920,7 +920,7 @@ unique_ptr<Controller> Console::getControllerPort(const Controller::Type type,
|
|||
Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) {
|
||||
bool devSettings = os.settings().getBool("dev.settings");
|
||||
if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess"))
|
||||
os.frameBuffer().showMessage(msg);
|
||||
os.frameBuffer().showTextMessage(msg);
|
||||
};
|
||||
controller = make_unique<AtariVox>(port, myEvent, *mySystem,
|
||||
myOSystem.settings().getString("avoxport"), nvramfile, callback);
|
||||
|
@ -933,7 +933,7 @@ unique_ptr<Controller> Console::getControllerPort(const Controller::Type type,
|
|||
Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) {
|
||||
bool devSettings = os.settings().getBool("dev.settings");
|
||||
if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess"))
|
||||
os.frameBuffer().showMessage(msg);
|
||||
os.frameBuffer().showTextMessage(msg);
|
||||
};
|
||||
controller = make_unique<SaveKey>(port, myEvent, *mySystem, nvramfile, callback);
|
||||
break;
|
||||
|
@ -987,7 +987,7 @@ void Console::changeAutoFireRate(int direction)
|
|||
else
|
||||
val << "Off";
|
||||
|
||||
myOSystem.frameBuffer().showMessage("Autofire rate", val.str(), rate, 0, isNTSC ? 30 : 25);
|
||||
myOSystem.frameBuffer().showGaugeMessage("Autofire rate", val.str(), rate, 0, isNTSC ? 30 : 25);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -1012,7 +1012,7 @@ void Console::toggleTIABit(TIABit bit, const string& bitname, bool show, bool to
|
|||
bool result = myTIA->toggleBit(bit, toggle ? 2 : 3);
|
||||
const string message = bitname + (result ? " enabled" : " disabled");
|
||||
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -1021,7 +1021,7 @@ void Console::toggleBits(bool toggle) const
|
|||
bool enabled = myTIA->toggleBits(toggle);
|
||||
const string message = string("TIA bits ") + (enabled ? "enabled" : "disabled");
|
||||
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -1030,7 +1030,7 @@ void Console::toggleTIACollision(TIABit bit, const string& bitname, bool show, b
|
|||
bool result = myTIA->toggleCollision(bit, toggle ? 2 : 3);
|
||||
const string message = bitname + (result ? " collision enabled" : " collision disabled");
|
||||
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -1039,7 +1039,7 @@ void Console::toggleCollisions(bool toggle) const
|
|||
bool enabled = myTIA->toggleCollisions(toggle);
|
||||
const string message = string("TIA collisions ") + (enabled ? "enabled" : "disabled");
|
||||
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -1048,7 +1048,7 @@ void Console::toggleFixedColors(bool toggle) const
|
|||
bool enabled = toggle ? myTIA->toggleFixedColors() : myTIA->usingFixedColors();
|
||||
const string message = string("Fixed debug colors ") + (enabled ? "enabled" : "disabled");
|
||||
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -1057,7 +1057,7 @@ void Console::toggleJitter(bool toggle) const
|
|||
bool enabled = myTIA->toggleJitter(toggle ? 2 : 3);
|
||||
const string message = string("TV scanline jitter ") + (enabled ? "enabled" : "disabled");
|
||||
|
||||
myOSystem.frameBuffer().showMessage(message);
|
||||
myOSystem.frameBuffer().showTextMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -191,12 +191,12 @@ void EventHandler::toggleSAPortOrder()
|
|||
if(saport == "lr")
|
||||
{
|
||||
mapStelladaptors("rl");
|
||||
myOSystem.frameBuffer().showMessage("Stelladaptor ports right/left");
|
||||
myOSystem.frameBuffer().showTextMessage("Stelladaptor ports right/left");
|
||||
}
|
||||
else
|
||||
{
|
||||
mapStelladaptors("lr");
|
||||
myOSystem.frameBuffer().showMessage("Stelladaptor ports left/right");
|
||||
myOSystem.frameBuffer().showTextMessage("Stelladaptor ports left/right");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ void EventHandler::set7800Mode()
|
|||
void EventHandler::handleMouseControl()
|
||||
{
|
||||
if(myMouseControl)
|
||||
myOSystem.frameBuffer().showMessage(myMouseControl->next());
|
||||
myOSystem.frameBuffer().showTextMessage(myMouseControl->next());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -323,7 +323,8 @@ void EventHandler::handleSystemEvent(SystemEvent e, int, int)
|
|||
{
|
||||
case SystemEvent::WINDOW_EXPOSED:
|
||||
case SystemEvent::WINDOW_RESIZED:
|
||||
myOSystem.frameBuffer().update(true); // force full update
|
||||
// Force full render update
|
||||
myOSystem.frameBuffer().update(FrameBuffer::UpdateMode::RERENDER);
|
||||
break;
|
||||
#ifdef BSPF_UNIX
|
||||
case SystemEvent::WINDOW_FOCUS_GAINED:
|
||||
|
@ -550,7 +551,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
myOSystem.frameBuffer().showMessage(msg + " settings");
|
||||
myOSystem.frameBuffer().showTextMessage(msg + " settings");
|
||||
myAdjustActive = false;
|
||||
}
|
||||
break;
|
||||
|
@ -1210,7 +1211,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
|||
|
||||
case Event::SaveAllStates:
|
||||
if (pressed && !repeated)
|
||||
myOSystem.frameBuffer().showMessage(myOSystem.state().rewindManager().saveAllStates());
|
||||
myOSystem.frameBuffer().showTextMessage(myOSystem.state().rewindManager().saveAllStates());
|
||||
return;
|
||||
|
||||
case Event::PreviousState:
|
||||
|
@ -1243,7 +1244,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
|||
|
||||
case Event::LoadAllStates:
|
||||
if (pressed && !repeated)
|
||||
myOSystem.frameBuffer().showMessage(myOSystem.state().rewindManager().loadAllStates());
|
||||
myOSystem.frameBuffer().showTextMessage(myOSystem.state().rewindManager().loadAllStates());
|
||||
return;
|
||||
|
||||
case Event::RewindPause:
|
||||
|
@ -1476,7 +1477,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
|||
{
|
||||
myEvent.set(Event::ConsoleBlackWhite, 0);
|
||||
myEvent.set(Event::ConsoleColor, 1);
|
||||
myOSystem.frameBuffer().showMessage(myIs7800 ? "Pause released" : "Color Mode");
|
||||
myOSystem.frameBuffer().showTextMessage(myIs7800 ? "Pause released" : "Color Mode");
|
||||
myOSystem.console().switches().update();
|
||||
}
|
||||
return;
|
||||
|
@ -1485,7 +1486,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
|||
{
|
||||
myEvent.set(Event::ConsoleBlackWhite, 1);
|
||||
myEvent.set(Event::ConsoleColor, 0);
|
||||
myOSystem.frameBuffer().showMessage(myIs7800 ? "Pause pushed" : "B/W Mode");
|
||||
myOSystem.frameBuffer().showTextMessage(myIs7800 ? "Pause pushed" : "B/W Mode");
|
||||
myOSystem.console().switches().update();
|
||||
}
|
||||
return;
|
||||
|
@ -1496,13 +1497,13 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
|||
{
|
||||
myEvent.set(Event::ConsoleBlackWhite, 1);
|
||||
myEvent.set(Event::ConsoleColor, 0);
|
||||
myOSystem.frameBuffer().showMessage(myIs7800 ? "Pause pushed" : "B/W Mode");
|
||||
myOSystem.frameBuffer().showTextMessage(myIs7800 ? "Pause pushed" : "B/W Mode");
|
||||
}
|
||||
else
|
||||
{
|
||||
myEvent.set(Event::ConsoleBlackWhite, 0);
|
||||
myEvent.set(Event::ConsoleColor, 1);
|
||||
myOSystem.frameBuffer().showMessage(myIs7800 ? "Pause released" : "Color Mode");
|
||||
myOSystem.frameBuffer().showTextMessage(myIs7800 ? "Pause released" : "Color Mode");
|
||||
}
|
||||
myOSystem.console().switches().update();
|
||||
}
|
||||
|
@ -1514,7 +1515,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
|||
myEvent.set(Event::ConsoleBlackWhite, 0);
|
||||
myEvent.set(Event::ConsoleColor, 0);
|
||||
if (myIs7800)
|
||||
myOSystem.frameBuffer().showMessage("Pause pressed");
|
||||
myOSystem.frameBuffer().showTextMessage("Pause pressed");
|
||||
myOSystem.console().switches().update();
|
||||
}
|
||||
return;
|
||||
|
@ -1524,7 +1525,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
|||
{
|
||||
myEvent.set(Event::ConsoleLeftDiffA, 1);
|
||||
myEvent.set(Event::ConsoleLeftDiffB, 0);
|
||||
myOSystem.frameBuffer().showMessage(GUI::LEFT_DIFFICULTY + " A");
|
||||
myOSystem.frameBuffer().showTextMessage(GUI::LEFT_DIFFICULTY + " A");
|
||||
myOSystem.console().switches().update();
|
||||
}
|
||||
return;
|
||||
|
@ -1533,7 +1534,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
|||
{
|
||||
myEvent.set(Event::ConsoleLeftDiffA, 0);
|
||||
myEvent.set(Event::ConsoleLeftDiffB, 1);
|
||||
myOSystem.frameBuffer().showMessage(GUI::LEFT_DIFFICULTY + " B");
|
||||
myOSystem.frameBuffer().showTextMessage(GUI::LEFT_DIFFICULTY + " B");
|
||||
myOSystem.console().switches().update();
|
||||
}
|
||||
return;
|
||||
|
@ -1544,13 +1545,13 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
|||
{
|
||||
myEvent.set(Event::ConsoleLeftDiffA, 0);
|
||||
myEvent.set(Event::ConsoleLeftDiffB, 1);
|
||||
myOSystem.frameBuffer().showMessage(GUI::LEFT_DIFFICULTY + " B");
|
||||
myOSystem.frameBuffer().showTextMessage(GUI::LEFT_DIFFICULTY + " B");
|
||||
}
|
||||
else
|
||||
{
|
||||
myEvent.set(Event::ConsoleLeftDiffA, 1);
|
||||
myEvent.set(Event::ConsoleLeftDiffB, 0);
|
||||
myOSystem.frameBuffer().showMessage(GUI::LEFT_DIFFICULTY + " A");
|
||||
myOSystem.frameBuffer().showTextMessage(GUI::LEFT_DIFFICULTY + " A");
|
||||
}
|
||||
myOSystem.console().switches().update();
|
||||
}
|
||||
|
@ -1561,7 +1562,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
|||
{
|
||||
myEvent.set(Event::ConsoleRightDiffA, 1);
|
||||
myEvent.set(Event::ConsoleRightDiffB, 0);
|
||||
myOSystem.frameBuffer().showMessage(GUI::RIGHT_DIFFICULTY + " A");
|
||||
myOSystem.frameBuffer().showTextMessage(GUI::RIGHT_DIFFICULTY + " A");
|
||||
myOSystem.console().switches().update();
|
||||
}
|
||||
return;
|
||||
|
@ -1570,7 +1571,7 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
|||
{
|
||||
myEvent.set(Event::ConsoleRightDiffA, 0);
|
||||
myEvent.set(Event::ConsoleRightDiffB, 1);
|
||||
myOSystem.frameBuffer().showMessage(GUI::RIGHT_DIFFICULTY + " B");
|
||||
myOSystem.frameBuffer().showTextMessage(GUI::RIGHT_DIFFICULTY + " B");
|
||||
myOSystem.console().switches().update();
|
||||
}
|
||||
return;
|
||||
|
@ -1581,13 +1582,13 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
|
|||
{
|
||||
myEvent.set(Event::ConsoleRightDiffA, 0);
|
||||
myEvent.set(Event::ConsoleRightDiffB, 1);
|
||||
myOSystem.frameBuffer().showMessage(GUI::RIGHT_DIFFICULTY + " B");
|
||||
myOSystem.frameBuffer().showTextMessage(GUI::RIGHT_DIFFICULTY + " B");
|
||||
}
|
||||
else
|
||||
{
|
||||
myEvent.set(Event::ConsoleRightDiffA, 1);
|
||||
myEvent.set(Event::ConsoleRightDiffB, 0);
|
||||
myOSystem.frameBuffer().showMessage(GUI::RIGHT_DIFFICULTY + " A");
|
||||
myOSystem.frameBuffer().showTextMessage(GUI::RIGHT_DIFFICULTY + " A");
|
||||
}
|
||||
myOSystem.console().switches().update();
|
||||
}
|
||||
|
@ -2287,6 +2288,7 @@ void EventHandler::enterMenuMode(EventHandlerState state)
|
|||
void EventHandler::leaveMenuMode()
|
||||
{
|
||||
#ifdef GUI_SUPPORT
|
||||
myOverlay->removeDialog(); // remove the base dialog from dialog stack
|
||||
setState(EventHandlerState::EMULATION);
|
||||
myOSystem.sound().mute(false);
|
||||
#endif
|
||||
|
@ -2312,14 +2314,15 @@ bool EventHandler::enterDebugMode()
|
|||
myOSystem.debugger().setQuitState();
|
||||
setState(EventHandlerState::EMULATION);
|
||||
if(fbstatus == FBInitStatus::FailTooLarge)
|
||||
myOSystem.frameBuffer().showMessage("Debugger window too large for screen",
|
||||
myOSystem.frameBuffer().showTextMessage("Debugger window too large for screen",
|
||||
MessagePosition::BottomCenter, true);
|
||||
return false;
|
||||
}
|
||||
myOverlay->reStack();
|
||||
myOSystem.sound().mute(true);
|
||||
|
||||
#else
|
||||
myOSystem.frameBuffer().showMessage("Debugger support not included",
|
||||
myOSystem.frameBuffer().showTextMessage("Debugger support not included",
|
||||
MessagePosition::BottomCenter, true);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -296,27 +296,45 @@ void FBSurface::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurface::wrapString(const string& inStr, int pos, string& leftStr, string& rightStr) const
|
||||
void FBSurface::splitString(const GUI::Font& font, const string& s, int w,
|
||||
string& left, string& right) const
|
||||
{
|
||||
uInt32 pos;
|
||||
int w2 = 0;
|
||||
bool split = false;
|
||||
|
||||
// SLOW algorithm to find the acceptable length. But it is good enough for now.
|
||||
for(pos = 0; pos < s.size(); ++pos)
|
||||
{
|
||||
int charWidth = font.getCharWidth(s[pos]);
|
||||
if(w2 + charWidth > w || s[pos] == '\n')
|
||||
{
|
||||
split = true;
|
||||
break;
|
||||
}
|
||||
w2 += charWidth;
|
||||
}
|
||||
|
||||
if(split)
|
||||
for(int i = pos; i > 0; --i)
|
||||
{
|
||||
if(isWhiteSpace(inStr[i]))
|
||||
if(isWhiteSpace(s[i]))
|
||||
{
|
||||
leftStr = inStr.substr(0, i);
|
||||
if(inStr[i] == ' ') // skip leading space after line break
|
||||
left = s.substr(0, i);
|
||||
if(s[i] == ' ' || s[pos] == '\n') // skip leading space after line break
|
||||
i++;
|
||||
rightStr = inStr.substr(i);
|
||||
right = s.substr(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
leftStr = inStr.substr(0, pos);
|
||||
rightStr = inStr.substr(pos);
|
||||
left = s.substr(0, pos);
|
||||
right = s.substr(pos);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FBSurface::isWhiteSpace(const char s) const
|
||||
{
|
||||
const string WHITESPACES = " ,.;:+-";
|
||||
const string WHITESPACES = " ,.;:+-*/'([\n";
|
||||
|
||||
for(size_t i = 0; i < WHITESPACES.length(); ++i)
|
||||
if(s == WHITESPACES[i])
|
||||
|
@ -331,37 +349,30 @@ int FBSurface::drawString(const GUI::Font& font, const string& s,
|
|||
ColorId color, TextAlign align,
|
||||
int deltax, bool useEllipsis, ColorId shadowColor)
|
||||
{
|
||||
int lines = 1;
|
||||
int lines = 0;
|
||||
|
||||
#ifdef GUI_SUPPORT
|
||||
string inStr = s;
|
||||
|
||||
// draw multiline string
|
||||
while (font.getStringWidth(inStr) > w && h >= font.getFontHeight() * 2)
|
||||
//while (font.getStringWidth(inStr) > w && h >= font.getFontHeight() * 2)
|
||||
while(inStr.length() && h >= font.getFontHeight() * 2)
|
||||
{
|
||||
// String is too wide.
|
||||
uInt32 i;
|
||||
string leftStr, rightStr;
|
||||
int w2 = 0;
|
||||
|
||||
// SLOW algorithm to find the acceptable length. But it is good enough for now.
|
||||
for(i = 0; i < inStr.size(); ++i)
|
||||
{
|
||||
int charWidth = font.getCharWidth(inStr[i]);
|
||||
if(w2 + charWidth > w)
|
||||
break;
|
||||
|
||||
w2 += charWidth;
|
||||
//str += inStr[i];
|
||||
}
|
||||
wrapString(inStr, i, leftStr, rightStr);
|
||||
splitString(font, inStr, w, leftStr, rightStr);
|
||||
drawString(font, leftStr, x, y, w, color, align, deltax, false, shadowColor);
|
||||
h -= font.getFontHeight();
|
||||
y += font.getFontHeight();
|
||||
inStr = rightStr;
|
||||
lines++;
|
||||
}
|
||||
if(inStr.length())
|
||||
{
|
||||
drawString(font, inStr, x, y, w, color, align, deltax, useEllipsis, shadowColor);
|
||||
lines++;
|
||||
}
|
||||
#endif
|
||||
return lines;
|
||||
}
|
||||
|
|
|
@ -247,6 +247,18 @@ class FBSurface
|
|||
ColorId color, TextAlign align = TextAlign::Left,
|
||||
int deltax = 0, bool useEllipsis = true, ColorId shadowColor = kNone);
|
||||
|
||||
/**
|
||||
Splits a given string to a given width considering whitespaces.
|
||||
|
||||
@param font The font to draw the string with
|
||||
@param s The string to split
|
||||
@param w The width of the string area
|
||||
@param left The left part of the split string
|
||||
@param right The right part of the split string
|
||||
*/
|
||||
void splitString(const GUI::Font& font, const string& s, int w,
|
||||
string& left, string& right) const;
|
||||
|
||||
/**
|
||||
The rendering attributes that can be modified for this texture.
|
||||
These probably can only be implemented in child FBSurfaces where
|
||||
|
@ -292,11 +304,14 @@ class FBSurface
|
|||
These methods set the origin point and width/height for the
|
||||
specified service. They are defined as separate x/y and w/h
|
||||
methods since these items are sometimes set separately.
|
||||
Other times they are set together, so we can use a Rect instead.
|
||||
*/
|
||||
virtual void setSrcPos(uInt32 x, uInt32 y) = 0;
|
||||
virtual void setSrcSize(uInt32 w, uInt32 h) = 0;
|
||||
virtual void setSrcRect(const Common::Rect& r) = 0;
|
||||
virtual void setDstPos(uInt32 x, uInt32 y) = 0;
|
||||
virtual void setDstSize(uInt32 w, uInt32 h) = 0;
|
||||
virtual void setDstRect(const Common::Rect& r) = 0;
|
||||
|
||||
/**
|
||||
This method should be called to enable/disable showing the surface
|
||||
|
@ -323,7 +338,18 @@ class FBSurface
|
|||
This method should be called to reset the surface to empty
|
||||
pixels / colour black.
|
||||
*/
|
||||
virtual void invalidate() = 0;
|
||||
virtual void invalidate() {}
|
||||
|
||||
/**
|
||||
This method should be called to reset a surface area to empty
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param w The width of the area
|
||||
@param h The height of the area
|
||||
*/
|
||||
virtual void invalidateRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) = 0;
|
||||
|
||||
|
||||
/**
|
||||
This method should be called to free any resources being used by
|
||||
|
@ -369,9 +395,6 @@ class FBSurface
|
|||
*/
|
||||
bool checkBounds(const uInt32 x, const uInt32 y) const;
|
||||
|
||||
void wrapString(const string& inStr, int pos,
|
||||
string& leftStr, string& rightStr) const;
|
||||
|
||||
/**
|
||||
Check if the given character is a whitespace.
|
||||
@param s Character to check
|
||||
|
|
|
@ -270,7 +270,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type,
|
|||
|
||||
#ifdef GUI_SUPPORT
|
||||
// Erase any messages from a previous run
|
||||
myMsg.counter = 0;
|
||||
myMsg.enabled = false;
|
||||
|
||||
// Create surfaces for TIA statistics and general messages
|
||||
const GUI::Font& f = hidpiEnabled() ? infoFont() : font();
|
||||
|
@ -311,7 +311,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type,
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::update(bool force)
|
||||
void FrameBuffer::update(UpdateMode mode)
|
||||
{
|
||||
// Onscreen messages are a special case and require different handling than
|
||||
// other objects; they aren't UI dialogs in the normal sense nor are they
|
||||
|
@ -322,13 +322,14 @@ void FrameBuffer::update(bool force)
|
|||
// - at the bottom of ::update(), to actually draw them (this must come
|
||||
// last, since they are always drawn on top of everything else).
|
||||
|
||||
// Full rendering is required when messages are enabled
|
||||
force = force || myMsg.counter >= 0;
|
||||
bool forceRedraw = mode & UpdateMode::REDRAW;
|
||||
bool redraw = forceRedraw;
|
||||
|
||||
// Detect when a message has been turned off; one last redraw is required
|
||||
// in this case, to draw over the area that the message occupied
|
||||
if(myMsg.counter == 0)
|
||||
myMsg.counter = -1;
|
||||
// Forced render without draw required if messages or dialogs were closed
|
||||
// Note: For dialogs only relevant when two or more dialogs were stacked
|
||||
bool rerender = (mode & (UpdateMode::REDRAW | UpdateMode::RERENDER))
|
||||
|| myPendingRender;
|
||||
myPendingRender = false;
|
||||
|
||||
switch(myOSystem.eventHandler().state())
|
||||
{
|
||||
|
@ -343,59 +344,69 @@ void FrameBuffer::update(bool force)
|
|||
if(myPausedCount-- <= 0)
|
||||
{
|
||||
myPausedCount = uInt32(7 * myOSystem.frameRate());
|
||||
showMessage("Paused", MessagePosition::MiddleCenter);
|
||||
}
|
||||
if(force)
|
||||
showTextMessage("Paused", MessagePosition::MiddleCenter);
|
||||
myTIASurface->render();
|
||||
}
|
||||
if(rerender)
|
||||
myTIASurface->render();
|
||||
|
||||
break; // EventHandlerState::PAUSE
|
||||
}
|
||||
|
||||
#ifdef GUI_SUPPORT
|
||||
case EventHandlerState::OPTIONSMENU:
|
||||
{
|
||||
force = force || myOSystem.menu().needsRedraw();
|
||||
if(force)
|
||||
myOSystem.menu().tick();
|
||||
redraw |= myOSystem.menu().needsRedraw();
|
||||
if(redraw)
|
||||
{
|
||||
clear();
|
||||
myTIASurface->render();
|
||||
myOSystem.menu().draw(force);
|
||||
myOSystem.menu().draw(forceRedraw);
|
||||
}
|
||||
else if(rerender)
|
||||
{
|
||||
clear();
|
||||
myTIASurface->render();
|
||||
myOSystem.menu().render();
|
||||
}
|
||||
break; // EventHandlerState::OPTIONSMENU
|
||||
}
|
||||
|
||||
case EventHandlerState::CMDMENU:
|
||||
{
|
||||
force = force || myOSystem.commandMenu().needsRedraw();
|
||||
if(force)
|
||||
myOSystem.commandMenu().tick();
|
||||
redraw |= myOSystem.commandMenu().needsRedraw();
|
||||
if(redraw)
|
||||
{
|
||||
clear();
|
||||
myTIASurface->render();
|
||||
myOSystem.commandMenu().draw(force);
|
||||
myOSystem.commandMenu().draw(forceRedraw);
|
||||
}
|
||||
break; // EventHandlerState::CMDMENU
|
||||
}
|
||||
|
||||
case EventHandlerState::MESSAGEMENU:
|
||||
{
|
||||
force = force || myOSystem.messageMenu().needsRedraw();
|
||||
if (force)
|
||||
myOSystem.messageMenu().tick();
|
||||
redraw |= myOSystem.messageMenu().needsRedraw();
|
||||
if(redraw)
|
||||
{
|
||||
clear();
|
||||
myTIASurface->render();
|
||||
myOSystem.messageMenu().draw(force);
|
||||
myOSystem.messageMenu().draw(forceRedraw);
|
||||
}
|
||||
break; // EventHandlerState::MESSAGEMENU
|
||||
}
|
||||
|
||||
case EventHandlerState::TIMEMACHINE:
|
||||
{
|
||||
force = force || myOSystem.timeMachine().needsRedraw();
|
||||
if(force)
|
||||
myOSystem.timeMachine().tick();
|
||||
redraw |= myOSystem.timeMachine().needsRedraw();
|
||||
if(redraw)
|
||||
{
|
||||
clear();
|
||||
myTIASurface->render();
|
||||
myOSystem.timeMachine().draw(force);
|
||||
myOSystem.timeMachine().draw(forceRedraw);
|
||||
}
|
||||
break; // EventHandlerState::TIMEMACHINE
|
||||
}
|
||||
|
@ -420,13 +431,13 @@ void FrameBuffer::update(bool force)
|
|||
r.rewindStates(1);
|
||||
}
|
||||
|
||||
force = force || success;
|
||||
if (force)
|
||||
redraw |= success;
|
||||
if(redraw)
|
||||
myTIASurface->render();
|
||||
|
||||
// Stop playback mode at the end of the state buffer
|
||||
// and switch to Time Machine or Pause mode
|
||||
if (!success)
|
||||
if(!success)
|
||||
{
|
||||
frames = 0;
|
||||
myOSystem.eventHandler().enterMenuMode(EventHandlerState::TIMEMACHINE);
|
||||
|
@ -436,12 +447,12 @@ void FrameBuffer::update(bool force)
|
|||
|
||||
case EventHandlerState::LAUNCHER:
|
||||
{
|
||||
force = force || myOSystem.launcher().needsRedraw();
|
||||
if(force)
|
||||
{
|
||||
clear();
|
||||
myOSystem.launcher().draw(force);
|
||||
}
|
||||
myOSystem.launcher().tick();
|
||||
redraw |= myOSystem.launcher().needsRedraw();
|
||||
if(redraw)
|
||||
myOSystem.launcher().draw(forceRedraw);
|
||||
else if(rerender)
|
||||
myOSystem.launcher().render();
|
||||
break; // EventHandlerState::LAUNCHER
|
||||
}
|
||||
#endif
|
||||
|
@ -449,12 +460,12 @@ void FrameBuffer::update(bool force)
|
|||
#ifdef DEBUGGER_SUPPORT
|
||||
case EventHandlerState::DEBUGGER:
|
||||
{
|
||||
force = force || myOSystem.debugger().needsRedraw();
|
||||
if(force)
|
||||
{
|
||||
clear();
|
||||
myOSystem.debugger().draw(force);
|
||||
}
|
||||
myOSystem.debugger().tick();
|
||||
redraw |= myOSystem.debugger().needsRedraw();
|
||||
if(redraw)
|
||||
myOSystem.debugger().draw(forceRedraw);
|
||||
else if(rerender)
|
||||
myOSystem.debugger().render();
|
||||
break; // EventHandlerState::DEBUGGER
|
||||
}
|
||||
#endif
|
||||
|
@ -468,10 +479,10 @@ void FrameBuffer::update(bool force)
|
|||
// indicates that, and then the code at the top of this method sees
|
||||
// the change and redraws everything
|
||||
if(myMsg.enabled)
|
||||
drawMessage();
|
||||
redraw |= drawMessage();
|
||||
|
||||
// Push buffers to screen only when necessary
|
||||
if(force)
|
||||
if(redraw || rerender)
|
||||
myBackend->renderToScreen();
|
||||
}
|
||||
|
||||
|
@ -501,19 +512,15 @@ void FrameBuffer::updateInEmulationMode(float framesPerSecond)
|
|||
myBackend->renderToScreen();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::showMessage(const string& message, MessagePosition position,
|
||||
bool force)
|
||||
{
|
||||
#ifdef GUI_SUPPORT
|
||||
void FrameBuffer::createMessage(const string& message, MessagePosition position, bool force)
|
||||
{
|
||||
// Only show messages if they've been enabled
|
||||
if(myMsg.surface == nullptr || !(force || myOSystem.settings().getBool("uimessages")))
|
||||
return;
|
||||
|
||||
const int fontWidth = font().getMaxCharWidth(),
|
||||
fontHeight = font().getFontHeight();
|
||||
const int fontHeight = font().getFontHeight();
|
||||
const int VBORDER = fontHeight / 4;
|
||||
const int HBORDER = fontWidth * 1.25 / 2.0;
|
||||
|
||||
myMsg.counter = uInt32(myOSystem.frameRate()) * 2; // Show message for 2 seconds
|
||||
if(myMsg.counter == 0)
|
||||
|
@ -522,39 +529,40 @@ void FrameBuffer::showMessage(const string& message, MessagePosition position,
|
|||
// Precompute the message coordinates
|
||||
myMsg.text = message;
|
||||
myMsg.color = kBtnTextColor;
|
||||
myMsg.showGauge = false;
|
||||
myMsg.w = std::min(fontWidth * (MESSAGE_WIDTH) - HBORDER * 2,
|
||||
font().getStringWidth(myMsg.text) + HBORDER * 2);
|
||||
myMsg.h = fontHeight + VBORDER * 2;
|
||||
myMsg.position = position;
|
||||
myMsg.enabled = true;
|
||||
myMsg.dirty = true;
|
||||
|
||||
myMsg.surface->setSrcSize(myMsg.w, myMsg.h);
|
||||
myMsg.surface->setDstSize(myMsg.w * hidpiScaleFactor(), myMsg.h * hidpiScaleFactor());
|
||||
}
|
||||
#endif
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::showTextMessage(const string& message, MessagePosition position,
|
||||
bool force)
|
||||
{
|
||||
#ifdef GUI_SUPPORT
|
||||
const int fontWidth = font().getMaxCharWidth();
|
||||
const int HBORDER = fontWidth * 1.25 / 2.0;
|
||||
|
||||
myMsg.showGauge = false;
|
||||
myMsg.w = std::min(fontWidth * (MESSAGE_WIDTH) - HBORDER * 2,
|
||||
font().getStringWidth(message) + HBORDER * 2);
|
||||
|
||||
createMessage(message, position, force);
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::showMessage(const string& message, const string& valueText,
|
||||
void FrameBuffer::showGaugeMessage(const string& message, const string& valueText,
|
||||
float value, float minValue, float maxValue)
|
||||
{
|
||||
#ifdef GUI_SUPPORT
|
||||
// Only show messages if they've been enabled
|
||||
if(myMsg.surface == nullptr || !myOSystem.settings().getBool("uimessages"))
|
||||
return;
|
||||
|
||||
const int fontWidth = font().getMaxCharWidth(),
|
||||
fontHeight = font().getFontHeight();
|
||||
const int VBORDER = fontHeight / 4;
|
||||
const int fontWidth = font().getMaxCharWidth();
|
||||
const int HBORDER = fontWidth * 1.25 / 2.0;
|
||||
|
||||
myMsg.counter = uInt32(myOSystem.frameRate()) * 2; // Show message for 2 seconds
|
||||
if(myMsg.counter == 0)
|
||||
myMsg.counter = 120;
|
||||
|
||||
// Precompute the message coordinates
|
||||
myMsg.text = message;
|
||||
myMsg.color = kBtnTextColor;
|
||||
myMsg.showGauge = true;
|
||||
if(maxValue - minValue != 0)
|
||||
myMsg.value = (value - minValue) / (maxValue - minValue) * 100.F;
|
||||
|
@ -562,16 +570,12 @@ void FrameBuffer::showMessage(const string& message, const string& valueText,
|
|||
myMsg.value = 100.F;
|
||||
myMsg.valueText = valueText;
|
||||
myMsg.w = std::min(fontWidth * MESSAGE_WIDTH,
|
||||
font().getStringWidth(myMsg.text)
|
||||
font().getStringWidth(message)
|
||||
+ fontWidth * (GAUGEBAR_WIDTH + 2)
|
||||
+ font().getStringWidth(myMsg.valueText))
|
||||
+ font().getStringWidth(valueText))
|
||||
+ HBORDER * 2;
|
||||
myMsg.h = fontHeight + VBORDER * 2;
|
||||
myMsg.position = MessagePosition::BottomCenter;
|
||||
myMsg.enabled = true;
|
||||
|
||||
myMsg.surface->setSrcSize(myMsg.w, myMsg.h);
|
||||
myMsg.surface->setDstSize(myMsg.w * hidpiScaleFactor(), myMsg.h * hidpiScaleFactor());
|
||||
createMessage(message, MessagePosition::BottomCenter);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -652,7 +656,7 @@ void FrameBuffer::toggleFrameStats(bool toggle)
|
|||
myOSystem.settings().setValue(
|
||||
myOSystem.settings().getBool("dev.settings") ? "dev.stats" : "plr.stats", myStatsEnabled);
|
||||
|
||||
myOSystem.frameBuffer().showMessage(string("Console info ") +
|
||||
myOSystem.frameBuffer().showTextMessage(string("Console info ") +
|
||||
(myStatsEnabled ? "enabled" : "disabled"));
|
||||
}
|
||||
|
||||
|
@ -676,12 +680,19 @@ void FrameBuffer::enableMessages(bool enable)
|
|||
myStatsMsg.enabled = false;
|
||||
|
||||
// Erase old messages on the screen
|
||||
myMsg.enabled = false;
|
||||
myMsg.counter = 0;
|
||||
update(true); // Force update immediately
|
||||
hideMessage();
|
||||
|
||||
update(); // update immediately
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::hideMessage()
|
||||
{
|
||||
myPendingRender = myMsg.enabled;
|
||||
myMsg.enabled = false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
inline bool FrameBuffer::drawMessage()
|
||||
{
|
||||
|
@ -690,15 +701,14 @@ inline bool FrameBuffer::drawMessage()
|
|||
// or show again this frame
|
||||
if(myMsg.counter == 0)
|
||||
{
|
||||
myMsg.enabled = false;
|
||||
return true;
|
||||
}
|
||||
else if(myMsg.counter < 0)
|
||||
{
|
||||
myMsg.enabled = false;
|
||||
hideMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(myMsg.dirty)
|
||||
{
|
||||
cerr << "--- draw message ---" << endl;
|
||||
|
||||
// Draw the bounded box and text
|
||||
const Common::Rect& dst = myMsg.surface->dstRect();
|
||||
const int fontWidth = font().getMaxCharWidth(),
|
||||
|
@ -794,11 +804,16 @@ inline bool FrameBuffer::drawMessage()
|
|||
x + swidth + fontWidth, VBORDER,
|
||||
myMsg.w, myMsg.color);
|
||||
}
|
||||
myMsg.dirty = false;
|
||||
myMsg.surface->render();
|
||||
return true;
|
||||
}
|
||||
|
||||
myMsg.counter--;
|
||||
myMsg.surface->render();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -845,7 +860,7 @@ void FrameBuffer::resetSurfaces()
|
|||
freeSurfaces();
|
||||
reloadSurfaces();
|
||||
|
||||
update(true); // force full update
|
||||
update(UpdateMode::REDRAW); // force full update
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -898,10 +913,9 @@ void FrameBuffer::setUIPalette()
|
|||
void FrameBuffer::stateChanged(EventHandlerState state)
|
||||
{
|
||||
// Make sure any onscreen messages are removed
|
||||
myMsg.enabled = false;
|
||||
myMsg.counter = 0;
|
||||
hideMessage();
|
||||
|
||||
update(true); // force full update
|
||||
update(); // update immediately
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -990,7 +1004,9 @@ void FrameBuffer::setFullscreen(bool enable)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::toggleFullscreen(bool toggle)
|
||||
{
|
||||
switch(myOSystem.eventHandler().state())
|
||||
EventHandlerState state = myOSystem.eventHandler().state();
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case EventHandlerState::LAUNCHER:
|
||||
case EventHandlerState::EMULATION:
|
||||
|
@ -1000,17 +1016,27 @@ void FrameBuffer::toggleFullscreen(bool toggle)
|
|||
const bool isFullscreen = toggle ? !fullScreen() : fullScreen();
|
||||
setFullscreen(isFullscreen);
|
||||
|
||||
if(myBufferType != BufferType::Launcher)
|
||||
if(state != EventHandlerState::LAUNCHER)
|
||||
{
|
||||
ostringstream msg;
|
||||
msg << "Fullscreen ";
|
||||
|
||||
if(state != EventHandlerState::DEBUGGER)
|
||||
{
|
||||
if(isFullscreen)
|
||||
msg << "enabled (" << myBackend->refreshRate() << " Hz, ";
|
||||
else
|
||||
msg << "disabled (";
|
||||
msg << "Zoom " << myActiveVidMode.zoom * 100 << "%)";
|
||||
|
||||
showMessage(msg.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
if(isFullscreen)
|
||||
msg << "enabled";
|
||||
else
|
||||
msg << "disabled";
|
||||
}
|
||||
showTextMessage(msg.str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1043,7 +1069,7 @@ void FrameBuffer::toggleAdaptRefresh(bool toggle)
|
|||
msg << (isAdaptRefresh ? "enabled" : "disabled");
|
||||
msg << " (" << myBackend->refreshRate() << " Hz)";
|
||||
|
||||
showMessage(msg.str());
|
||||
showTextMessage(msg.str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1069,7 +1095,7 @@ void FrameBuffer::changeOverscan(int direction)
|
|||
val << (overscan > 0 ? "+" : "" ) << overscan << "%";
|
||||
else
|
||||
val << "Off";
|
||||
myOSystem.frameBuffer().showMessage("Overscan", val.str(), overscan, 0, 10);
|
||||
myOSystem.frameBuffer().showGaugeMessage("Overscan", val.str(), overscan, 0, 10);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1106,9 +1132,9 @@ void FrameBuffer::switchVideoMode(int direction)
|
|||
if(applyVideoMode() == FBInitStatus::Success)
|
||||
{
|
||||
if(fullScreen())
|
||||
showMessage(myActiveVidMode.description);
|
||||
showTextMessage(myActiveVidMode.description);
|
||||
else
|
||||
showMessage("Zoom", myActiveVidMode.description, myActiveVidMode.zoom,
|
||||
showGaugeMessage("Zoom", myActiveVidMode.description, myActiveVidMode.zoom,
|
||||
supportedTIAMinZoom(), myTIAMaxZoom);
|
||||
}
|
||||
}
|
||||
|
@ -1163,6 +1189,7 @@ FBInitStatus FrameBuffer::applyVideoMode()
|
|||
|
||||
resetSurfaces();
|
||||
setCursorState();
|
||||
myPendingRender = true;
|
||||
}
|
||||
else
|
||||
Logger::error("ERROR: Couldn't initialize video subsystem");
|
||||
|
@ -1248,7 +1275,7 @@ void FrameBuffer::toggleGrabMouse()
|
|||
myGrabMouse = !myGrabMouse;
|
||||
setCursorState();
|
||||
myOSystem.settings().setValue("grabmouse", myGrabMouse);
|
||||
myOSystem.frameBuffer().showMessage(oldState != myGrabMouse ? myGrabMouse
|
||||
myOSystem.frameBuffer().showTextMessage(oldState != myGrabMouse ? myGrabMouse
|
||||
? "Grab mouse enabled" : "Grab mouse disabled"
|
||||
: "Grab mouse not allowed while cursor shown");
|
||||
}
|
||||
|
@ -1299,8 +1326,6 @@ void FrameBuffer::toggleGrabMouse()
|
|||
kColorInfo TIA output position color
|
||||
kColorTitleBar Title bar color
|
||||
kColorTitleText Title text color
|
||||
kColorTitleBarLo Disabled title bar color
|
||||
kColorTitleTextLo Disabled title text color
|
||||
*/
|
||||
UIPaletteArray FrameBuffer::ourStandardUIPalette = {
|
||||
{ 0x686868, 0x000000, 0xa38c61, 0xdccfa5, 0x404040, // base
|
||||
|
@ -1311,7 +1336,7 @@ UIPaletteArray FrameBuffer::ourStandardUIPalette = {
|
|||
0xac3410, 0xd55941, // scrollbar
|
||||
0xc80000, 0xffff80, 0xc8c8ff, 0xc80000, // debugger
|
||||
0xac3410, 0xd55941, 0xdccfa5, 0xf0f0cf, 0xa38c61, // slider
|
||||
0xffffff, 0xac3410, 0xf0f0cf, 0x686868, 0xdccfa5 // other
|
||||
0xffffff, 0xac3410, 0xf0f0cf // other
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1324,7 +1349,7 @@ UIPaletteArray FrameBuffer::ourClassicUIPalette = {
|
|||
0x20a020, 0x00ff00, // scrollbar
|
||||
0xc80000, 0x00ff00, 0xc8c8ff, 0xc80000, // debugger
|
||||
0x20a020, 0x00ff00, 0x404040, 0x686868, 0x404040, // slider
|
||||
0x00ff00, 0x20a020, 0x000000, 0x686868, 0x404040 // other
|
||||
0x00ff00, 0x20a020, 0x000000 // other
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1337,7 +1362,7 @@ UIPaletteArray FrameBuffer::ourLightUIPalette = {
|
|||
0xc0c0c0, 0x808080, // scrollbar
|
||||
0xffc0c0, 0x000000, 0xe00000, 0xc00000, // debugger
|
||||
0x333333, 0x0078d7, 0xc0c0c0, 0xffffff, 0xc0c0c0, // slider 0xBDDEF9| 0xe1e1e1 | 0xffffff
|
||||
0xffffff, 0x333333, 0xf0f0f0, 0x808080, 0xc0c0c0 // other
|
||||
0xffffff, 0x333333, 0xf0f0f0 // other
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1350,6 +1375,6 @@ UIPaletteArray FrameBuffer::ourDarkUIPalette = {
|
|||
0x3c3c3c, 0x646464, // scrollbar
|
||||
0x7f2020, 0xc0c0c0, 0xe00000, 0xc00000, // debugger
|
||||
0x989898, 0x0059a3, 0x3c3c3c, 0x000000, 0x3c3c3c, // slider
|
||||
0x000000, 0x989898, 0x202020, 0x646464, 0x3c3c3c // other
|
||||
0x000000, 0x989898, 0x202020 // other
|
||||
}
|
||||
};
|
||||
|
|
|
@ -55,6 +55,12 @@ class FrameBuffer
|
|||
// Zoom level step interval
|
||||
static constexpr float ZOOM_STEPS = 0.25;
|
||||
|
||||
enum UpdateMode {
|
||||
NONE = 0,
|
||||
REDRAW = 1,
|
||||
RERENDER = 2
|
||||
};
|
||||
|
||||
public:
|
||||
FrameBuffer(OSystem& osystem);
|
||||
~FrameBuffer();
|
||||
|
@ -84,7 +90,7 @@ class FrameBuffer
|
|||
Updates the display, which depending on the current mode could mean
|
||||
drawing the TIA, any pending menus, etc.
|
||||
*/
|
||||
void update(bool force = false);
|
||||
void update(UpdateMode mode = UpdateMode::NONE);
|
||||
|
||||
/**
|
||||
There is a dedicated update method for emulation mode.
|
||||
|
@ -92,13 +98,18 @@ class FrameBuffer
|
|||
void updateInEmulationMode(float framesPerSecond);
|
||||
|
||||
/**
|
||||
Shows a message onscreen.
|
||||
Set pending rendering flag.
|
||||
*/
|
||||
void setPendingRender() { myPendingRender = true; }
|
||||
|
||||
/**
|
||||
Shows a text message onscreen.
|
||||
|
||||
@param message The message to be shown
|
||||
@param position Onscreen position for the message
|
||||
@param force Force showing this message, even if messages are disabled
|
||||
*/
|
||||
void showMessage(const string& message,
|
||||
void showTextMessage(const string& message,
|
||||
MessagePosition position = MessagePosition::BottomCenter,
|
||||
bool force = false);
|
||||
/**
|
||||
|
@ -110,7 +121,7 @@ class FrameBuffer
|
|||
@param minValue The minimal value of the gauge bar
|
||||
@param maxValue The maximal value of the gauge bar
|
||||
*/
|
||||
void showMessage(const string& message, const string& valueText,
|
||||
void showGaugeMessage(const string& message, const string& valueText,
|
||||
float value, float minValue = 0.F, float maxValue = 100.F);
|
||||
|
||||
bool messageShown() const;
|
||||
|
@ -375,6 +386,18 @@ class FrameBuffer
|
|||
*/
|
||||
void resetSurfaces();
|
||||
|
||||
#ifdef GUI_SUPPORT
|
||||
/**
|
||||
Helps to create a basic message onscreen.
|
||||
|
||||
@param message The message to be shown
|
||||
@param position Onscreen position for the message
|
||||
@param force Force showing this message, even if messages are disabled
|
||||
*/
|
||||
void createMessage(const string& message, MessagePosition position,
|
||||
bool force = false);
|
||||
#endif
|
||||
|
||||
/**
|
||||
Draw pending messages.
|
||||
|
||||
|
@ -382,6 +405,11 @@ class FrameBuffer
|
|||
*/
|
||||
bool drawMessage();
|
||||
|
||||
/**
|
||||
Hide pending messages.
|
||||
*/
|
||||
void hideMessage();
|
||||
|
||||
/**
|
||||
Draws the frame stats overlay.
|
||||
*/
|
||||
|
@ -443,6 +471,9 @@ class FrameBuffer
|
|||
// Supported renderers
|
||||
VariantList myRenderers;
|
||||
|
||||
// Flag for pending render
|
||||
bool myPendingRender{false};
|
||||
|
||||
// The VideoModeHandler class takes responsibility for all video
|
||||
// mode functionality
|
||||
VideoModeHandler myVidModeHandler;
|
||||
|
@ -478,6 +509,7 @@ class FrameBuffer
|
|||
ColorId color{kNone};
|
||||
shared_ptr<FBSurface> surface;
|
||||
bool enabled{false};
|
||||
bool dirty{false};
|
||||
bool showGauge{false};
|
||||
float value{0.0F};
|
||||
string valueText;
|
||||
|
|
|
@ -109,9 +109,7 @@ static constexpr ColorId
|
|||
kColorInfo = 287,
|
||||
kColorTitleBar = 288,
|
||||
kColorTitleText = 289,
|
||||
kColorTitleBarLo = 290,
|
||||
kColorTitleTextLo = 291,
|
||||
kNumColors = 292,
|
||||
kNumColors = 290,
|
||||
kNone = 0 // placeholder to represent default/no color
|
||||
;
|
||||
|
||||
|
|
|
@ -475,9 +475,9 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum,
|
|||
{
|
||||
const string& id = myConsole->cartridge().multiCartID();
|
||||
if(id == "")
|
||||
myFrameBuffer->showMessage("New console created");
|
||||
myFrameBuffer->showTextMessage("New console created");
|
||||
else
|
||||
myFrameBuffer->showMessage("Multicart " +
|
||||
myFrameBuffer->showTextMessage("Multicart " +
|
||||
myConsole->cartridge().detectedType() + ", loading ROM" + id);
|
||||
}
|
||||
buf << "Game console created:" << endl
|
||||
|
@ -506,7 +506,7 @@ string OSystem::createConsole(const FilesystemNode& rom, const string& md5sum,
|
|||
msg << myConsole->leftController().name() << "/" << myConsole->rightController().name()
|
||||
<< " - " << myConsole->cartridge().detectedType()
|
||||
<< " - " << myConsole->getFormatString();
|
||||
myFrameBuffer->showMessage(msg.str());
|
||||
myFrameBuffer->showTextMessage(msg.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ unique_ptr<Controller> QuadTari::addController(const Controller::Type type, bool
|
|||
Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) {
|
||||
bool devSettings = os.settings().getBool("dev.settings");
|
||||
if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess"))
|
||||
os.frameBuffer().showMessage(msg);
|
||||
os.frameBuffer().showTextMessage(msg);
|
||||
};
|
||||
|
||||
switch(type)
|
||||
|
|
|
@ -184,7 +184,7 @@ void TIASurface::setNTSC(NTSCFilter::Preset preset, bool show)
|
|||
}
|
||||
myOSystem.settings().setValue("tv.filter", int(preset));
|
||||
|
||||
if(show) myFB.showMessage(buf.str());
|
||||
if(show) myFB.showTextMessage(buf.str());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -221,7 +221,7 @@ void TIASurface::setNTSCAdjustable(int direction)
|
|||
|
||||
setNTSC(NTSCFilter::Preset::CUSTOM);
|
||||
ntsc().selectAdjustable(direction, text, valueText, value);
|
||||
myOSystem.frameBuffer().showMessage(text, valueText, value);
|
||||
myOSystem.frameBuffer().showGaugeMessage(text, valueText, value);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -232,7 +232,7 @@ void TIASurface::changeNTSCAdjustable(int adjustable, int direction)
|
|||
|
||||
setNTSC(NTSCFilter::Preset::CUSTOM);
|
||||
ntsc().changeAdjustable(adjustable, direction, text, valueText, newValue);
|
||||
myOSystem.frameBuffer().showMessage(text, valueText, newValue);
|
||||
myOSystem.frameBuffer().showGaugeMessage(text, valueText, newValue);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -243,7 +243,7 @@ void TIASurface::changeCurrentNTSCAdjustable(int direction)
|
|||
|
||||
setNTSC(NTSCFilter::Preset::CUSTOM);
|
||||
ntsc().changeCurrentAdjustable(direction, text, valueText, newValue);
|
||||
myOSystem.frameBuffer().showMessage(text, valueText, newValue);
|
||||
myOSystem.frameBuffer().showGaugeMessage(text, valueText, newValue);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -259,7 +259,7 @@ void TIASurface::setScanlineIntensity(int direction)
|
|||
buf << intensity << "%";
|
||||
else
|
||||
buf << "Off";
|
||||
myFB.showMessage("Scanline intensity", buf.str(), intensity);
|
||||
myFB.showGaugeMessage("Scanline intensity", buf.str(), intensity);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -67,11 +67,12 @@ AboutDialog::AboutDialog(OSystem& osystem, DialogContainer& parent,
|
|||
addCancelWidget(b);
|
||||
|
||||
xpos = HBORDER; ypos = _th + VBORDER + (buttonHeight - fontHeight) / 2;
|
||||
myTitle = new StaticTextWidget(this, font, xpos, ypos, _w - xpos * 2, fontHeight,
|
||||
"", TextAlign::Center);
|
||||
int bwidth = font.getStringWidth("What's New" + ELLIPSIS) + fontWidth * 2.5;
|
||||
|
||||
myTitle = new StaticTextWidget(this, font, xpos + bwidth, ypos, _w - (xpos + bwidth) * 2,
|
||||
fontHeight, "", TextAlign::Center);
|
||||
myTitle->setTextColor(kTextColorEm);
|
||||
|
||||
int bwidth = font.getStringWidth("What's New" + ELLIPSIS) + fontWidth * 2.5;
|
||||
myWhatsNewButton =
|
||||
new ButtonWidget(this, font, _w - HBORDER - bwidth, ypos - (buttonHeight - fontHeight) / 2,
|
||||
bwidth, buttonHeight, "What's New" + ELLIPSIS, kWhatsNew);
|
||||
|
|
|
@ -46,20 +46,6 @@ CheckListWidget::CheckListWidget(GuiObject* boss, const GUI::Font& font,
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheckListWidget::handleMouseEntered()
|
||||
{
|
||||
setFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheckListWidget::handleMouseLeft()
|
||||
{
|
||||
clearFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheckListWidget::setList(const StringList& list, const BoolArray& state)
|
||||
{
|
||||
|
|
|
@ -42,10 +42,6 @@ class CheckListWidget : public ListWidget
|
|||
bool getState(int line);
|
||||
bool getSelectedState() { return getState(_selectedItem); }
|
||||
|
||||
protected:
|
||||
void handleMouseEntered() override;
|
||||
void handleMouseLeft() override;
|
||||
|
||||
private:
|
||||
bool handleEvent(Event::Type e) override;
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
|
|
|
@ -77,7 +77,7 @@ void ContextMenu::show(uInt32 x, uInt32 y, const Common::Rect& bossRect, int ite
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ContextMenu::center()
|
||||
void ContextMenu::setPosition()
|
||||
{
|
||||
// First set position according to original coordinates
|
||||
surface().setDstPos(_xorig, _yorig);
|
||||
|
@ -346,8 +346,12 @@ int ContextMenu::findItem(int x, int y) const
|
|||
void ContextMenu::drawCurrentSelection(int item)
|
||||
{
|
||||
// Change selection
|
||||
if(_selectedOffset != item)
|
||||
{
|
||||
_selectedOffset = item;
|
||||
cerr << "ContextMenu" << endl;
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -621,5 +625,5 @@ void ContextMenu::drawDialog()
|
|||
s.drawBitmap(_downImg, ((_w-_x)>>1)-4, (_rowHeight>>1)+y-4, _scrollDnColor, _arrowSize);
|
||||
}
|
||||
|
||||
setDirty();
|
||||
clearDirty();
|
||||
}
|
||||
|
|
|
@ -71,8 +71,8 @@ class ContextMenu : public Dialog, public CommandSender
|
|||
const string& getSelectedName() const;
|
||||
const Variant& getSelectedTag() const;
|
||||
|
||||
/** This dialog uses its own positioning, so we override Dialog::center() */
|
||||
void center() override;
|
||||
/** This dialog uses its own positioning, so we override Dialog::setPosition() */
|
||||
void setPosition() override;
|
||||
|
||||
/** The following methods are used when we want to select *and*
|
||||
send a command for the new selection. They are only to be used
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "Dialog.hxx"
|
||||
#include "Widget.hxx"
|
||||
#include "TabWidget.hxx"
|
||||
#include "ToolTip.hxx"
|
||||
|
||||
#include "ContextMenu.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
|
@ -49,10 +50,24 @@ Dialog::Dialog(OSystem& instance, DialogContainer& parent, const GUI::Font& font
|
|||
const string& title, int x, int y, int w, int h)
|
||||
: GuiObject(instance, parent, *this, x, y, w, h),
|
||||
_font(font),
|
||||
_title(title),
|
||||
_flags(Widget::FLAG_ENABLED | Widget::FLAG_BORDER | Widget::FLAG_CLEARBG)
|
||||
_title(title)
|
||||
{
|
||||
_flags = Widget::FLAG_ENABLED | Widget::FLAG_BORDER | Widget::FLAG_CLEARBG;
|
||||
setTitle(title);
|
||||
|
||||
// Create shading surface
|
||||
uInt32 data = 0xff000000;
|
||||
|
||||
_shadeSurface = instance.frameBuffer().allocateSurface(
|
||||
1, 1, ScalingInterpolation::sharp, &data);
|
||||
|
||||
FBSurface::Attributes& attr = _shadeSurface->attributes();
|
||||
|
||||
attr.blending = true;
|
||||
attr.blendalpha = 25; // darken background dialogs by 25%
|
||||
_shadeSurface->applyAttributes();
|
||||
|
||||
_toolTip = make_unique<ToolTip>(*this, font);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -91,7 +106,7 @@ void Dialog::open()
|
|||
const uInt32 scale = instance().frameBuffer().hidpiScaleFactor();
|
||||
_surface->setDstSize(_w * scale, _h * scale);
|
||||
|
||||
center();
|
||||
setPosition();
|
||||
|
||||
if(_myTabList.size())
|
||||
// (Re)-build the focus list to use for all widgets of all tabs
|
||||
|
@ -110,8 +125,6 @@ void Dialog::open()
|
|||
loadConfig(); // has to be done AFTER (re)building the focus list
|
||||
|
||||
_visible = true;
|
||||
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -128,7 +141,6 @@ void Dialog::close()
|
|||
_visible = false;
|
||||
|
||||
parent().removeDialog();
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -144,11 +156,36 @@ void Dialog::setTitle(const string& title)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::center()
|
||||
void Dialog::setPosition()
|
||||
{
|
||||
positionAt(instance().settings().getInt("dialogpos"));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::setDirty()
|
||||
{
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::setDirtyChain()
|
||||
{
|
||||
_dirtyChain = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::tick()
|
||||
{
|
||||
// Recursively tick dialog and all child dialogs and widgets
|
||||
Widget* w = _firstWidget;
|
||||
|
||||
while(w)
|
||||
{
|
||||
w->tick();
|
||||
w = w->_next;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::positionAt(uInt32 pos)
|
||||
{
|
||||
|
@ -190,26 +227,50 @@ void Dialog::positionAt(uInt32 pos)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Dialog::render()
|
||||
void Dialog::redraw(bool force)
|
||||
{
|
||||
if(!_dirty || !isVisible())
|
||||
return false;
|
||||
if(!isVisible())
|
||||
return;
|
||||
|
||||
if(force)
|
||||
setDirty();
|
||||
|
||||
// Draw this dialog
|
||||
center();
|
||||
setPosition();
|
||||
drawDialog();
|
||||
// full rendering is caused in dialog container
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Dialog::render()
|
||||
{
|
||||
cerr << " render " << typeid(*this).name() << endl;
|
||||
|
||||
// Update dialog surface; also render any extra surfaces
|
||||
// Extra surfaces must be rendered afterwards, so they are drawn on top
|
||||
if(_surface->render())
|
||||
{
|
||||
mySurfaceStack.applyAll([](shared_ptr<FBSurface>& surface){
|
||||
mySurfaceStack.applyAll([](shared_ptr<FBSurface>& surface) {
|
||||
surface->render();
|
||||
});
|
||||
}
|
||||
_dirty = false;
|
||||
|
||||
return true;
|
||||
// Dialog is still on top if e.g a dialog without title is opened
|
||||
// (e.g. ContextMenu)
|
||||
bool onTop = parent().myDialogStack.top() == this
|
||||
|| (parent().myDialogStack.get(parent().myDialogStack.size() - 2) == this
|
||||
&& !parent().myDialogStack.top()->hasTitle());
|
||||
//&& typeid(*parent().myDialogStack.top()) == typeid(ContextMenu))
|
||||
|
||||
if(!onTop)
|
||||
{
|
||||
cerr << " shade " << typeid(*this).name() << endl;
|
||||
|
||||
_shadeSurface->setDstRect(_surface->dstRect());
|
||||
_shadeSurface->render();
|
||||
}
|
||||
|
||||
_toolTip->render();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -305,7 +366,7 @@ void Dialog::setFocus(Widget* w)
|
|||
{
|
||||
// If the click occured inside a widget which is not the currently
|
||||
// focused one, change the focus to that widget.
|
||||
if(w && w != _focusedWidget && w->wantsFocus())
|
||||
if(w && w != _focusedWidget && w->wantsFocus() && w->isEnabled())
|
||||
{
|
||||
// Redraw widgets for new focus
|
||||
_focusedWidget = Widget::setFocusForChain(this, getFocusList(), w, 0);
|
||||
|
@ -371,39 +432,43 @@ void Dialog::drawDialog()
|
|||
|
||||
FBSurface& s = surface();
|
||||
|
||||
// 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
|
||||
&& !parent().myDialogStack.top()->hasTitle());
|
||||
if(isDirty())
|
||||
{
|
||||
cerr << endl << "d";
|
||||
//cerr << "*** draw dialog " << typeid(*this).name() << " ***" << endl;
|
||||
|
||||
if(_flags & Widget::FLAG_CLEARBG)
|
||||
if(clearsBackground())
|
||||
{
|
||||
// cerr << "Dialog::drawDialog(): w = " << _w << ", h = " << _h << " @ " << &s << endl << endl;
|
||||
s.fillRect(_x, _y + _th, _w, _h - _th, _onTop ? kDlgColor : kBGColorLo);
|
||||
|
||||
if(hasBackground())
|
||||
s.fillRect(_x, _y + _th, _w, _h - _th, kDlgColor);
|
||||
else
|
||||
s.invalidateRect(_x, _y + _th, _w, _h - _th);
|
||||
if(_th)
|
||||
{
|
||||
s.fillRect(_x, _y, _w, _th, _onTop ? kColorTitleBar : kColorTitleBarLo);
|
||||
s.fillRect(_x, _y, _w, _th, kColorTitleBar);
|
||||
s.drawString(_font, _title, _x + _font.getMaxCharWidth() * 1.25, _y + _font.getFontHeight() / 6,
|
||||
_font.getStringWidth(_title),
|
||||
_onTop ? kColorTitleText : kColorTitleTextLo);
|
||||
_font.getStringWidth(_title), kColorTitleText);
|
||||
}
|
||||
}
|
||||
else {
|
||||
s.invalidate();
|
||||
//cerr << "invalidate " << typeid(*this).name() << endl;
|
||||
}
|
||||
if(hasBorder()) // currently only used by Dialog itself
|
||||
s.frameRect(_x, _y, _w, _h, kColor);
|
||||
|
||||
// Make all child widgets dirty
|
||||
Widget::setDirtyInChain(_firstWidget);
|
||||
|
||||
clearDirty();
|
||||
}
|
||||
else
|
||||
s.invalidate();
|
||||
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
|
||||
Widget* w = _firstWidget;
|
||||
Widget::setDirtyInChain(w);
|
||||
cerr << endl;
|
||||
|
||||
// Draw all children
|
||||
w = _firstWidget;
|
||||
while(w)
|
||||
{
|
||||
w->draw();
|
||||
w = w->_next;
|
||||
}
|
||||
drawChain();
|
||||
|
||||
// Draw outlines for focused widgets
|
||||
// Don't change focus, since this will trigger lost and received
|
||||
|
@ -412,8 +477,25 @@ void Dialog::drawDialog()
|
|||
{
|
||||
_focusedWidget = Widget::setFocusForChain(this, getFocusList(),
|
||||
_focusedWidget, 0, false);
|
||||
if(_focusedWidget)
|
||||
_focusedWidget->draw(); // make sure the highlight color is drawn initially
|
||||
//if(_focusedWidget)
|
||||
// _focusedWidget->draw(); // make sure the highlight color is drawn initially
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -556,6 +638,9 @@ void Dialog::handleMouseMoved(int x, int y)
|
|||
|
||||
if (w && (w->getFlags() & Widget::FLAG_TRACK_MOUSE))
|
||||
w->handleMouseMoved(x - (w->getAbsX() - _x), y - (w->getAbsY() - _y));
|
||||
|
||||
// Update mouse coordinates for tooltips
|
||||
_toolTip->update(_mouseWidget, Common::Point(x, y));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -26,6 +26,7 @@ class OSystem;
|
|||
class DialogContainer;
|
||||
class TabWidget;
|
||||
class CommandSender;
|
||||
class ToolTip;
|
||||
|
||||
#include "Stack.hxx"
|
||||
#include "Widget.hxx"
|
||||
|
@ -54,19 +55,21 @@ class Dialog : public GuiObject
|
|||
void close();
|
||||
|
||||
bool isVisible() const override { return _visible; }
|
||||
bool isOnTop() const { return _onTop; }
|
||||
bool isOnTop() const { return true; } // TODO: remove
|
||||
|
||||
virtual void center();
|
||||
virtual void setPosition();
|
||||
virtual void drawDialog();
|
||||
virtual void loadConfig() { }
|
||||
virtual void saveConfig() { }
|
||||
virtual void setDefaults() { }
|
||||
|
||||
// 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; }
|
||||
bool render();
|
||||
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;
|
||||
|
@ -89,10 +92,6 @@ class Dialog : public GuiObject
|
|||
*/
|
||||
void addSurface(const shared_ptr<FBSurface>& surface);
|
||||
|
||||
void setFlags(int flags) { _flags |= flags; setDirty(); }
|
||||
void clearFlags(int flags) { _flags &= ~flags; setDirty(); }
|
||||
int getFlags() const { return _flags; }
|
||||
|
||||
void setTitle(const string& title);
|
||||
bool hasTitle() { return !_title.empty(); }
|
||||
|
||||
|
@ -124,6 +123,8 @@ class Dialog : public GuiObject
|
|||
*/
|
||||
bool shouldResize(uInt32& w, uInt32& h) const;
|
||||
|
||||
ToolTip& tooltip() { return *_toolTip; }
|
||||
|
||||
protected:
|
||||
void draw() override { }
|
||||
void releaseFocus() override;
|
||||
|
@ -197,11 +198,11 @@ class Dialog : public GuiObject
|
|||
Widget* _cancelWidget{nullptr};
|
||||
|
||||
bool _visible{false};
|
||||
bool _onTop{true};
|
||||
bool _processCancel{false};
|
||||
string _title;
|
||||
int _th{0};
|
||||
int _layer{0};
|
||||
unique_ptr<ToolTip> _toolTip;
|
||||
|
||||
Common::FixedStack<shared_ptr<FBSurface>> mySurfaceStack;
|
||||
|
||||
|
@ -232,10 +233,9 @@ class Dialog : public GuiObject
|
|||
|
||||
WidgetArray _buttonGroup;
|
||||
shared_ptr<FBSurface> _surface;
|
||||
shared_ptr<FBSurface> _shadeSurface;
|
||||
|
||||
int _tabID{0};
|
||||
int _flags{0};
|
||||
bool _dirty{false};
|
||||
uInt32 _max_w{0}; // maximum wanted width
|
||||
uInt32 _max_h{0}; // maximum wanted height
|
||||
|
||||
|
|
|
@ -89,31 +89,57 @@ void DialogContainer::updateTime(uInt64 time)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool DialogContainer::draw(bool full)
|
||||
void DialogContainer::draw(bool full)
|
||||
{
|
||||
if(myDialogStack.empty())
|
||||
return false;
|
||||
return;
|
||||
|
||||
cerr << "draw " << full << " " << typeid(*this).name() << endl;
|
||||
|
||||
// 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();
|
||||
|
||||
myDialogStack.applyAll([&](Dialog*& d){
|
||||
if(dirty)
|
||||
d->setDirty();
|
||||
full |= d->render();
|
||||
// Draw and render all dirty dialogs
|
||||
myDialogStack.applyAll([&](Dialog*& d) {
|
||||
if(full || d->needsRedraw())
|
||||
d->redraw(full);
|
||||
});
|
||||
// Always render all surfaces, bottom to top
|
||||
render();
|
||||
}
|
||||
|
||||
return full;
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DialogContainer::tick()
|
||||
{
|
||||
if(!myDialogStack.empty())
|
||||
myDialogStack.top()->tick();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DialogContainer::render()
|
||||
{
|
||||
if(myDialogStack.empty())
|
||||
return;
|
||||
|
||||
cerr << "full re-render " << typeid(*this).name() << endl;
|
||||
|
||||
// Make sure we start in a clean state (with zero'ed buffers)
|
||||
if(!myOSystem.eventHandler().inTIAMode())
|
||||
myOSystem.frameBuffer().clear();
|
||||
|
||||
// Render all dialogs
|
||||
myDialogStack.applyAll([&](Dialog*& d) {
|
||||
d->render();
|
||||
});
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool DialogContainer::needsRedraw() const
|
||||
{
|
||||
return !myDialogStack.empty() ? myDialogStack.top()->isDirty() : false;
|
||||
return !myDialogStack.empty()
|
||||
? myDialogStack.top()->needsRedraw()
|
||||
: false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -129,8 +155,8 @@ int DialogContainer::addDialog(Dialog* d)
|
|||
const uInt32 scale = myOSystem.frameBuffer().hidpiScaleFactor();
|
||||
|
||||
if(uInt32(d->getWidth() * scale) > r.w() || uInt32(d->getHeight() * scale) > r.h())
|
||||
myOSystem.frameBuffer().showMessage(
|
||||
"Unable to show dialog box; FIX THE CODE");
|
||||
myOSystem.frameBuffer().showTextMessage(
|
||||
"Unable to show dialog box; FIX THE CODE", MessagePosition::BottomCenter, true);
|
||||
else
|
||||
{
|
||||
d->setDirty();
|
||||
|
@ -144,9 +170,11 @@ void DialogContainer::removeDialog()
|
|||
{
|
||||
if(!myDialogStack.empty())
|
||||
{
|
||||
cerr << "remove dialog " << typeid(*myDialogStack.top()).name() << endl;
|
||||
myDialogStack.pop();
|
||||
if(!myDialogStack.empty())
|
||||
myDialogStack.top()->setDirty();
|
||||
|
||||
// Inform the frame buffer that it has to render all surfaces
|
||||
myOSystem.frameBuffer().setPendingRender();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,6 +185,9 @@ void DialogContainer::reStack()
|
|||
while(!myDialogStack.empty())
|
||||
myDialogStack.top()->close();
|
||||
|
||||
// Make sure that all surfaces are cleared
|
||||
myOSystem.frameBuffer().clear();
|
||||
|
||||
baseDialog()->open();
|
||||
|
||||
// Reset all continuous events
|
||||
|
|
|
@ -120,11 +120,19 @@ class DialogContainer
|
|||
void handleJoyHatEvent(int stick, int hat, JoyHatDir hdir, int button);
|
||||
|
||||
/**
|
||||
Draw the stack of menus (full indicates to redraw all items).
|
||||
|
||||
@return Answers whether any drawing actually occurred.
|
||||
Tick the dialog and all its widgets.
|
||||
*/
|
||||
bool draw(bool full = false);
|
||||
void tick();
|
||||
|
||||
/**
|
||||
Draw the stack of menus (full indicates to redraw all items).
|
||||
*/
|
||||
void draw(bool full = false);
|
||||
|
||||
/**
|
||||
Render the stack of menus.
|
||||
*/
|
||||
void render();
|
||||
|
||||
/**
|
||||
Answers whether a full redraw is required.
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "OSystem.hxx"
|
||||
#include "FBSurface.hxx"
|
||||
#include "Dialog.hxx"
|
||||
#include "ToolTip.hxx"
|
||||
#include "Font.hxx"
|
||||
#include "EditTextWidget.hxx"
|
||||
|
||||
|
@ -48,20 +49,6 @@ void EditTextWidget::setText(const string& str, bool changed)
|
|||
_changed = changed;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditTextWidget::handleMouseEntered()
|
||||
{
|
||||
setFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditTextWidget::handleMouseLeft()
|
||||
{
|
||||
clearFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditTextWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
|
||||
{
|
||||
|
|
|
@ -54,8 +54,6 @@ class EditTextWidget : public EditableWidget
|
|||
Common::Rect getEditRect() const override;
|
||||
|
||||
void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleMouseEntered() override;
|
||||
void handleMouseLeft() override;
|
||||
|
||||
protected:
|
||||
string _backupString;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "OSystem.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
#include "UndoHandler.hxx"
|
||||
#include "ToolTip.hxx"
|
||||
#include "EditableWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -63,6 +64,28 @@ void EditableWidget::setText(const string& str, bool)
|
|||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditableWidget::tick()
|
||||
{
|
||||
if(_hasFocus && isEditable() && _editMode && isVisible() && _boss->isVisible())
|
||||
{
|
||||
_caretTimer++;
|
||||
if(_caretTimer > 40) // switch every 2/3rd seconds
|
||||
{
|
||||
_caretTimer = 0;
|
||||
_caretEnabled = !_caretEnabled;
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
Widget::tick();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool EditableWidget::wantsToolTip() const
|
||||
{
|
||||
return !(_hasFocus && isEditable() && _editMode) && Widget::wantsToolTip();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditableWidget::setEditable(bool editable, bool hiliteBG)
|
||||
{
|
||||
|
@ -79,6 +102,14 @@ void EditableWidget::setEditable(bool editable, bool hiliteBG)
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditableWidget::receivedFocusWidget()
|
||||
{
|
||||
_caretTimer = 0;
|
||||
_caretEnabled = true;
|
||||
dialog().tooltip().hide();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditableWidget::lostFocusWidget()
|
||||
{
|
||||
|
@ -107,7 +138,7 @@ bool EditableWidget::handleText(char text)
|
|||
|
||||
if(tryInsertChar(text, _caretPos))
|
||||
{
|
||||
_caretPos++;
|
||||
setCaretPos(_caretPos + 1);
|
||||
sendCommand(EditableWidget::kChangedCmd, 0, _id);
|
||||
setDirty();
|
||||
return true;
|
||||
|
@ -265,7 +296,7 @@ bool EditableWidget::handleKeyDown(StellaKey key, StellaMod mod)
|
|||
{
|
||||
// Put caret at last difference
|
||||
myUndoHandler->lastDiff(_editString, oldString);
|
||||
_caretPos = myUndoHandler->lastDiff(_editString, oldString);
|
||||
setCaretPos(myUndoHandler->lastDiff(_editString, oldString));
|
||||
_selectSize = 0;
|
||||
sendCommand(EditableWidget::kChangedCmd, key, _id);
|
||||
}
|
||||
|
@ -316,22 +347,16 @@ void EditableWidget::drawCaretSelection()
|
|||
if (!_editable || !isVisible() || !_boss->isVisible() || !_hasFocus)
|
||||
return;
|
||||
|
||||
// Draw the selection
|
||||
if(_selectSize)
|
||||
{
|
||||
FBSurface& s = _boss->dialog().surface();
|
||||
const Common::Rect& editRect = getEditRect();
|
||||
int x = editRect.x();
|
||||
int y = editRect.y();
|
||||
|
||||
x += getCaretOffset();
|
||||
|
||||
x += _x;
|
||||
y += _y;
|
||||
|
||||
FBSurface& s = _boss->dialog().surface();
|
||||
s.vLine(x, y + 2, y + editRect.h() - 2, kTextColorHi);
|
||||
s.vLine(x-1, y + 2, y + editRect.h() - 2, kTextColorHi);
|
||||
|
||||
if(_selectSize)
|
||||
{
|
||||
string text = selectString();
|
||||
|
||||
x = editRect.x();
|
||||
y = editRect.y();
|
||||
int w = editRect.w();
|
||||
|
@ -355,9 +380,27 @@ void EditableWidget::drawCaretSelection()
|
|||
y += _y;
|
||||
|
||||
s.fillRect(x - 1, y + 1, w + 1, h - 3, kTextColorHi);
|
||||
s.drawString(_font, text, x, y + 1, w, h,
|
||||
s.drawString(_font, text, x, y + 1 + _dyText, w, h,
|
||||
kTextColorInv, TextAlign::Left, 0, false);
|
||||
}
|
||||
|
||||
// Draw the caret
|
||||
if(_caretEnabled ^ (_selectSize != 0))
|
||||
{
|
||||
FBSurface& s = _boss->dialog().surface();
|
||||
const Common::Rect& editRect = getEditRect();
|
||||
int x = editRect.x();
|
||||
int y = editRect.y();
|
||||
ColorId color = _caretEnabled ? kTextColorHi : kTextColorInv;
|
||||
|
||||
x += getCaretOffset();
|
||||
x += _x;
|
||||
y += _y;
|
||||
|
||||
s.vLine(x, y + 1, y + editRect.h() - 3, color);
|
||||
s.vLine(x - 1, y + 1, y + editRect.h() - 3, color);
|
||||
clearDirty();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -366,6 +409,9 @@ bool EditableWidget::setCaretPos(int newPos)
|
|||
assert(newPos >= 0 && newPos <= int(_editString.size()));
|
||||
_caretPos = newPos;
|
||||
|
||||
_caretTimer = 0;
|
||||
_caretEnabled = true;
|
||||
|
||||
return adjustOffset();
|
||||
}
|
||||
|
||||
|
@ -375,6 +421,8 @@ bool EditableWidget::moveCaretPos(int direction)
|
|||
if(setCaretPos(_caretPos + direction))
|
||||
{
|
||||
_selectSize -= direction;
|
||||
_caretTimer = 0;
|
||||
_caretEnabled = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -452,6 +500,7 @@ bool EditableWidget::killChar(int direction, bool addEdit)
|
|||
{
|
||||
myUndoHandler->endChars(_editString);
|
||||
_editString.erase(_caretPos, 1);
|
||||
setCaretPos(_caretPos);
|
||||
|
||||
if(addEdit)
|
||||
myUndoHandler->doo(_editString);
|
||||
|
@ -556,7 +605,7 @@ bool EditableWidget::moveWord(int direction, bool select)
|
|||
if(select)
|
||||
_selectSize++;
|
||||
}
|
||||
_caretPos = currentPos;
|
||||
setCaretPos(currentPos);
|
||||
handled = true;
|
||||
}
|
||||
else if(direction == +1) // move to first character of next word
|
||||
|
@ -575,7 +624,7 @@ bool EditableWidget::moveWord(int direction, bool select)
|
|||
if(select)
|
||||
_selectSize--;
|
||||
}
|
||||
_caretPos = currentPos;
|
||||
setCaretPos(currentPos);
|
||||
handled = true;
|
||||
}
|
||||
|
||||
|
@ -630,6 +679,7 @@ bool EditableWidget::killSelectedText(bool addEdit)
|
|||
_selectSize = -_selectSize;
|
||||
}
|
||||
_editString.erase(_caretPos, _selectSize);
|
||||
setCaretPos(_caretPos);
|
||||
_selectSize = 0;
|
||||
if(addEdit)
|
||||
myUndoHandler->doo(_editString);
|
||||
|
@ -689,7 +739,7 @@ bool EditableWidget::pasteSelectedText()
|
|||
|
||||
_editString.insert(_caretPos, buf.str());
|
||||
// position cursor at the end of pasted text
|
||||
_caretPos += int(buf.str().length());
|
||||
setCaretPos(_caretPos + int(buf.str().length()));
|
||||
|
||||
if(selected || !pasted.empty())
|
||||
{
|
||||
|
|
|
@ -65,7 +65,10 @@ class EditableWidget : public Widget, public CommandSender
|
|||
void setTextFilter(const TextFilter& filter) { _filter = filter; }
|
||||
|
||||
protected:
|
||||
void receivedFocusWidget() override;
|
||||
void lostFocusWidget() override;
|
||||
void tick() override;
|
||||
bool wantsToolTip() const override;
|
||||
|
||||
virtual void startEditMode() { setFlags(Widget::FLAG_WANTS_RAWDATA); }
|
||||
virtual void endEditMode() { clearFlags(Widget::FLAG_WANTS_RAWDATA); }
|
||||
|
@ -110,6 +113,8 @@ class EditableWidget : public Widget, public CommandSender
|
|||
unique_ptr<UndoHandler> myUndoHandler;
|
||||
|
||||
int _caretPos{0};
|
||||
int _caretTimer{0};
|
||||
bool _caretEnabled{true};
|
||||
|
||||
// Size of current selected text
|
||||
// 0 = no selection
|
||||
|
@ -119,6 +124,8 @@ class EditableWidget : public Widget, public CommandSender
|
|||
|
||||
protected:
|
||||
int _editScrollOffset{0};
|
||||
bool _editMode{true};
|
||||
int _dyText{0};
|
||||
|
||||
private:
|
||||
TextFilter _filter;
|
||||
|
|
|
@ -855,12 +855,12 @@ void GameInfoDialog::saveCurrentPropertiesToDisk()
|
|||
propfile /= myGameFile.getNameWithExt(".pro");
|
||||
|
||||
propfile.write(out);
|
||||
instance().frameBuffer().showMessage("Properties saved to " +
|
||||
instance().frameBuffer().showTextMessage("Properties saved to " +
|
||||
propfile.getShortPath());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
instance().frameBuffer().showMessage("Error saving properties");
|
||||
instance().frameBuffer().showTextMessage("Error saving properties");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,21 @@ class GuiObject : public CommandReceiver
|
|||
friend class Widget;
|
||||
friend class DialogContainer;
|
||||
|
||||
public:
|
||||
enum : uInt32 {
|
||||
FLAG_ENABLED = 1 << 0,
|
||||
FLAG_INVISIBLE = 1 << 1,
|
||||
FLAG_HILITED = 1 << 2,
|
||||
FLAG_BORDER = 1 << 3,
|
||||
FLAG_CLEARBG = 1 << 4,
|
||||
FLAG_TRACK_MOUSE = 1 << 5,
|
||||
FLAG_RETAIN_FOCUS = 1 << 6,
|
||||
FLAG_WANTS_TAB = 1 << 7,
|
||||
FLAG_WANTS_RAWDATA = 1 << 8,
|
||||
FLAG_NOBG = 1 << 9,
|
||||
FLAG_MOUSE_FOCUS = 1 << 10
|
||||
};
|
||||
|
||||
public:
|
||||
// The commands generated by various widgets
|
||||
enum {
|
||||
|
@ -77,7 +92,41 @@ class GuiObject : public CommandReceiver
|
|||
virtual void setHeight(int h) { _h = h; }
|
||||
|
||||
virtual bool isVisible() const = 0;
|
||||
|
||||
virtual void setDirty() = 0;
|
||||
virtual void setDirtyChain() = 0;
|
||||
void clearDirty() { _dirty = false; }
|
||||
void clearDirtyChain() { _dirtyChain = false; }
|
||||
bool isDirty() const { return _dirty; }
|
||||
bool isChainDirty() const { return _dirtyChain; }
|
||||
|
||||
// The GUI indicates if its underlying surface needs to be redrawn
|
||||
// and then re-rendered
|
||||
virtual bool needsRedraw() { return isDirty() || isChainDirty(); }
|
||||
|
||||
virtual void tick() = 0;
|
||||
|
||||
void setFlags(uInt32 flags, bool updateDirty = true)
|
||||
{
|
||||
uInt32 oldFlags = _flags;
|
||||
|
||||
_flags |= flags;
|
||||
if(updateDirty && oldFlags != _flags)
|
||||
setDirty();
|
||||
}
|
||||
void clearFlags(uInt32 flags, bool updateDirty = true)
|
||||
{
|
||||
uInt32 oldFlags = _flags;
|
||||
|
||||
_flags &= ~flags;
|
||||
if(updateDirty && oldFlags != _flags)
|
||||
setDirty();
|
||||
}
|
||||
uInt32 getFlags() const { return _flags; }
|
||||
|
||||
bool hasBorder() const { return _flags & FLAG_BORDER; }
|
||||
bool clearsBackground() const { return _flags & FLAG_CLEARBG; }
|
||||
bool hasBackground() const { return !(_flags & FLAG_NOBG); }
|
||||
|
||||
/** Add given widget(s) to the focus list */
|
||||
virtual void addFocusWidget(Widget* w) = 0;
|
||||
|
@ -96,6 +145,7 @@ class GuiObject : public CommandReceiver
|
|||
protected:
|
||||
virtual void releaseFocus() = 0;
|
||||
virtual void draw() = 0;
|
||||
virtual void drawChain() = 0;
|
||||
|
||||
private:
|
||||
OSystem& myOSystem;
|
||||
|
@ -104,6 +154,9 @@ 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};
|
||||
WidgetArray _focusList;
|
||||
|
|
|
@ -130,7 +130,7 @@ void InputTextDialog::show(uInt32 x, uInt32 y, const Common::Rect& bossRect)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void InputTextDialog::center()
|
||||
void InputTextDialog::setPosition()
|
||||
{
|
||||
if(!myEnableCenter)
|
||||
{
|
||||
|
@ -144,7 +144,7 @@ void InputTextDialog::center()
|
|||
surface().setDstPos(myXOrig, myYOrig);
|
||||
}
|
||||
else
|
||||
Dialog::center();
|
||||
Dialog::setPosition();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -58,7 +58,7 @@ class InputTextDialog : public Dialog, public CommandSender
|
|||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
|
||||
/** This dialog uses its own positioning, so we override Dialog::center() */
|
||||
void center() override;
|
||||
void setPosition() override;
|
||||
|
||||
private:
|
||||
vector<EditTextWidget*> myInput;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "StellaSettingsDialog.hxx"
|
||||
#include "WhatsNewDialog.hxx"
|
||||
#include "MessageBox.hxx"
|
||||
#include "ToolTip.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "FBSurface.hxx"
|
||||
|
@ -79,6 +80,8 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
|
|||
const string& lblAllFiles = "Show all files";
|
||||
const string& lblFound = "XXXX items found";
|
||||
|
||||
tooltip().setFont(font);
|
||||
|
||||
lwidth = font.getStringWidth(lblRom);
|
||||
lwidth2 = font.getStringWidth(lblAllFiles) + CheckboxWidget::boxSize(font);
|
||||
int lwidth3 = font.getStringWidth(lblFilter);
|
||||
|
@ -120,12 +123,14 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
|
|||
// Show the filter input field
|
||||
xpos -= fwidth + LBL_GAP;
|
||||
myPattern = new EditTextWidget(this, font, xpos, ypos - 2, fwidth, lineHeight, "");
|
||||
myPattern->setToolTip("Enter filter text to reduce file list.");
|
||||
// Show the "Filter" label
|
||||
xpos -= lwidth3 + LBL_GAP;
|
||||
new StaticTextWidget(this, font, xpos, ypos, lblFilter);
|
||||
// Show the checkbox for all files
|
||||
xpos -= lwidth2 + LBL_GAP * 3;
|
||||
myAllFiles = new CheckboxWidget(this, font, xpos, ypos, lblAllFiles, kAllfilesCmd);
|
||||
myAllFiles->setToolTip("Uncheck to show ROM files only.");
|
||||
wid.push_back(myAllFiles);
|
||||
wid.push_back(myPattern);
|
||||
}
|
||||
|
@ -178,6 +183,7 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
|
|||
#ifndef BSPF_MACOS
|
||||
myStartButton = new ButtonWidget(this, font, xpos, ypos, (buttonWidth + 0) / 4, buttonHeight,
|
||||
"Select", kLoadROMCmd);
|
||||
myStartButton->setToolTip("Start emulation of selected ROM.");
|
||||
wid.push_back(myStartButton);
|
||||
|
||||
xpos += (buttonWidth + 0) / 4 + BUTTON_GAP;
|
||||
|
@ -562,6 +568,7 @@ void LauncherDialog::handleMouseDown(int x, int y, MouseButton b, int clickCount
|
|||
// Grab right mouse button for context menu, send left to base class
|
||||
if(b == MouseButton::RIGHT)
|
||||
{
|
||||
dialog().tooltip().hide();
|
||||
// Dynamically create context menu for ROM list options
|
||||
VariantList items;
|
||||
|
||||
|
@ -662,7 +669,7 @@ void LauncherDialog::loadRom()
|
|||
instance().settings().setValue("romdir", currentNode().getParent().getShortPath());
|
||||
}
|
||||
else
|
||||
instance().frameBuffer().showMessage(result, MessagePosition::MiddleCenter, true);
|
||||
instance().frameBuffer().showTextMessage(result, MessagePosition::MiddleCenter, true);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -101,7 +101,7 @@ class LauncherDialog : public Dialog
|
|||
static constexpr int MIN_ROMINFO_ROWS = 7; // full lines
|
||||
static constexpr int MIN_ROMINFO_LINES = 4; // extra lines
|
||||
|
||||
void center() override { positionAt(0); }
|
||||
void setPosition() override { positionAt(0); }
|
||||
void handleKeyDown(StellaKey key, StellaMod mod, bool repeated) override;
|
||||
void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
|
|
|
@ -36,6 +36,8 @@ ListWidget::ListWidget(GuiObject* boss, const GUI::Font& font,
|
|||
_textcolor = kTextColor;
|
||||
_textcolorhi = kTextColor;
|
||||
|
||||
_editMode = false;
|
||||
|
||||
_cols = w / _fontWidth;
|
||||
_rows = h / _lineHeight;
|
||||
|
||||
|
|
|
@ -99,7 +99,6 @@ class ListWidget : public EditableWidget
|
|||
int _currentPos{0};
|
||||
int _selectedItem{-1};
|
||||
int _highlightedItem{-1};
|
||||
bool _editMode{false};
|
||||
bool _useScrollbar{true};
|
||||
|
||||
ScrollBarWidget* _scrollBar{nullptr};
|
||||
|
|
|
@ -123,12 +123,12 @@ void LoggerDialog::saveLogFile()
|
|||
{
|
||||
stringstream out;
|
||||
out << Logger::instance().logMessages();
|
||||
instance().frameBuffer().showMessage("Saving log file to " + node.getShortPath());
|
||||
instance().frameBuffer().showTextMessage("Saving log file to " + node.getShortPath());
|
||||
node.write(out);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
instance().frameBuffer().showMessage("Error saving log file to " + node.getShortPath());
|
||||
instance().frameBuffer().showTextMessage("Error saving log file to " + node.getShortPath());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "FBSurface.hxx"
|
||||
#include "Font.hxx"
|
||||
#include "ContextMenu.hxx"
|
||||
#include "Dialog.hxx"
|
||||
#include "ToolTip.hxx"
|
||||
#include "DialogContainer.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
|
||||
|
@ -122,6 +124,7 @@ void PopUpWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
|
|||
{
|
||||
if(isEnabled() && !myMenu->isVisible())
|
||||
{
|
||||
dialog().tooltip().hide();
|
||||
// Add menu just underneath parent widget
|
||||
myMenu->show(getAbsX() + _labelWidth, getAbsY() + getHeight(),
|
||||
dialog().surface().dstRect(), myMenu->getSelected());
|
||||
|
@ -158,20 +161,6 @@ void PopUpWidget::handleMouseWheel(int x, int y, int direction)
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void PopUpWidget::handleMouseEntered()
|
||||
{
|
||||
setFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void PopUpWidget::handleMouseLeft()
|
||||
{
|
||||
clearFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool PopUpWidget::handleEvent(Event::Type e)
|
||||
{
|
||||
|
@ -277,7 +266,7 @@ void PopUpWidget::drawWidget(bool hilite)
|
|||
|
||||
// Fill the background
|
||||
ColorId bgCol = isEditable() ? kWidColor : kDlgColor;
|
||||
s.fillRect(x + 1, _y + 1, w - (_arrowWidth * 2 - 0), _h - 2,
|
||||
s.fillRect(x + 1, _y + 1, w - (_arrowWidth * 2 - 1), _h - 2,
|
||||
onTop ? _changed ? kDbgChangedColor : bgCol : kDlgColor);
|
||||
s.fillRect(x + w - (_arrowWidth * 2 - 2), _y + 1, (_arrowWidth * 2 - 3), _h - 2,
|
||||
onTop ? isEnabled() && hilite ? kBtnColorHi : bgCol : kBGColorLo);
|
||||
|
|
|
@ -70,8 +70,6 @@ class PopUpWidget : public EditableWidget
|
|||
protected:
|
||||
void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleMouseWheel(int x, int y, int direction) override;
|
||||
void handleMouseEntered() override;
|
||||
void handleMouseLeft() override;
|
||||
bool handleEvent(Event::Type e) override;
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
|
||||
|
|
|
@ -172,6 +172,8 @@ void RomInfoWidget::parseProperties(const FilesystemNode& node)
|
|||
myRomInfo.push_back("Controllers: " + (left + " (left), " + right + " (right)"));
|
||||
if (bsDetected != "")
|
||||
myRomInfo.push_back("Type: " + Bankswitch::typeToDesc(Bankswitch::nameToType(bsDetected)));
|
||||
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -227,4 +229,5 @@ void RomInfoWidget::drawWidget(bool hilite)
|
|||
onTop ? _textcolor : _shadowcolor);
|
||||
ypos += _font.getLineHeight() + (lines - 1) * _font.getFontHeight();
|
||||
}
|
||||
clearDirty();
|
||||
}
|
||||
|
|
|
@ -240,19 +240,11 @@ void ScrollBarWidget::checkBounds(int old_pos)
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ScrollBarWidget::handleMouseEntered()
|
||||
{
|
||||
setFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ScrollBarWidget::handleMouseLeft()
|
||||
{
|
||||
_part = Part::None;
|
||||
clearFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
Widget::handleMouseLeft();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -315,6 +307,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();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -49,7 +49,6 @@ class ScrollBarWidget : public Widget, public CommandSender
|
|||
void handleMouseUp(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleMouseMoved(int x, int y) override;
|
||||
bool handleMouseClicks(int x, int y, MouseButton b) override;
|
||||
void handleMouseEntered() override;
|
||||
void handleMouseLeft() override;
|
||||
void setArrows();
|
||||
|
||||
|
|
|
@ -268,6 +268,7 @@ void StellaSettingsDialog::saveConfig()
|
|||
settings.setValue("uipalette",
|
||||
myThemePopup->getSelectedTag().toString());
|
||||
instance().frameBuffer().setUIPalette();
|
||||
instance().frameBuffer().update(FrameBuffer::UpdateMode::REDRAW);
|
||||
|
||||
// Dialog position
|
||||
settings.setValue("dialogpos", myPositionPopup->getSelectedTag().toString());
|
||||
|
|
|
@ -51,17 +51,44 @@ void StringListWidget::setList(const StringList& list)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void StringListWidget::handleMouseEntered()
|
||||
int StringListWidget::getToolTipIndex(const Common::Point& pos) const
|
||||
{
|
||||
setFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
int idx = (pos.y - getAbsY()) / _lineHeight + _currentPos;
|
||||
|
||||
if(idx >= int(_list.size()))
|
||||
return -1;
|
||||
else
|
||||
return idx;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void StringListWidget::handleMouseLeft()
|
||||
string StringListWidget::getToolTip(const Common::Point& pos) const
|
||||
{
|
||||
clearFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
Common::Rect rect = getEditRect();
|
||||
int idx = getToolTipIndex(pos);
|
||||
|
||||
if(idx < 0)
|
||||
return EmptyString;
|
||||
|
||||
const string value = _list[idx];
|
||||
|
||||
if(uInt32(_font.getStringWidth(value)) > rect.w())
|
||||
return _toolTipText + value;
|
||||
else
|
||||
return _toolTipText;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool StringListWidget::changedToolTip(const Common::Point& oldPos,
|
||||
const Common::Point& newPos) const
|
||||
{
|
||||
bool ch = getToolTipIndex(oldPos) != getToolTipIndex(newPos)
|
||||
&& getToolTip(oldPos) != getToolTip(newPos);
|
||||
|
||||
if(ch)
|
||||
cerr << "changed" << endl;
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -32,9 +32,16 @@ class StringListWidget : public ListWidget
|
|||
void setList(const StringList& list);
|
||||
bool wantsFocus() const override { return true; }
|
||||
|
||||
string getToolTip(const Common::Point& pos) const override;
|
||||
bool changedToolTip(const Common::Point& oldPos, const Common::Point& newPos) const override;
|
||||
|
||||
protected:
|
||||
void handleMouseEntered() override;
|
||||
void handleMouseLeft() override;
|
||||
// display depends on _hasFocus so we have to redraw when focus changes
|
||||
void receivedFocusWidget() override { setDirty(); }
|
||||
void lostFocusWidget() override { setDirty(); }
|
||||
|
||||
bool hasToolTip() const override { return true; }
|
||||
|
||||
void drawWidget(bool hilite) override;
|
||||
Common::Rect getEditRect() const override;
|
||||
|
||||
|
@ -42,6 +49,9 @@ class StringListWidget : public ListWidget
|
|||
bool _hilite{false};
|
||||
int _textOfs{0};
|
||||
|
||||
private:
|
||||
int getToolTipIndex(const Common::Point& pos) const;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
StringListWidget() = delete;
|
||||
|
|
|
@ -213,20 +213,6 @@ void TabWidget::handleMouseDown(int x, int y, MouseButton b, int clickCount)
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TabWidget::handleMouseEntered()
|
||||
{
|
||||
setFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TabWidget::handleMouseLeft()
|
||||
{
|
||||
clearFlags(Widget::FLAG_HILITED);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TabWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
||||
{
|
||||
|
@ -275,17 +261,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 +295,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);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -63,8 +63,8 @@ class TabWidget : public Widget, public CommandSender
|
|||
|
||||
protected:
|
||||
void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleMouseEntered() override;
|
||||
void handleMouseLeft() override;
|
||||
void handleMouseEntered() override {}
|
||||
void handleMouseLeft() override {}
|
||||
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||
bool handleEvent(Event::Type event) override;
|
||||
|
|
|
@ -35,7 +35,9 @@ TimeLineWidget::TimeLineWidget(GuiObject* boss, const GUI::Font& font,
|
|||
: ButtonWidget(boss, font, x, y, w, h, label, cmd),
|
||||
_labelWidth(labelWidth)
|
||||
{
|
||||
_flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE;
|
||||
_flags = Widget::FLAG_ENABLED | Widget::FLAG_TRACK_MOUSE
|
||||
| Widget::FLAG_CLEARBG | Widget::FLAG_NOBG;
|
||||
|
||||
_bgcolor = kDlgColor;
|
||||
_bgcolorhi = kDlgColor;
|
||||
|
||||
|
@ -84,7 +86,7 @@ void TimeLineWidget::setStepValues(const IntArray& steps)
|
|||
if(steps.size() > _stepValue.capacity())
|
||||
_stepValue.reserve(2 * steps.size());
|
||||
|
||||
double scale = (_w - _labelWidth - 2 - HANDLE_W*0) / double(steps.back());
|
||||
double scale = (_w - _labelWidth - 2 - HANDLE_W) / double(steps.back());
|
||||
|
||||
// Skip the very last value; we take care of it outside the end of the loop
|
||||
for(uInt32 i = 0; i < steps.size() - 1; ++i)
|
||||
|
@ -92,7 +94,7 @@ void TimeLineWidget::setStepValues(const IntArray& steps)
|
|||
|
||||
// Due to integer <-> double conversion, the last value is sometimes
|
||||
// slightly less than the maximum value; we assign it manually to fix this
|
||||
_stepValue.push_back(_w - _labelWidth - 2 - HANDLE_W*0);
|
||||
_stepValue.push_back(_w - _labelWidth - 2 - HANDLE_W);
|
||||
}
|
||||
else
|
||||
_stepValue.push_back(0);
|
||||
|
@ -141,17 +143,18 @@ void TimeLineWidget::drawWidget(bool hilite)
|
|||
{
|
||||
FBSurface& s = _boss->dialog().surface();
|
||||
|
||||
cerr << "TimeLineWidget::drawWidget " << typeid(s).name() << endl;
|
||||
|
||||
// Draw the label, if any
|
||||
if(_labelWidth > 0)
|
||||
s.drawString(_font, _label, _x, _y + 2, _labelWidth,
|
||||
isEnabled() ? kTextColor : kColor, TextAlign::Left);
|
||||
|
||||
int p = valueToPos(_value),
|
||||
x = _x + _labelWidth,
|
||||
w = _w - _labelWidth;
|
||||
|
||||
// Frame the handle
|
||||
const int HANDLE_W2 = (HANDLE_W + 1) / 2;
|
||||
int p = valueToPos(_value),
|
||||
x = _x + _labelWidth + HANDLE_W2,
|
||||
w = _w - _labelWidth - HANDLE_W;
|
||||
s.hLine(x + p - HANDLE_W2, _y + 0, x + p - HANDLE_W2 + HANDLE_W, kColorInfo);
|
||||
s.vLine(x + p - HANDLE_W2, _y + 1, _y + _h - 2, kColorInfo);
|
||||
s.hLine(x + p - HANDLE_W2 + 1, _y + _h - 1, x + p - HANDLE_W2 + 1 + HANDLE_W, kBGColor);
|
||||
|
|
|
@ -218,6 +218,7 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
|||
|
||||
this->clearFlags(Widget::FLAG_CLEARBG); // does only work combined with blending (0..100)!
|
||||
this->clearFlags(Widget::FLAG_BORDER);
|
||||
this->setFlags(Widget::FLAG_NOBG);
|
||||
|
||||
xpos = H_BORDER;
|
||||
ypos = V_BORDER;
|
||||
|
@ -225,8 +226,10 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
|||
// Add index info
|
||||
myCurrentIdxWidget = new StaticTextWidget(this, font, xpos, ypos, "1000", TextAlign::Left, kBGColor);
|
||||
myCurrentIdxWidget->setTextColor(kColorInfo);
|
||||
myCurrentIdxWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG);
|
||||
myLastIdxWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("1000"), ypos,
|
||||
"1000", TextAlign::Right, kBGColor);
|
||||
myLastIdxWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG);
|
||||
myLastIdxWidget->setTextColor(kColorInfo);
|
||||
|
||||
// Add timeline
|
||||
|
@ -241,9 +244,11 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
|||
// Add time info
|
||||
int ypos_s = ypos + (buttonHeight - font.getFontHeight() + 1) / 2; // align to button vertical center
|
||||
myCurrentTimeWidget = new StaticTextWidget(this, font, xpos, ypos_s, "00:00.00", TextAlign::Left, kBGColor);
|
||||
myCurrentTimeWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG);
|
||||
myCurrentTimeWidget->setTextColor(kColorInfo);
|
||||
myLastTimeWidget = new StaticTextWidget(this, font, _w - H_BORDER - font.getStringWidth("00:00.00"), ypos_s,
|
||||
"00:00.00", TextAlign::Right, kBGColor);
|
||||
myLastTimeWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG);
|
||||
myLastTimeWidget->setTextColor(kColorInfo);
|
||||
xpos = myCurrentTimeWidget->getRight() + BUTTON_GAP * 4;
|
||||
|
||||
|
@ -287,11 +292,12 @@ TimeMachineDialog::TimeMachineDialog(OSystem& osystem, DialogContainer& parent,
|
|||
// Add message
|
||||
myMessageWidget = new StaticTextWidget(this, font, xpos, ypos_s,
|
||||
" ", TextAlign::Left, kBGColor);
|
||||
myMessageWidget->setFlags(Widget::FLAG_CLEARBG | Widget::FLAG_NOBG);
|
||||
myMessageWidget->setTextColor(kColorInfo);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TimeMachineDialog::center()
|
||||
void TimeMachineDialog::setPosition()
|
||||
{
|
||||
// Place on the bottom of the screen, centered horizontally
|
||||
const Common::Size& screen = instance().frameBuffer().screenSize();
|
||||
|
@ -434,11 +440,11 @@ void TimeMachineDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
break;
|
||||
|
||||
case kSaveAll:
|
||||
instance().frameBuffer().showMessage(instance().state().rewindManager().saveAllStates());
|
||||
instance().frameBuffer().showTextMessage(instance().state().rewindManager().saveAllStates());
|
||||
break;
|
||||
|
||||
case kLoadAll:
|
||||
instance().frameBuffer().showMessage(instance().state().rewindManager().loadAllStates());
|
||||
instance().frameBuffer().showTextMessage(instance().state().rewindManager().loadAllStates());
|
||||
initBar();
|
||||
break;
|
||||
|
||||
|
|
|
@ -44,8 +44,8 @@ class TimeMachineDialog : public Dialog
|
|||
/** initialize timeline bar */
|
||||
void initBar();
|
||||
|
||||
/** This dialog uses its own positioning, so we override Dialog::center() */
|
||||
void center() override;
|
||||
/** This dialog uses its own positioning, so we override Dialog::setPosition() */
|
||||
void setPosition() override;
|
||||
|
||||
/** convert cycles into time */
|
||||
string getTimeString(uInt64 cycles);
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "OSystem.hxx"
|
||||
#include "Dialog.hxx"
|
||||
#include "DialogContainer.hxx"
|
||||
#include "Font.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "FBSurface.hxx"
|
||||
#include "Widget.hxx"
|
||||
|
||||
#include "ToolTip.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
ToolTip::ToolTip(Dialog& dialog, const GUI::Font& font)
|
||||
: myDialog(dialog)
|
||||
{
|
||||
myScale = myDialog.instance().frameBuffer().hidpiScaleFactor();
|
||||
|
||||
setFont(font);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ToolTip::setFont(const GUI::Font& font)
|
||||
{
|
||||
myFont = &font;
|
||||
const int fontWidth = font.getMaxCharWidth(),
|
||||
fontHeight = font.getFontHeight();
|
||||
|
||||
myTextXOfs = fontHeight < 24 ? 5 : 8;
|
||||
myTextYOfs = fontHeight < 24 ? 2 : 3;
|
||||
myWidth = fontWidth * MAX_COLUMNS + myTextXOfs * 2;
|
||||
myHeight = fontHeight * MAX_ROWS + myTextYOfs * 2;
|
||||
|
||||
mySurface = myDialog.instance().frameBuffer().allocateSurface(myWidth, myHeight);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ToolTip::request()
|
||||
{
|
||||
// Called each frame when a tooltip is wanted
|
||||
if(myFocusWidget && myTimer < DELAY_TIME * RELEASE_SPEED)
|
||||
{
|
||||
const string tip = myFocusWidget->getToolTip(myMousePos);
|
||||
|
||||
if(!tip.empty())
|
||||
{
|
||||
myTipWidget = myFocusWidget;
|
||||
myTimer += RELEASE_SPEED;
|
||||
if(myTimer >= DELAY_TIME * RELEASE_SPEED)
|
||||
show(tip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ToolTip::update(const Widget* widget, const Common::Point& pos)
|
||||
{
|
||||
// Called each mouse move
|
||||
myMousePos = pos;
|
||||
myFocusWidget = widget;
|
||||
|
||||
if(myTipWidget != widget)
|
||||
release(false);
|
||||
|
||||
if(!myTipShown)
|
||||
release(true);
|
||||
else
|
||||
{
|
||||
if(myTipWidget->changedToolTip(myTipPos, myMousePos))
|
||||
{
|
||||
const string tip = myTipWidget->getToolTip(myMousePos);
|
||||
|
||||
if(!tip.empty())
|
||||
show(tip);
|
||||
else
|
||||
release(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ToolTip::hide()
|
||||
{
|
||||
if(myTipShown)
|
||||
{
|
||||
myTimer = 0;
|
||||
myTipWidget = myFocusWidget = nullptr;
|
||||
myTipShown = false;
|
||||
myDialog.instance().frameBuffer().setPendingRender();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ToolTip::release(bool emptyTip)
|
||||
{
|
||||
if(myTipShown)
|
||||
{
|
||||
myTipShown = false;
|
||||
myDialog.instance().frameBuffer().setPendingRender();
|
||||
}
|
||||
|
||||
// After displaying a tip, slowly reset the timer to 0
|
||||
// until a new tip is requested
|
||||
if((emptyTip || myTipWidget != myFocusWidget) && myTimer)
|
||||
myTimer--;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ToolTip::show(const string& tip)
|
||||
{
|
||||
myTipPos = myMousePos;
|
||||
|
||||
uInt32 maxWidth = std::min(myWidth - myTextXOfs * 2, uInt32(myFont->getStringWidth(tip)));
|
||||
|
||||
mySurface->fillRect(1, 1, maxWidth + myTextXOfs * 2 - 2, myHeight - 2, kWidColor);
|
||||
int lines = std::min(MAX_ROWS,
|
||||
uInt32(mySurface->drawString(*myFont, tip, myTextXOfs, myTextYOfs,
|
||||
maxWidth, myHeight - myTextYOfs * 2,
|
||||
kTextColor)));
|
||||
// Calculate maximum width of drawn string lines
|
||||
uInt32 width = 0;
|
||||
string inStr = tip;
|
||||
for(int i = 0; i < lines; ++i)
|
||||
{
|
||||
string leftStr, rightStr;
|
||||
|
||||
mySurface->splitString(*myFont, inStr, maxWidth, leftStr, rightStr);
|
||||
width = std::max(width, uInt32(myFont->getStringWidth(leftStr)));
|
||||
inStr = rightStr;
|
||||
}
|
||||
width += myTextXOfs * 2;
|
||||
|
||||
// Calculate and set surface size and position
|
||||
const uInt32 height = std::min(myHeight, myFont->getFontHeight() * lines + myTextYOfs * 2);
|
||||
const uInt32 V_GAP = 1;
|
||||
const uInt32 H_CURSOR = 18;
|
||||
// Note: The rects include HiDPI scaling
|
||||
const Common::Rect imageRect = myDialog.instance().frameBuffer().imageRect();
|
||||
const Common::Rect dialogRect = myDialog.surface().dstRect();
|
||||
// Limit position to app size and adjust accordingly
|
||||
const Int32 xAbs = myTipPos.x + dialogRect.x() / myScale;
|
||||
const uInt32 yAbs = myTipPos.y + dialogRect.y() / myScale;
|
||||
Int32 x = std::min(xAbs, Int32(imageRect.w() / myScale - width));
|
||||
const uInt32 y = (yAbs + height + H_CURSOR > imageRect.h() / myScale)
|
||||
? yAbs - height - V_GAP
|
||||
: yAbs + H_CURSOR / myScale + V_GAP;
|
||||
|
||||
if(x < 0)
|
||||
{
|
||||
x = 0;
|
||||
width = std::min(width, imageRect.w() / myScale);
|
||||
}
|
||||
|
||||
mySurface->setSrcSize(width, height);
|
||||
mySurface->setDstSize(width * myScale, height * myScale);
|
||||
mySurface->setDstPos(x * myScale, y * myScale);
|
||||
mySurface->frameRect(0, 0, width, height, kColor);
|
||||
|
||||
myTipShown = true;
|
||||
myDialog.instance().frameBuffer().setPendingRender();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ToolTip::render()
|
||||
{
|
||||
if(myTipShown)
|
||||
mySurface->render(), cerr << " render tooltip" << endl;
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#ifndef TOOL_TIP_HXX
|
||||
#define TOOL_TIP_HXX
|
||||
|
||||
/**
|
||||
* Class for providing tooltip functionality
|
||||
*
|
||||
* @author Thomas Jentzsch
|
||||
*/
|
||||
|
||||
class OSystem;
|
||||
class Dialog;
|
||||
class Widget;
|
||||
class FBSurface;
|
||||
|
||||
#include "Rect.hxx"
|
||||
|
||||
class ToolTip
|
||||
{
|
||||
private:
|
||||
static constexpr uInt32 MAX_COLUMNS = 60;
|
||||
static constexpr uInt32 MAX_ROWS = 5;
|
||||
|
||||
public:
|
||||
// Maximum tooltip length
|
||||
static constexpr uInt32 MAX_LEN = MAX_COLUMNS * MAX_ROWS;
|
||||
|
||||
ToolTip(Dialog& dialog, const GUI::Font& font);
|
||||
~ToolTip() = default;
|
||||
|
||||
void setFont(const GUI::Font& font);
|
||||
|
||||
/**
|
||||
Request a tooltip display.
|
||||
*/
|
||||
void request();
|
||||
|
||||
/**
|
||||
Hide a displayed tooltip and reset the timer.
|
||||
*/
|
||||
void hide();
|
||||
|
||||
/**
|
||||
Hide a displayed tooltip and reset the timer slowly.
|
||||
This allows faster tip display of the next tip.
|
||||
*/
|
||||
void release(bool emptyTip);
|
||||
|
||||
/**
|
||||
Update focused widget and current mouse position.
|
||||
*/
|
||||
void update(const Widget* widget, const Common::Point& pos);
|
||||
|
||||
/*
|
||||
Render the tooltip
|
||||
*/
|
||||
void render();
|
||||
|
||||
private:
|
||||
void show(const string& tip);
|
||||
|
||||
private:
|
||||
static constexpr uInt32 DELAY_TIME = 45; // display delay [frames]
|
||||
// Tips are slower released than requested, so that repeated tips are shown
|
||||
// faster. This constant defines how much faster.
|
||||
static constexpr uInt32 RELEASE_SPEED = 2;
|
||||
|
||||
Dialog& myDialog;
|
||||
const GUI::Font* myFont{nullptr};
|
||||
const Widget* myTipWidget{nullptr};
|
||||
const Widget* myFocusWidget{nullptr};
|
||||
|
||||
uInt32 myTimer{0};
|
||||
Common::Point myMousePos;
|
||||
Common::Point myTipPos;
|
||||
uInt32 myWidth{0};
|
||||
uInt32 myHeight{0};
|
||||
uInt32 myTextXOfs{0};
|
||||
uInt32 myTextYOfs{0};
|
||||
bool myTipShown{false};
|
||||
uInt32 myScale{1};
|
||||
shared_ptr<FBSurface> mySurface;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -441,6 +441,7 @@ void UIDialog::saveConfig()
|
|||
settings.setValue("uipalette",
|
||||
myPalettePopup->getSelectedTag().toString());
|
||||
instance().frameBuffer().setUIPalette();
|
||||
instance().frameBuffer().update(FrameBuffer::UpdateMode::REDRAW);
|
||||
|
||||
// Dialog font
|
||||
settings.setValue("dialogfont",
|
||||
|
|
|
@ -122,12 +122,14 @@ void VideoAudioDialog::addDisplayTab()
|
|||
myRenderer = new PopUpWidget(myTab, _font, xpos, ypos, pwidth, lineHeight,
|
||||
instance().frameBuffer().supportedRenderers(),
|
||||
"Renderer ", lwidth);
|
||||
myRenderer->setToolTip("Select renderer used for displaying screen.");
|
||||
wid.push_back(myRenderer);
|
||||
const int swidth = myRenderer->getWidth() - lwidth;
|
||||
ypos += lineHeight + VGAP;
|
||||
|
||||
// TIA interpolation
|
||||
myTIAInterpolate = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Interpolation ");
|
||||
myTIAInterpolate->setToolTip("Blur emulated display.");
|
||||
wid.push_back(myTIAInterpolate);
|
||||
|
||||
ypos += lineHeight + VGAP * 4;
|
||||
|
@ -145,12 +147,14 @@ void VideoAudioDialog::addDisplayTab()
|
|||
|
||||
// FS stretch
|
||||
myUseStretch = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Stretch");
|
||||
myUseStretch->setToolTip("Stretch emulated display to fill whole screen.");
|
||||
wid.push_back(myUseStretch);
|
||||
|
||||
#ifdef ADAPTABLE_REFRESH_SUPPORT
|
||||
// Adapt refresh rate
|
||||
ypos += lineHeight + VGAP;
|
||||
myRefreshAdapt = new CheckboxWidget(myTab, _font, xpos + INDENT, ypos + 1, "Adapt display refresh rate");
|
||||
myRefreshAdapt->setToolTip("Select optimal display refresh rate for each ROM.");
|
||||
wid.push_back(myRefreshAdapt);
|
||||
#else
|
||||
myRefreshAdapt = nullptr;
|
||||
|
@ -167,6 +171,7 @@ void VideoAudioDialog::addDisplayTab()
|
|||
// Aspect ratio correction
|
||||
ypos += lineHeight + VGAP * 4;
|
||||
myCorrectAspect = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Correct aspect ratio (*)");
|
||||
myCorrectAspect->setToolTip("Uncheck to disable real world aspect ratio correction.");
|
||||
wid.push_back(myCorrectAspect);
|
||||
|
||||
// Vertical size
|
||||
|
@ -176,6 +181,7 @@ void VideoAudioDialog::addDisplayTab()
|
|||
"V-Size adjust", lwidth, kVSizeChanged, fontWidth * 7, "%", 0, true);
|
||||
myVSizeAdjust->setMinValue(-5); myVSizeAdjust->setMaxValue(5);
|
||||
myVSizeAdjust->setTickmarkIntervals(2);
|
||||
myVSizeAdjust->setToolTip("Adjust vertical size to match emulated TV display.");
|
||||
wid.push_back(myVSizeAdjust);
|
||||
|
||||
|
||||
|
@ -231,6 +237,7 @@ void VideoAudioDialog::addPaletteTab()
|
|||
myPhaseShiftNtsc->setMinValue((PaletteHandler::DEF_NTSC_SHIFT - PaletteHandler::MAX_PHASE_SHIFT) * 10);
|
||||
myPhaseShiftNtsc->setMaxValue((PaletteHandler::DEF_NTSC_SHIFT + PaletteHandler::MAX_PHASE_SHIFT) * 10);
|
||||
myPhaseShiftNtsc->setTickmarkIntervals(4);
|
||||
myPhaseShiftNtsc->setToolTip("Adjust NTSC phase shift of 'Custom' palette.");
|
||||
wid.push_back(myPhaseShiftNtsc);
|
||||
ypos += lineHeight + VGAP;
|
||||
|
||||
|
@ -240,6 +247,7 @@ void VideoAudioDialog::addPaletteTab()
|
|||
myPhaseShiftPal->setMinValue((PaletteHandler::DEF_PAL_SHIFT - PaletteHandler::MAX_PHASE_SHIFT) * 10);
|
||||
myPhaseShiftPal->setMaxValue((PaletteHandler::DEF_PAL_SHIFT + PaletteHandler::MAX_PHASE_SHIFT) * 10);
|
||||
myPhaseShiftPal->setTickmarkIntervals(4);
|
||||
myPhaseShiftPal->setToolTip("Adjust PAL phase shift of 'Custom' palette.");
|
||||
wid.push_back(myPhaseShiftPal);
|
||||
ypos += lineHeight + VGAP;
|
||||
|
||||
|
@ -252,6 +260,7 @@ void VideoAudioDialog::addPaletteTab()
|
|||
myTVRedScale->setMinValue(0);
|
||||
myTVRedScale->setMaxValue(100);
|
||||
myTVRedScale->setTickmarkIntervals(2);
|
||||
myTVRedScale->setToolTip("Adjust red saturation of 'Custom' palette.");
|
||||
wid.push_back(myTVRedScale);
|
||||
|
||||
const int xposr = myTIAPalette->getRight() - rgbsWidth;
|
||||
|
@ -261,6 +270,7 @@ void VideoAudioDialog::addPaletteTab()
|
|||
myTVRedShift->setMinValue((PaletteHandler::DEF_RGB_SHIFT - PaletteHandler::MAX_RGB_SHIFT) * 10);
|
||||
myTVRedShift->setMaxValue((PaletteHandler::DEF_RGB_SHIFT + PaletteHandler::MAX_RGB_SHIFT) * 10);
|
||||
myTVRedShift->setTickmarkIntervals(2);
|
||||
myTVRedShift->setToolTip("Adjust red shift of 'Custom' palette.");
|
||||
wid.push_back(myTVRedShift);
|
||||
ypos += lineHeight + VGAP;
|
||||
|
||||
|
@ -270,6 +280,7 @@ void VideoAudioDialog::addPaletteTab()
|
|||
myTVGreenScale->setMinValue(0);
|
||||
myTVGreenScale->setMaxValue(100);
|
||||
myTVGreenScale->setTickmarkIntervals(2);
|
||||
myTVGreenScale->setToolTip("Adjust green saturation of 'Custom' palette.");
|
||||
wid.push_back(myTVGreenScale);
|
||||
|
||||
myTVGreenShift =
|
||||
|
@ -278,6 +289,7 @@ void VideoAudioDialog::addPaletteTab()
|
|||
myTVGreenShift->setMinValue((PaletteHandler::DEF_RGB_SHIFT - PaletteHandler::MAX_RGB_SHIFT) * 10);
|
||||
myTVGreenShift->setMaxValue((PaletteHandler::DEF_RGB_SHIFT + PaletteHandler::MAX_RGB_SHIFT) * 10);
|
||||
myTVGreenShift->setTickmarkIntervals(2);
|
||||
myTVGreenShift->setToolTip("Adjust green shift of 'Custom' palette.");
|
||||
wid.push_back(myTVGreenShift);
|
||||
ypos += lineHeight + VGAP;
|
||||
|
||||
|
@ -287,6 +299,7 @@ void VideoAudioDialog::addPaletteTab()
|
|||
myTVBlueScale->setMinValue(0);
|
||||
myTVBlueScale->setMaxValue(100);
|
||||
myTVBlueScale->setTickmarkIntervals(2);
|
||||
myTVBlueScale->setToolTip("Adjust blue saturation of 'Custom' palette.");
|
||||
wid.push_back(myTVBlueScale);
|
||||
|
||||
myTVBlueShift =
|
||||
|
@ -295,6 +308,7 @@ void VideoAudioDialog::addPaletteTab()
|
|||
myTVBlueShift->setMinValue((PaletteHandler::DEF_RGB_SHIFT - PaletteHandler::MAX_RGB_SHIFT) * 10);
|
||||
myTVBlueShift->setMaxValue((PaletteHandler::DEF_RGB_SHIFT + PaletteHandler::MAX_RGB_SHIFT) * 10);
|
||||
myTVBlueShift->setTickmarkIntervals(2);
|
||||
myTVBlueShift->setToolTip("Adjust blue shift of 'Custom' palette.");
|
||||
wid.push_back(myTVBlueShift);
|
||||
ypos += lineHeight + VGAP;
|
||||
xpos -= INDENT;
|
||||
|
@ -959,7 +973,16 @@ void VideoAudioDialog::handlePaletteUpdate()
|
|||
instance().frameBuffer().tiaSurface().paletteHandler().setAdjustables(paletteAdj);
|
||||
|
||||
if(instance().hasConsole())
|
||||
{
|
||||
instance().frameBuffer().tiaSurface().paletteHandler().setPalette();
|
||||
|
||||
constexpr int NUM_LUMA = 8;
|
||||
constexpr int NUM_CHROMA = 16;
|
||||
|
||||
for(int idx = 0; idx < NUM_CHROMA; ++idx)
|
||||
for(int lum = 0; lum < NUM_LUMA; ++lum)
|
||||
myColor[idx][lum]->setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -1157,10 +1180,11 @@ void VideoAudioDialog::addPalette(int x, int y, int w, int h)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void VideoAudioDialog::colorPalette()
|
||||
{
|
||||
if(instance().hasConsole())
|
||||
{
|
||||
constexpr int NUM_LUMA = 8;
|
||||
constexpr int NUM_CHROMA = 16;
|
||||
|
||||
if(instance().hasConsole())
|
||||
{
|
||||
const int order[2][NUM_CHROMA] =
|
||||
{
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
|
@ -1176,11 +1200,14 @@ void VideoAudioDialog::colorPalette()
|
|||
ss << Common::Base::HEX1 << std::uppercase << color;
|
||||
myColorLbl[idx]->setLabel(ss.str());
|
||||
for(int lum = 0; lum < NUM_LUMA; ++lum)
|
||||
{
|
||||
myColor[idx][lum]->setColor(color * NUM_CHROMA + lum * 2); // skip grayscale colors
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
// disable palette
|
||||
for(int idx = 0; idx < NUM_CHROMA; ++idx)
|
||||
for(int lum = 0; lum < NUM_LUMA; ++lum)
|
||||
myColor[idx][lum]->setEnabled(false);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "bspf.hxx"
|
||||
#include "Command.hxx"
|
||||
#include "Dialog.hxx"
|
||||
#include "ToolTip.hxx"
|
||||
#include "FBSurface.hxx"
|
||||
#include "GuiObject.hxx"
|
||||
#include "OSystem.hxx"
|
||||
|
@ -54,9 +55,38 @@ Widget::~Widget()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Widget::setDirty()
|
||||
{
|
||||
// A widget being dirty indicates that its parent dialog is dirty
|
||||
// So we inform the parent about it
|
||||
_boss->dialog().setDirty();
|
||||
_dirty = true;
|
||||
|
||||
// Inform the parent object that its children chain is dirty
|
||||
_boss->setDirtyChain();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Widget::setDirtyChain()
|
||||
{
|
||||
_dirtyChain = true;
|
||||
|
||||
// Inform the parent object that its children chain is dirty
|
||||
_boss->setDirtyChain();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Widget::tick()
|
||||
{
|
||||
if(isEnabled())
|
||||
{
|
||||
if(wantsToolTip())
|
||||
dialog().tooltip().request();
|
||||
|
||||
// Recursively tick widget and all child dialogs and widgets
|
||||
Widget* w = _firstWidget;
|
||||
|
||||
while(w)
|
||||
{
|
||||
w->tick();
|
||||
w = w->_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -65,11 +95,14 @@ void Widget::draw()
|
|||
if(!isVisible() || !_boss->isVisible())
|
||||
return;
|
||||
|
||||
if(isDirty())
|
||||
{
|
||||
cerr << " *** draw widget " << typeid(*this).name() << " ***" << endl;
|
||||
//cerr << "w";
|
||||
|
||||
FBSurface& s = _boss->dialog().surface();
|
||||
|
||||
bool onTop = _boss->dialog().isOnTop();
|
||||
|
||||
bool hasBorder = _flags & Widget::FLAG_BORDER; // currently only used by Dialog widget
|
||||
int oldX = _x, oldY = _y;
|
||||
|
||||
// Account for our relative position in the dialog
|
||||
|
@ -77,20 +110,29 @@ void Widget::draw()
|
|||
_y = getAbsY();
|
||||
|
||||
// Clear background (unless alpha blending is enabled)
|
||||
if(_flags & Widget::FLAG_CLEARBG)
|
||||
if(clearsBackground())
|
||||
{
|
||||
int x = _x, y = _y, w = _w, h = _h;
|
||||
if(hasBorder)
|
||||
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);
|
||||
if(hasBackground())
|
||||
s.fillRect(x, y, w, h, !onTop
|
||||
? _bgcolorlo
|
||||
: (_flags & Widget::FLAG_HILITED) && isEnabled()
|
||||
? _bgcolorhi : _bgcolor);
|
||||
else
|
||||
s.invalidateRect(x, y, w, h);
|
||||
}
|
||||
|
||||
// Draw border
|
||||
if(hasBorder)
|
||||
if(hasBorder())
|
||||
{
|
||||
s.frameRect(_x, _y, _w, _h, !onTop ? kColor : (_flags & Widget::FLAG_HILITED) && isEnabled() ? kWidColorHi : kColor);
|
||||
s.frameRect(_x, _y, _w, _h, !onTop
|
||||
? kColor
|
||||
: (_flags & Widget::FLAG_HILITED) && isEnabled()
|
||||
? kWidColorHi : kColor);
|
||||
_x += 4;
|
||||
_y += 4;
|
||||
_w -= 8;
|
||||
|
@ -101,7 +143,7 @@ void Widget::draw()
|
|||
drawWidget((_flags & Widget::FLAG_HILITED) ? true : false);
|
||||
|
||||
// Restore x/y
|
||||
if (hasBorder)
|
||||
if(hasBorder())
|
||||
{
|
||||
_x -= 4;
|
||||
_y -= 4;
|
||||
|
@ -111,16 +153,44 @@ void Widget::draw()
|
|||
|
||||
_x = oldX;
|
||||
_y = oldY;
|
||||
}
|
||||
clearDirty();
|
||||
|
||||
// Draw all children
|
||||
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;
|
||||
|
||||
while(w)
|
||||
{
|
||||
if(w->needsRedraw())
|
||||
w->draw();
|
||||
w = w->_next;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Widget::handleMouseEntered()
|
||||
{
|
||||
if(isEnabled())
|
||||
setFlags(Widget::FLAG_HILITED | Widget::FLAG_MOUSE_FOCUS);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Widget::handleMouseLeft()
|
||||
{
|
||||
if(isEnabled())
|
||||
clearFlags(Widget::FLAG_HILITED | Widget::FLAG_MOUSE_FOCUS);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Widget::receivedFocus()
|
||||
{
|
||||
|
@ -150,6 +220,14 @@ void Widget::setEnabled(bool e)
|
|||
else clearFlags(Widget::FLAG_ENABLED);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Widget::setToolTip(const string& text)
|
||||
{
|
||||
assert(text.length() <= ToolTip::MAX_LEN);
|
||||
|
||||
_toolTipText = text;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Widget* Widget::findWidgetInChain(Widget* w, int x, int y)
|
||||
{
|
||||
|
@ -224,7 +302,7 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
|
|||
|
||||
s.frameRect(x, y, w, h, onTop ? kDlgColor : kBGColorLo);
|
||||
|
||||
tmp->setDirty();
|
||||
//tmp->setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,7 +358,7 @@ Widget* Widget::setFocusForChain(GuiObject* boss, WidgetArray& arr,
|
|||
if (onTop)
|
||||
s.frameRect(x, y, w, h, kWidFrameColor, FrameStyle::Dashed);
|
||||
|
||||
tmp->setDirty();
|
||||
//tmp->setDirty();
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
@ -290,6 +368,7 @@ void Widget::setDirtyInChain(Widget* start)
|
|||
{
|
||||
while(start)
|
||||
{
|
||||
//cerr << "setDirtyInChain " << typeid(*start).name() << endl;
|
||||
start->setDirty();
|
||||
start = start->_next;
|
||||
}
|
||||
|
@ -304,7 +383,8 @@ StaticTextWidget::StaticTextWidget(GuiObject* boss, const GUI::Font& font,
|
|||
_label(text),
|
||||
_align(align)
|
||||
{
|
||||
_flags = Widget::FLAG_ENABLED;
|
||||
_flags = Widget::FLAG_ENABLED | FLAG_CLEARBG;
|
||||
|
||||
_bgcolor = kDlgColor;
|
||||
_bgcolorhi = kDlgColor;
|
||||
_textcolor = kTextColor;
|
||||
|
@ -338,6 +418,23 @@ void StaticTextWidget::setLabel(const string& label)
|
|||
setDirty();
|
||||
}
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void StaticTextWidget::handleMouseEntered()
|
||||
{
|
||||
if(isEnabled())
|
||||
// Mouse focus for tooltips must not change dirty status
|
||||
setFlags(Widget::FLAG_MOUSE_FOCUS, false);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void StaticTextWidget::handleMouseLeft()
|
||||
{
|
||||
if(isEnabled())
|
||||
// Mouse focus for tooltips must not change dirty status
|
||||
clearFlags(Widget::FLAG_MOUSE_FOCUS, false);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void StaticTextWidget::drawWidget(bool hilite)
|
||||
{
|
||||
|
@ -345,8 +442,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();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -400,13 +495,15 @@ ButtonWidget::ButtonWidget(GuiObject* boss, const GUI::Font& font,
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ButtonWidget::handleMouseEntered()
|
||||
{
|
||||
setFlags(Widget::FLAG_HILITED);
|
||||
if(isEnabled())
|
||||
setFlags(Widget::FLAG_HILITED | Widget::FLAG_MOUSE_FOCUS);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void ButtonWidget::handleMouseLeft()
|
||||
{
|
||||
clearFlags(Widget::FLAG_HILITED);
|
||||
if(isEnabled())
|
||||
clearFlags(Widget::FLAG_HILITED | Widget::FLAG_MOUSE_FOCUS);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -474,8 +571,6 @@ void ButtonWidget::drawWidget(bool hilite)
|
|||
!(isEnabled() && onTop) ? _textcolorlo :
|
||||
hilite ? _textcolorhi : _textcolor,
|
||||
_bmw, _bmh);
|
||||
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -508,18 +603,6 @@ CheckboxWidget::CheckboxWidget(GuiObject* boss, const GUI::Font& font,
|
|||
setFill(CheckboxWidget::FillType::Normal);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheckboxWidget::handleMouseEntered()
|
||||
{
|
||||
setFlags(Widget::FLAG_HILITED);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheckboxWidget::handleMouseLeft()
|
||||
{
|
||||
clearFlags(Widget::FLAG_HILITED);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheckboxWidget::handleMouseUp(int x, int y, MouseButton b, int clickCount)
|
||||
{
|
||||
|
@ -635,8 +718,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 +733,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 +951,6 @@ void SliderWidget::drawWidget(bool hilite)
|
|||
if(_valueLabelWidth > 0)
|
||||
s.drawString(_font, _valueLabel + _valueUnit, _x + _w - _valueLabelWidth, _y + 2,
|
||||
_valueLabelWidth, isEnabled() ? kTextColor : kColor);
|
||||
|
||||
setDirty();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -26,6 +26,7 @@ class Dialog;
|
|||
#include <cassert>
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Rect.hxx"
|
||||
#include "Event.hxx"
|
||||
#include "EventHandlerConstants.hxx"
|
||||
#include "FrameBufferConstants.hxx"
|
||||
|
@ -42,19 +43,6 @@ class Widget : public GuiObject
|
|||
{
|
||||
friend class Dialog;
|
||||
|
||||
public:
|
||||
enum : uInt32 {
|
||||
FLAG_ENABLED = 1 << 0,
|
||||
FLAG_INVISIBLE = 1 << 1,
|
||||
FLAG_HILITED = 1 << 2,
|
||||
FLAG_BORDER = 1 << 3,
|
||||
FLAG_CLEARBG = 1 << 4,
|
||||
FLAG_TRACK_MOUSE = 1 << 5,
|
||||
FLAG_RETAIN_FOCUS = 1 << 6,
|
||||
FLAG_WANTS_TAB = 1 << 7,
|
||||
FLAG_WANTS_RAWDATA = 1 << 8
|
||||
};
|
||||
|
||||
public:
|
||||
Widget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h);
|
||||
~Widget() override;
|
||||
|
@ -71,8 +59,8 @@ class Widget : public GuiObject
|
|||
virtual bool handleKeyUp(StellaKey key, StellaMod mod) { return false; }
|
||||
virtual void handleMouseDown(int x, int y, MouseButton b, int clickCount) { }
|
||||
virtual void handleMouseUp(int x, int y, MouseButton b, int clickCount) { }
|
||||
virtual void handleMouseEntered() { }
|
||||
virtual void handleMouseLeft() { }
|
||||
virtual void handleMouseEntered();
|
||||
virtual void handleMouseLeft();
|
||||
virtual void handleMouseMoved(int x, int y) { }
|
||||
virtual void handleMouseWheel(int x, int y, int direction) { }
|
||||
virtual bool handleMouseClicks(int x, int y, MouseButton b) { return false; }
|
||||
|
@ -82,8 +70,12 @@ class Widget : public GuiObject
|
|||
virtual bool handleJoyHat(int stick, int hat, JoyHatDir hdir, int button = JOY_CTRL_NONE) { return false; }
|
||||
virtual bool handleEvent(Event::Type event) { return false; }
|
||||
|
||||
void tick() override;
|
||||
|
||||
void setDirty() override;
|
||||
void setDirtyChain() override;
|
||||
void draw() override;
|
||||
void drawChain() override;
|
||||
void receivedFocus();
|
||||
void lostFocus();
|
||||
void addFocusWidget(Widget* w) override { _focusList.push_back(w); }
|
||||
|
@ -94,12 +86,10 @@ class Widget : public GuiObject
|
|||
/** Set/clear FLAG_ENABLED */
|
||||
void setEnabled(bool e);
|
||||
|
||||
void setFlags(uInt32 flags) { _flags |= flags; setDirty(); }
|
||||
void clearFlags(uInt32 flags) { _flags &= ~flags; setDirty(); }
|
||||
uInt32 getFlags() const { return _flags; }
|
||||
|
||||
bool isEnabled() const { return _flags & FLAG_ENABLED; }
|
||||
bool isVisible() const override { return !(_flags & FLAG_INVISIBLE); }
|
||||
bool isHighlighted() const { return _flags & FLAG_HILITED; }
|
||||
bool hasMouseFocus() const { return _flags & FLAG_MOUSE_FOCUS; }
|
||||
virtual bool wantsFocus() const { return _flags & FLAG_RETAIN_FOCUS; }
|
||||
bool wantsTab() const { return _flags & FLAG_WANTS_TAB; }
|
||||
bool wantsRaw() const { return _flags & FLAG_WANTS_RAWDATA; }
|
||||
|
@ -115,6 +105,11 @@ class Widget : public GuiObject
|
|||
void setBGColorHi(ColorId color) { _bgcolorhi = color; setDirty(); }
|
||||
void setShadowColor(ColorId color) { _shadowcolor = color; setDirty(); }
|
||||
|
||||
void setToolTip(const string& text);
|
||||
virtual string getToolTip(const Common::Point& pos) const { return _toolTipText; }
|
||||
virtual bool changedToolTip(const Common::Point& oldPos,
|
||||
const Common::Point& newPos) const { return false; }
|
||||
|
||||
virtual void loadConfig() { }
|
||||
|
||||
protected:
|
||||
|
@ -127,6 +122,9 @@ class Widget : public GuiObject
|
|||
|
||||
void releaseFocus() override { assert(_boss); _boss->releaseFocus(); }
|
||||
|
||||
virtual bool wantsToolTip() const { return hasMouseFocus() && hasToolTip(); }
|
||||
virtual bool hasToolTip() const { return !_toolTipText.empty(); }
|
||||
|
||||
// By default, delegate unhandled commands to the boss
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override
|
||||
{ assert(_boss); _boss->handleCommand(sender, cmd, data, id); }
|
||||
|
@ -136,7 +134,6 @@ class Widget : public GuiObject
|
|||
const GUI::Font& _font;
|
||||
Widget* _next{nullptr};
|
||||
uInt32 _id{0};
|
||||
uInt32 _flags{0};
|
||||
bool _hasFocus{false};
|
||||
int _fontWidth{0};
|
||||
int _lineHeight{0};
|
||||
|
@ -147,6 +144,7 @@ class Widget : public GuiObject
|
|||
ColorId _textcolorhi{kTextColorHi};
|
||||
ColorId _textcolorlo{kBGColorLo};
|
||||
ColorId _shadowcolor{kShadowColor};
|
||||
string _toolTipText;
|
||||
|
||||
public:
|
||||
static Widget* findWidgetInChain(Widget* start, int x, int y);
|
||||
|
@ -188,6 +186,10 @@ class StaticTextWidget : public Widget
|
|||
const string& text = "", TextAlign align = TextAlign::Left,
|
||||
ColorId shadowColor = kNone);
|
||||
~StaticTextWidget() override = default;
|
||||
|
||||
void handleMouseEntered() override;
|
||||
void handleMouseLeft() override;
|
||||
|
||||
void setValue(int value);
|
||||
void setLabel(const string& label);
|
||||
void setAlign(TextAlign align) { _align = align; setDirty(); }
|
||||
|
@ -281,8 +283,6 @@ class CheckboxWidget : public ButtonWidget
|
|||
bool getState() const { return _state; }
|
||||
|
||||
void handleMouseUp(int x, int y, MouseButton b, int clickCount) override;
|
||||
void handleMouseEntered() override;
|
||||
void handleMouseLeft() override;
|
||||
|
||||
static int boxSize(const GUI::Font& font)
|
||||
{
|
||||
|
|
|
@ -49,6 +49,7 @@ MODULE_OBJS := \
|
|||
src/gui/TimeLineWidget.o \
|
||||
src/gui/TimeMachineDialog.o \
|
||||
src/gui/TimeMachine.o \
|
||||
src/gui/ToolTip.o \
|
||||
src/gui/UndoHandler.o \
|
||||
src/gui/UIDialog.o \
|
||||
src/gui/VideoAudioDialog.o \
|
||||
|
|
|
@ -44,13 +44,17 @@ class FBSurfaceLIBRETRO : public FBSurface
|
|||
const Common::Rect& dstRect() const override { return myDstGUIR; }
|
||||
void setSrcPos(uInt32 x, uInt32 y) override { }
|
||||
void setSrcSize(uInt32 w, uInt32 h) override { }
|
||||
void setSrcRect(const Common::Rect& r) override { }
|
||||
void setDstPos(uInt32 x, uInt32 y) override { }
|
||||
void setDstSize(uInt32 w, uInt32 h) override { }
|
||||
void setDstRect(const Common::Rect& r) override { }
|
||||
|
||||
void setVisible(bool visible) override { }
|
||||
|
||||
void translateCoords(Int32& x, Int32& y) const override { }
|
||||
bool render() override { return true; }
|
||||
void invalidate() override { }
|
||||
void invalidateRect(uInt32, uInt32, uInt32, uInt32) override { }
|
||||
void free() override { }
|
||||
void reload() override { }
|
||||
void resize(uInt32 width, uInt32 height) override { }
|
||||
|
|
|
@ -531,6 +531,10 @@
|
|||
DCBDDE9B1D6A5F0E009DF1E9 /* Cart3EPlusWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBDDE991D6A5F0E009DF1E9 /* Cart3EPlusWidget.hxx */; };
|
||||
DCBDDE9E1D6A5F2F009DF1E9 /* Cart3EPlus.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCBDDE9C1D6A5F2F009DF1E9 /* Cart3EPlus.cxx */; };
|
||||
DCBDDE9F1D6A5F2F009DF1E9 /* Cart3EPlus.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCBDDE9D1D6A5F2F009DF1E9 /* Cart3EPlus.hxx */; };
|
||||
DCC2FDF5255EB82500FA5E81 /* ToolTip.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC2FDF3255EB82500FA5E81 /* ToolTip.hxx */; };
|
||||
DCC2FDF6255EB82500FA5E81 /* ToolTip.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCC2FDF4255EB82500FA5E81 /* ToolTip.cxx */; };
|
||||
DCC2FDF92566AD8800FA5E81 /* DataGridRamWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCC2FDF72566AD8800FA5E81 /* DataGridRamWidget.cxx */; };
|
||||
DCC2FDFA2566AD8800FA5E81 /* DataGridRamWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC2FDF82566AD8800FA5E81 /* DataGridRamWidget.hxx */; };
|
||||
DCC527D110B9DA19005E1287 /* Device.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC527C910B9DA19005E1287 /* Device.hxx */; };
|
||||
DCC527D210B9DA19005E1287 /* M6502.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCC527CA10B9DA19005E1287 /* M6502.cxx */; };
|
||||
DCC527D310B9DA19005E1287 /* M6502.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCC527CB10B9DA19005E1287 /* M6502.hxx */; };
|
||||
|
@ -1298,6 +1302,10 @@
|
|||
DCBDDE991D6A5F0E009DF1E9 /* Cart3EPlusWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cart3EPlusWidget.hxx; sourceTree = "<group>"; };
|
||||
DCBDDE9C1D6A5F2F009DF1E9 /* Cart3EPlus.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cart3EPlus.cxx; sourceTree = "<group>"; };
|
||||
DCBDDE9D1D6A5F2F009DF1E9 /* Cart3EPlus.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cart3EPlus.hxx; sourceTree = "<group>"; };
|
||||
DCC2FDF3255EB82500FA5E81 /* ToolTip.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ToolTip.hxx; sourceTree = "<group>"; };
|
||||
DCC2FDF4255EB82500FA5E81 /* ToolTip.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ToolTip.cxx; sourceTree = "<group>"; };
|
||||
DCC2FDF72566AD8800FA5E81 /* DataGridRamWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataGridRamWidget.cxx; sourceTree = "<group>"; };
|
||||
DCC2FDF82566AD8800FA5E81 /* DataGridRamWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DataGridRamWidget.hxx; sourceTree = "<group>"; };
|
||||
DCC527C910B9DA19005E1287 /* Device.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Device.hxx; sourceTree = "<group>"; };
|
||||
DCC527CA10B9DA19005E1287 /* M6502.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = M6502.cxx; sourceTree = "<group>"; };
|
||||
DCC527CB10B9DA19005E1287 /* M6502.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = M6502.hxx; sourceTree = "<group>"; };
|
||||
|
@ -1702,6 +1710,8 @@
|
|||
2D20F9E708C603EC00A73076 /* CpuWidget.hxx */,
|
||||
2D20F9E808C603EC00A73076 /* DataGridOpsWidget.cxx */,
|
||||
2D20F9E908C603EC00A73076 /* DataGridOpsWidget.hxx */,
|
||||
DCC2FDF72566AD8800FA5E81 /* DataGridRamWidget.cxx */,
|
||||
DCC2FDF82566AD8800FA5E81 /* DataGridRamWidget.hxx */,
|
||||
2D20F9EA08C603EC00A73076 /* DataGridWidget.cxx */,
|
||||
2D20F9EB08C603EC00A73076 /* DataGridWidget.hxx */,
|
||||
2D20F9EC08C603EC00A73076 /* DebuggerDialog.cxx */,
|
||||
|
@ -2167,6 +2177,8 @@
|
|||
DCA82C6E1FEB4E780059340F /* TimeMachine.hxx */,
|
||||
DCA82C6F1FEB4E780059340F /* TimeMachineDialog.cxx */,
|
||||
DCA82C701FEB4E780059340F /* TimeMachineDialog.hxx */,
|
||||
DCC2FDF4255EB82500FA5E81 /* ToolTip.cxx */,
|
||||
DCC2FDF3255EB82500FA5E81 /* ToolTip.hxx */,
|
||||
DC8078E60B4BD697005E9305 /* UIDialog.cxx */,
|
||||
DC8078E70B4BD697005E9305 /* UIDialog.hxx */,
|
||||
DCBA539825557E2800087DD7 /* UndoHandler.cxx */,
|
||||
|
@ -2572,6 +2584,7 @@
|
|||
E08FCD5823A037EB0051F59B /* QisBlitter.hxx in Headers */,
|
||||
DCA078351F8C1B04008EFEE5 /* SDL_lib.hxx in Headers */,
|
||||
DCDA03B11A2009BB00711920 /* CartWD.hxx in Headers */,
|
||||
DCC2FDFA2566AD8800FA5E81 /* DataGridRamWidget.hxx in Headers */,
|
||||
2D91745909BA90380026E9FF /* PromptWidget.hxx in Headers */,
|
||||
DC3C9BC62469C8F700CF2D47 /* PaletteHandler.hxx in Headers */,
|
||||
2D91745A09BA90380026E9FF /* RamWidget.hxx in Headers */,
|
||||
|
@ -2651,6 +2664,7 @@
|
|||
DC5D1AA7102C6FC900E59AC1 /* Stack.hxx in Headers */,
|
||||
DCF7B0DE10A762FC007A2870 /* CartF0.hxx in Headers */,
|
||||
DCF7B0E010A762FC007A2870 /* CartFA.hxx in Headers */,
|
||||
DCC2FDF5255EB82500FA5E81 /* ToolTip.hxx in Headers */,
|
||||
DCC527D110B9DA19005E1287 /* Device.hxx in Headers */,
|
||||
DC6F394E21B897F300897AD8 /* ThreadDebugging.hxx in Headers */,
|
||||
DCC527D310B9DA19005E1287 /* M6502.hxx in Headers */,
|
||||
|
@ -3191,6 +3205,7 @@
|
|||
DC676A591729A0B000E4E73D /* CartSBWidget.cxx in Sources */,
|
||||
DC3C9BCC2469C93D00CF2D47 /* EmulationDialog.cxx in Sources */,
|
||||
DC676A5B1729A0B000E4E73D /* CartX07Widget.cxx in Sources */,
|
||||
DCC2FDF92566AD8800FA5E81 /* DataGridRamWidget.cxx in Sources */,
|
||||
DC7A24DF173B1DBC00B20FE9 /* FileListWidget.cxx in Sources */,
|
||||
DC13B53F176FF2F500B8B4BB /* RomListSettings.cxx in Sources */,
|
||||
DC3EE8581E2C0E6D00905161 /* crc32.c in Sources */,
|
||||
|
@ -3205,6 +3220,7 @@
|
|||
DCAACB0E188D636F00A4D282 /* Cart4KSCWidget.cxx in Sources */,
|
||||
DCB60AD02543100900A5C1D2 /* FBBackendSDL2.cxx in Sources */,
|
||||
DCAACB10188D636F00A4D282 /* CartBFSCWidget.cxx in Sources */,
|
||||
DCC2FDF6255EB82500FA5E81 /* ToolTip.cxx in Sources */,
|
||||
DCAACB12188D636F00A4D282 /* CartBFWidget.cxx in Sources */,
|
||||
DCAACB14188D636F00A4D282 /* CartDFSCWidget.cxx in Sources */,
|
||||
DCAACB16188D636F00A4D282 /* CartDFWidget.cxx in Sources */,
|
||||
|
@ -3389,7 +3405,7 @@
|
|||
.,
|
||||
"$(HOME)/Library/Frameworks",
|
||||
);
|
||||
GCC_ENABLE_CPP_RTTI = NO;
|
||||
GCC_ENABLE_CPP_RTTI = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_VERSION = "";
|
||||
|
@ -3464,7 +3480,7 @@
|
|||
.,
|
||||
"$(HOME)/Library/Frameworks",
|
||||
);
|
||||
GCC_ENABLE_CPP_RTTI = NO;
|
||||
GCC_ENABLE_CPP_RTTI = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 3;
|
||||
GCC_VERSION = "";
|
||||
|
|
|
@ -681,6 +681,7 @@
|
|||
<ClCompile Include="..\debugger\gui\CartX07Widget.cxx">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\debugger\gui\DataGridRamWidget.cxx" />
|
||||
<ClCompile Include="..\debugger\gui\DelayQueueWidget.cxx">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
@ -786,6 +787,7 @@
|
|||
<ClCompile Include="..\gui\TimeLineWidget.cxx" />
|
||||
<ClCompile Include="..\gui\TimeMachine.cxx" />
|
||||
<ClCompile Include="..\gui\TimeMachineDialog.cxx" />
|
||||
<ClCompile Include="..\gui\ToolTip.cxx" />
|
||||
<ClCompile Include="..\gui\UndoHandler.cxx" />
|
||||
<ClCompile Include="..\gui\WhatsNewDialog.cxx" />
|
||||
<ClCompile Include="FSNodeWINDOWS.cxx" />
|
||||
|
@ -1705,6 +1707,7 @@
|
|||
<ClInclude Include="..\debugger\gui\ControllerWidget.hxx">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\debugger\gui\DataGridRamWidget.hxx" />
|
||||
<ClInclude Include="..\debugger\gui\DelayQueueWidget.hxx">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
|
@ -1838,6 +1841,7 @@
|
|||
<ClInclude Include="..\gui\TimeLineWidget.hxx" />
|
||||
<ClInclude Include="..\gui\TimeMachine.hxx" />
|
||||
<ClInclude Include="..\gui\TimeMachineDialog.hxx" />
|
||||
<ClInclude Include="..\gui\ToolTip.hxx" />
|
||||
<ClInclude Include="..\gui\UndoHandler.hxx" />
|
||||
<ClInclude Include="..\gui\WhatsNewDialog.hxx" />
|
||||
<ClInclude Include="..\libpng\pngdebug.h" />
|
||||
|
|
|
@ -1032,6 +1032,12 @@
|
|||
<ClCompile Include="..\gui\UndoHandler.cxx">
|
||||
<Filter>Source Files\gui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\gui\ToolTip.cxx">
|
||||
<Filter>Source Files\gui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\debugger\gui\DataGridRamWidget.cxx">
|
||||
<Filter>Source Files\debugger</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\common\bspf.hxx">
|
||||
|
@ -2123,6 +2129,12 @@
|
|||
<ClInclude Include="..\gui\UndoHandler.hxx">
|
||||
<Filter>Header Files\gui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\gui\ToolTip.hxx">
|
||||
<Filter>Header Files\gui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\debugger\gui\DataGridRamWidget.hxx">
|
||||
<Filter>Header Files\debugger</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="stella.ico">
|
||||
|
|
Loading…
Reference in New Issue