Move display options to owned_opts
This also removes limits on the main window position so it can now be negative. This is necessary on Windows where multiple screens to the left and top of the main screen have negative coordinates. A check at startup ensures we always restore the window within the drawable area.
This commit is contained in:
parent
216bf4d7e4
commit
950a4070c1
|
@ -765,6 +765,7 @@ set(
|
|||
config/option.cpp
|
||||
config/user-input.cpp
|
||||
dialogs/display-config.cpp
|
||||
widgets/keep-on-top-styler.cpp
|
||||
widgets/keyedit.cpp
|
||||
widgets/joyedit.cpp
|
||||
widgets/option-validator.cpp
|
||||
|
@ -811,6 +812,7 @@ set(
|
|||
config/user-input.h
|
||||
dialogs/display-config.h
|
||||
widgets/dpi-support.h
|
||||
widgets/keep-on-top-styler.h
|
||||
widgets/option-validator.h
|
||||
widgets/render-plugin.h
|
||||
widgets/wx/keyedit.h
|
||||
|
|
|
@ -2267,12 +2267,6 @@ EVT_HANDLER(Logging, "Logging...")
|
|||
{
|
||||
wxDialog* dlg = wxGetApp().frame->logdlg;
|
||||
dlg->SetWindowStyle(wxCAPTION | wxRESIZE_BORDER);
|
||||
|
||||
if (gopts.keep_on_top)
|
||||
dlg->SetWindowStyle(dlg->GetWindowStyle() | wxSTAY_ON_TOP);
|
||||
else
|
||||
dlg->SetWindowStyle(dlg->GetWindowStyle() & ~wxSTAY_ON_TOP);
|
||||
|
||||
dlg->Show();
|
||||
dlg->Raise();
|
||||
}
|
||||
|
@ -2741,15 +2735,6 @@ EVT_HANDLER(GameBoyAdvanceConfigure, "Game Boy Advance options...")
|
|||
|
||||
EVT_HANDLER_MASK(DisplayConfigure, "Display options...", CMDEN_NREC_ANY)
|
||||
{
|
||||
if (gopts.max_threads != 1) {
|
||||
gopts.max_threads = wxThread::GetCPUCount();
|
||||
}
|
||||
|
||||
// Just in case GetCPUCount() returns 0 or -1
|
||||
if (gopts.max_threads < 0) {
|
||||
gopts.max_threads = 1;
|
||||
}
|
||||
|
||||
wxDialog* dlg = GetXRCDialog("DisplayConfig");
|
||||
if (ShowModal(dlg) != wxID_OK) {
|
||||
return;
|
||||
|
@ -2965,18 +2950,12 @@ EVT_HANDLER(wxID_ABOUT, "About...")
|
|||
|
||||
EVT_HANDLER(Bilinear, "Use bilinear filter with 3d renderer")
|
||||
{
|
||||
GetMenuOptionBool("Bilinear", &gopts.bilinear);
|
||||
// Force new panel with new bilinear option.
|
||||
panel->ResetPanel();
|
||||
update_opts();
|
||||
GetMenuOptionConfig("Bilinear", config::OptionID::kDispBilinear);
|
||||
}
|
||||
|
||||
EVT_HANDLER(RetainAspect, "Retain aspect ratio when resizing")
|
||||
{
|
||||
GetMenuOptionBool("RetainAspect", &gopts.retain_aspect);
|
||||
// Force new panel with new aspect ratio options.
|
||||
panel->ResetPanel();
|
||||
update_opts();
|
||||
GetMenuOptionConfig("RetainAspect", config::OptionID::kDispStretch);
|
||||
}
|
||||
|
||||
EVT_HANDLER(Printer, "Enable printer emulation")
|
||||
|
@ -3080,15 +3059,7 @@ EVT_HANDLER(ApplyPatches, "Apply IPS/UPS/IPF patches if found")
|
|||
|
||||
EVT_HANDLER(KeepOnTop, "Keep window on top")
|
||||
{
|
||||
GetMenuOptionBool("KeepOnTop", &gopts.keep_on_top);
|
||||
MainFrame* mf = wxGetApp().frame;
|
||||
|
||||
if (gopts.keep_on_top)
|
||||
mf->SetWindowStyle(mf->GetWindowStyle() | wxSTAY_ON_TOP);
|
||||
else
|
||||
mf->SetWindowStyle(mf->GetWindowStyle() & ~wxSTAY_ON_TOP);
|
||||
|
||||
update_opts();
|
||||
GetMenuOptionConfig("KeepOnTop", config::OptionID::kDispKeepOnTop);
|
||||
}
|
||||
|
||||
EVT_HANDLER(StatusBar, "Enable status bar")
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <wx/log.h>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
#include "../common/ConfigManager.h"
|
||||
#include "../gb/gbGlobals.h"
|
||||
|
@ -145,20 +146,27 @@ wxString AllEnumValuesForArray(const std::array<wxString, SIZE>& input) {
|
|||
// static
|
||||
std::array<Option, kNbOptions>& Option::All() {
|
||||
struct OwnedOptions {
|
||||
double video_scale = 3;
|
||||
wxString filter_plugin = wxEmptyString;
|
||||
/// Display
|
||||
bool bilinear = true;
|
||||
Filter filter = Filter::kNone;
|
||||
wxString filter_plugin = wxEmptyString;
|
||||
Interframe interframe = Interframe::kNone;
|
||||
bool keep_on_top = false;
|
||||
int32_t max_threads = 0;
|
||||
#if defined(NO_OGL)
|
||||
RenderMethod render_method = RenderMethod::kSimple;
|
||||
#else
|
||||
RenderMethod render_method = RenderMethod::kOpenGL;
|
||||
#endif
|
||||
double video_scale = 3;
|
||||
bool retain_aspect = true;
|
||||
|
||||
/// Geometry
|
||||
bool window_maximized = false;
|
||||
uint32_t window_height = 0;
|
||||
uint32_t window_width = 0;
|
||||
int window_pos_x = -1;
|
||||
int window_pos_y = -1;
|
||||
int32_t window_pos_x = -1;
|
||||
int32_t window_pos_y = -1;
|
||||
};
|
||||
static OwnedOptions g_owned_opts;
|
||||
|
||||
|
@ -170,15 +178,15 @@ std::array<Option, kNbOptions>& Option::All() {
|
|||
// clang-format off
|
||||
static std::array<Option, kNbOptions> g_all_opts = {
|
||||
/// Display
|
||||
Option(OptionID::kDispBilinear, &gopts.bilinear),
|
||||
Option(OptionID::kDispBilinear, &g_owned_opts.bilinear),
|
||||
Option(OptionID::kDispFilter, &g_owned_opts.filter),
|
||||
Option(OptionID::kDispFilterPlugin, &g_owned_opts.filter_plugin),
|
||||
Option(OptionID::kDispIFB, &g_owned_opts.interframe),
|
||||
Option(OptionID::kDispKeepOnTop, &gopts.keep_on_top),
|
||||
Option(OptionID::kDispMaxThreads, &gopts.max_threads, 1, 256),
|
||||
Option(OptionID::kDispKeepOnTop, &g_owned_opts.keep_on_top),
|
||||
Option(OptionID::kDispMaxThreads, &g_owned_opts.max_threads, 0, 256),
|
||||
Option(OptionID::kDispRenderMethod, &g_owned_opts.render_method),
|
||||
Option(OptionID::kDispScale, &g_owned_opts.video_scale, 1, 6),
|
||||
Option(OptionID::kDispStretch, &gopts.retain_aspect),
|
||||
Option(OptionID::kDispStretch, &g_owned_opts.retain_aspect),
|
||||
|
||||
/// GB
|
||||
Option(OptionID::kGBBiosFile, &gopts.gb_bios),
|
||||
|
@ -270,8 +278,8 @@ std::array<Option, kNbOptions>& Option::All() {
|
|||
Option(OptionID::kGeomIsMaximized, &g_owned_opts.window_maximized),
|
||||
Option(OptionID::kGeomWindowHeight, &g_owned_opts.window_height, 0, 99999),
|
||||
Option(OptionID::kGeomWindowWidth, &g_owned_opts.window_width, 0, 99999),
|
||||
Option(OptionID::kGeomWindowX, &g_owned_opts.window_pos_x, -1, 99999),
|
||||
Option(OptionID::kGeomWindowY, &g_owned_opts.window_pos_y, -1, 99999),
|
||||
Option(OptionID::kGeomWindowX, &g_owned_opts.window_pos_x, std::numeric_limits<int32_t>::min(), std::numeric_limits<int32_t>::max()),
|
||||
Option(OptionID::kGeomWindowY, &g_owned_opts.window_pos_y, std::numeric_limits<int32_t>::min(), std::numeric_limits<int32_t>::max()),
|
||||
|
||||
/// UI
|
||||
Option(OptionID::kUIAllowKeyboardBackgroundInput, &allowKeyboardBackgroundInput),
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
namespace config {
|
||||
|
||||
enum class OptionID {
|
||||
// Display
|
||||
/// Display
|
||||
kDispBilinear = 0,
|
||||
kDispFilter,
|
||||
kDispFilterPlugin,
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "config/option-id.h"
|
||||
#include "config/option-proxy.h"
|
||||
#include "config/option.h"
|
||||
#include "keep-on-top-styler.h"
|
||||
#include "rpi.h"
|
||||
#include "wayland.h"
|
||||
#include "widgets/option-validator.h"
|
||||
|
@ -250,7 +251,8 @@ DisplayConfig::DisplayConfig(wxWindow* parent)
|
|||
interframe_observer_(config::OptionID::kDispIFB,
|
||||
std::bind(&DisplayConfig::OnInterframeChanged,
|
||||
this,
|
||||
std::placeholders::_1)) {
|
||||
std::placeholders::_1)),
|
||||
keep_on_top_styler_(this) {
|
||||
#if !wxCHECK_VERSION(3, 1, 0)
|
||||
// This needs to be set before loading any element on the window. This also
|
||||
// has no effect since wx 3.1.0, where it became the default.
|
||||
|
@ -337,6 +339,9 @@ void DisplayConfig::OnDialogShowEvent(wxShowEvent& event) {
|
|||
} else {
|
||||
StopPluginHandler();
|
||||
}
|
||||
|
||||
// Let the event propagate.
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void DisplayConfig::PopulatePluginOptions() {
|
||||
|
@ -408,6 +413,9 @@ void DisplayConfig::UpdatePlugin(wxCommandEvent& event) {
|
|||
config::Filter::kPlugin);
|
||||
plugin_label_->Enable(is_plugin);
|
||||
plugin_selector_->Enable(is_plugin);
|
||||
|
||||
// Let the event propagate.
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void DisplayConfig::OnFilterChanged(config::Option* option) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <wx/event.h>
|
||||
|
||||
#include "config/option-observer.h"
|
||||
#include "widgets/keep-on-top-styler.h"
|
||||
|
||||
// Forward declarations.
|
||||
class wxChoice;
|
||||
|
@ -55,8 +56,9 @@ private:
|
|||
wxChoice* plugin_selector_;
|
||||
wxChoice* filter_selector_;
|
||||
wxChoice* interframe_selector_;
|
||||
config::OptionsObserver filter_observer_;
|
||||
config::OptionsObserver interframe_observer_;
|
||||
const config::OptionsObserver filter_observer_;
|
||||
const config::OptionsObserver interframe_observer_;
|
||||
const widgets::KeepOnTopStyler keep_on_top_styler_;
|
||||
};
|
||||
|
||||
} // namespace dialogs
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "../gba/CheatSearch.h"
|
||||
#include "config/game-control.h"
|
||||
#include "config/option.h"
|
||||
#include "config/option-proxy.h"
|
||||
#include "config/user-input.h"
|
||||
#include "dialogs/display-config.h"
|
||||
#include "opts.h"
|
||||
|
@ -322,7 +323,7 @@ public:
|
|||
wxDialog* subdlg = GetXRCDialog("CheatEdit");
|
||||
dlg->SetWindowStyle(wxCAPTION | wxRESIZE_BORDER);
|
||||
|
||||
if (gopts.keep_on_top)
|
||||
if (OPTION(kDispKeepOnTop))
|
||||
subdlg->SetWindowStyle(subdlg->GetWindowStyle() | wxSTAY_ON_TOP);
|
||||
else
|
||||
subdlg->SetWindowStyle(subdlg->GetWindowStyle() & ~wxSTAY_ON_TOP);
|
||||
|
@ -545,7 +546,7 @@ public:
|
|||
wxDialog* subdlg = GetXRCDialog("CheatEdit");
|
||||
dlg->SetWindowStyle(wxCAPTION | wxRESIZE_BORDER);
|
||||
|
||||
if (gopts.keep_on_top)
|
||||
if (OPTION(kDispKeepOnTop))
|
||||
subdlg->SetWindowStyle(subdlg->GetWindowStyle() | wxSTAY_ON_TOP);
|
||||
else
|
||||
subdlg->SetWindowStyle(subdlg->GetWindowStyle() & ~wxSTAY_ON_TOP);
|
||||
|
@ -1075,7 +1076,7 @@ public:
|
|||
wxDialog* subdlg = GetXRCDialog("CheatAdd");
|
||||
dlg->SetWindowStyle(wxCAPTION | wxRESIZE_BORDER);
|
||||
|
||||
if (gopts.keep_on_top)
|
||||
if (OPTION(kDispKeepOnTop))
|
||||
subdlg->SetWindowStyle(subdlg->GetWindowStyle() | wxSTAY_ON_TOP);
|
||||
else
|
||||
subdlg->SetWindowStyle(subdlg->GetWindowStyle() & ~wxSTAY_ON_TOP);
|
||||
|
@ -3785,7 +3786,7 @@ bool MainFrame::BindControls()
|
|||
else
|
||||
mf->GetStatusBar()->Hide();
|
||||
|
||||
if (gopts.keep_on_top)
|
||||
if (OPTION(kDispKeepOnTop))
|
||||
mf->SetWindowStyle(mf->GetWindowStyle() | wxSTAY_ON_TOP);
|
||||
else
|
||||
mf->SetWindowStyle(mf->GetWindowStyle() & ~wxSTAY_ON_TOP);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <wx/display.h>
|
||||
|
||||
#include "config/option-observer.h"
|
||||
#include "config/option-proxy.h"
|
||||
#include "config/option.h"
|
||||
#include "strutils.h"
|
||||
#include "wxvbam.h"
|
||||
|
@ -308,14 +309,6 @@ wxAcceleratorEntry_v sys_accels;
|
|||
// This constructor only works with globally allocated gopts.
|
||||
opts_t::opts_t()
|
||||
{
|
||||
// handle erroneous thread count values appropriately
|
||||
max_threads = wxThread::GetCPUCount();
|
||||
if (max_threads > 256)
|
||||
max_threads = 256;
|
||||
|
||||
if (max_threads < 1)
|
||||
max_threads = 1;
|
||||
|
||||
recent = new wxFileHistory(10);
|
||||
|
||||
// These are globals being set here.
|
||||
|
@ -556,6 +549,20 @@ void load_opts() {
|
|||
cfg->SetPath(wxT("/"));
|
||||
cfg->Flush();
|
||||
|
||||
// We default the MaxThreads option to 0, so set it to the CPU count here.
|
||||
config::OptionProxy<config::OptionID::kDispMaxThreads> max_threads;
|
||||
if (max_threads == 0) {
|
||||
// Handle erroneous thread count values appropriately.
|
||||
const int cpu_count = wxThread::GetCPUCount();
|
||||
if (cpu_count > 256) {
|
||||
max_threads = 256;
|
||||
} else if (cpu_count < 1) {
|
||||
max_threads = 1;
|
||||
} else {
|
||||
max_threads = cpu_count;
|
||||
}
|
||||
}
|
||||
|
||||
InitializeOptionObservers();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,11 +23,7 @@ extern struct opts_t {
|
|||
// I instead organized this by opts.cpp table order
|
||||
|
||||
/// Display
|
||||
bool bilinear = true;
|
||||
wxVideoMode fs_mode;
|
||||
int max_threads = 0;
|
||||
bool retain_aspect = true;
|
||||
bool keep_on_top = false;
|
||||
|
||||
/// GB
|
||||
wxString gb_bios;
|
||||
|
|
|
@ -110,8 +110,9 @@ GameArea::GameArea()
|
|||
pointer_blanked(false),
|
||||
mouse_active_time(0),
|
||||
render_observer_(
|
||||
{config::OptionID::kDispRenderMethod, config::OptionID::kDispFilter,
|
||||
config::OptionID::kDispIFB},
|
||||
{config::OptionID::kDispBilinear, config::OptionID::kDispFilter,
|
||||
config::OptionID::kDispRenderMethod, config::OptionID::kDispIFB,
|
||||
config::OptionID::kDispStretch},
|
||||
std::bind(&GameArea::ResetPanel, this)),
|
||||
scale_observer_(config::OptionID::kDispScale,
|
||||
std::bind(&GameArea::AdjustSize, this, true)) {
|
||||
|
@ -1158,32 +1159,28 @@ void GameArea::OnIdle(wxIdleEvent& event)
|
|||
AdjustMinSize();
|
||||
AdjustSize(false);
|
||||
|
||||
unsigned frame_priority = gopts.retain_aspect ? 0 : 1;
|
||||
const bool retain_aspect = OPTION(kDispStretch);
|
||||
const unsigned frame_priority = retain_aspect ? 0 : 1;
|
||||
|
||||
GetSizer()->Clear();
|
||||
|
||||
// add spacers on top and bottom to center panel vertically
|
||||
// but not on 2.8 which does not handle this correctly
|
||||
if (gopts.retain_aspect)
|
||||
#if wxCHECK_VERSION(2, 9, 0)
|
||||
if (retain_aspect) {
|
||||
GetSizer()->Add(0, 0, wxEXPAND);
|
||||
#else
|
||||
frame_priority = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// this triggers an assertion dialog in <= 3.1.2 in debug mode
|
||||
GetSizer()->Add(w, frame_priority, gopts.retain_aspect ? (wxSHAPED | wxALIGN_CENTER | wxEXPAND) : wxEXPAND);
|
||||
GetSizer()->Add(
|
||||
w, frame_priority,
|
||||
retain_aspect ? (wxSHAPED | wxALIGN_CENTER | wxEXPAND) : wxEXPAND);
|
||||
|
||||
#if wxCHECK_VERSION(2, 9, 0)
|
||||
if (gopts.retain_aspect)
|
||||
if (retain_aspect) {
|
||||
GetSizer()->Add(0, 0, wxEXPAND);
|
||||
#endif
|
||||
}
|
||||
|
||||
Layout();
|
||||
|
||||
#if wxCHECK_VERSION(2, 9, 0)
|
||||
SendSizeEvent();
|
||||
#endif
|
||||
|
||||
if (pointer_blanked)
|
||||
w->SetCursor(wxCursor(wxCURSOR_BLANK));
|
||||
|
@ -1196,7 +1193,8 @@ void GameArea::OnIdle(wxIdleEvent& event)
|
|||
utilUpdateSystemColorMaps(gopts.gba_lcd_filter);
|
||||
else if (loaded == IMAGE_GB)
|
||||
utilUpdateSystemColorMaps(gopts.gb_lcd_filter);
|
||||
else utilUpdateSystemColorMaps(false);
|
||||
else
|
||||
utilUpdateSystemColorMaps(false);
|
||||
}
|
||||
|
||||
mf->PollJoysticks();
|
||||
|
@ -1806,13 +1804,13 @@ void DrawingPanelBase::DrawArea(uint8_t** data)
|
|||
todraw = pixbuf2;
|
||||
|
||||
// FIXME: filters race condition?
|
||||
gopts.max_threads = 1;
|
||||
const int max_threads = 1;
|
||||
|
||||
// First, apply filters, if applicable, in parallel, if enabled
|
||||
// FIXME: && (gopts.ifb != FF_MOTION_BLUR || !renderer_can_motion_blur)
|
||||
if (OPTION(kDispFilter) != config::Filter::kNone ||
|
||||
OPTION(kDispIFB) != config::Interframe::kNone) {
|
||||
if (nthreads != gopts.max_threads) {
|
||||
if (nthreads != max_threads) {
|
||||
if (nthreads) {
|
||||
if (nthreads > 1)
|
||||
for (int i = 0; i < nthreads; i++) {
|
||||
|
@ -1826,7 +1824,7 @@ void DrawingPanelBase::DrawArea(uint8_t** data)
|
|||
delete[] threads;
|
||||
}
|
||||
|
||||
nthreads = gopts.max_threads;
|
||||
nthreads = max_threads;
|
||||
threads = new FilterThread[nthreads];
|
||||
// first time around, no threading in order to avoid
|
||||
// static initializer conflicts
|
||||
|
@ -2217,6 +2215,8 @@ void GLDrawingPanel::DrawingPanelInit()
|
|||
|
||||
AdjustViewport();
|
||||
|
||||
const bool bilinear = OPTION(kDispBilinear);
|
||||
|
||||
// taken from GTK front end almost verbatim
|
||||
glDisable(GL_CULL_FACE);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
@ -2241,9 +2241,9 @@ void GLDrawingPanel::DrawingPanelInit()
|
|||
glGenTextures(1, &texid);
|
||||
glBindTexture(GL_TEXTURE_2D, texid);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||
gopts.bilinear ? GL_LINEAR : GL_NEAREST);
|
||||
bilinear ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
gopts.bilinear ? GL_LINEAR : GL_NEAREST);
|
||||
bilinear ? GL_LINEAR : GL_NEAREST);
|
||||
|
||||
#define int_fmt out_16 ? GL_RGB5 : GL_RGB
|
||||
#define tex_fmt out_16 ? GL_BGRA : GL_RGBA, \
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "../common/SoundSDL.h"
|
||||
#include "config/game-control.h"
|
||||
#include "config/option-proxy.h"
|
||||
#include "wxvbam.h"
|
||||
#include "SDL.h"
|
||||
#include <wx/ffile.h>
|
||||
|
@ -777,7 +778,7 @@ public:
|
|||
{
|
||||
dlg->SetWindowStyle(wxCAPTION | wxRESIZE_BORDER);
|
||||
|
||||
if (gopts.keep_on_top)
|
||||
if (OPTION(kDispKeepOnTop))
|
||||
dlg->SetWindowStyle(dlg->GetWindowStyle() | wxSTAY_ON_TOP);
|
||||
else
|
||||
dlg->SetWindowStyle(dlg->GetWindowStyle() & ~wxSTAY_ON_TOP);
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
|
||||
#include "../common/cstdint.h"
|
||||
|
||||
#include "../gba/armdis.h"
|
||||
#include "viewsupt.h"
|
||||
#include "wxvbam.h"
|
||||
#include <wx/ffile.h>
|
||||
#include <wx/vlbox.h>
|
||||
#include "../gba/armdis.h"
|
||||
#include "config/option-proxy.h"
|
||||
#include "keep-on-top-styler.h"
|
||||
#include "viewsupt.h"
|
||||
#include "wxvbam.h"
|
||||
|
||||
// avoid exporting classes
|
||||
namespace Viewers {
|
||||
|
@ -515,8 +517,7 @@ void MainFrame::IOViewer()
|
|||
baddialog(); \
|
||||
cb->SetValidator(wxBoolIntValidator(&systemVerbose, val, val)); \
|
||||
} while (0)
|
||||
LogDialog::LogDialog()
|
||||
{
|
||||
LogDialog::LogDialog() : keep_on_top_styler_(this) {
|
||||
const wxString dname = wxT("Logging");
|
||||
|
||||
if (!wxXmlResource::Get()->LoadDialog(this, wxGetApp().frame, dname))
|
||||
|
@ -727,7 +728,7 @@ public:
|
|||
selreg_len->SetValue(s);
|
||||
selregion->SetWindowStyle(wxCAPTION | wxRESIZE_BORDER);
|
||||
|
||||
if (gopts.keep_on_top)
|
||||
if (OPTION(kDispKeepOnTop))
|
||||
selregion->SetWindowStyle(selregion->GetWindowStyle() | wxSTAY_ON_TOP);
|
||||
else
|
||||
selregion->SetWindowStyle(selregion->GetWindowStyle() & ~wxSTAY_ON_TOP);
|
||||
|
@ -752,7 +753,7 @@ public:
|
|||
selreg_len->SetValue(wxEmptyString);
|
||||
selregion->SetWindowStyle(wxCAPTION | wxRESIZE_BORDER);
|
||||
|
||||
if (gopts.keep_on_top)
|
||||
if (OPTION(kDispKeepOnTop))
|
||||
selregion->SetWindowStyle(selregion->GetWindowStyle() | wxSTAY_ON_TOP);
|
||||
else
|
||||
selregion->SetWindowStyle(selregion->GetWindowStyle() & ~wxSTAY_ON_TOP);
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
#include "widgets/keep-on-top-styler.h"
|
||||
|
||||
#include <wx/toplevel.h>
|
||||
|
||||
#include "config/option-proxy.h"
|
||||
#include "config/option.h"
|
||||
|
||||
namespace widgets {
|
||||
|
||||
KeepOnTopStyler::KeepOnTopStyler(wxTopLevelWindow* window)
|
||||
: window_(window),
|
||||
on_top_observer_(config::OptionID::kDispKeepOnTop,
|
||||
std::bind(&KeepOnTopStyler::OnKeepOnTopChanged,
|
||||
this,
|
||||
std::placeholders::_1)) {
|
||||
assert(window_);
|
||||
window_->Bind(wxEVT_SHOW, &KeepOnTopStyler::OnShow, this);
|
||||
}
|
||||
|
||||
KeepOnTopStyler::~KeepOnTopStyler() {
|
||||
// Need to manually unbind to stop processing events for this window.
|
||||
window_->Unbind(wxEVT_SHOW, &KeepOnTopStyler::OnShow, this);
|
||||
}
|
||||
|
||||
void KeepOnTopStyler::OnShow(wxShowEvent& show_event) {
|
||||
if (show_event.IsShown()) {
|
||||
// This must be called when the window is shown or it has no effect.
|
||||
OnKeepOnTopChanged(
|
||||
config::Option::ByID(config::OptionID::kDispKeepOnTop));
|
||||
}
|
||||
|
||||
// Let the event propagate.
|
||||
show_event.Skip();
|
||||
}
|
||||
|
||||
void KeepOnTopStyler::OnKeepOnTopChanged(config::Option* option) {
|
||||
if (option->GetBool()) {
|
||||
window_->SetWindowStyle(window_->GetWindowStyle() | wxSTAY_ON_TOP);
|
||||
} else {
|
||||
window_->SetWindowStyle(window_->GetWindowStyle() & ~wxSTAY_ON_TOP);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace widgets
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef VBAM_WX_DIALOGS_BASE_DIALOG_H_
|
||||
#define VBAM_WX_DIALOGS_BASE_DIALOG_H_
|
||||
|
||||
#include <wx/event.h>
|
||||
|
||||
#include "config/option-observer.h"
|
||||
|
||||
// Forward declarations.
|
||||
class wxTopLevelWindow;
|
||||
|
||||
namespace config {
|
||||
class Option;
|
||||
}
|
||||
|
||||
namespace widgets {
|
||||
|
||||
// Helper class to automatically set and unset the wxSTAY_ON_TOP to any
|
||||
// top-level window. Simply add it as a private member to any top-level window
|
||||
// implementation and pass the reference to the window in the constructor.
|
||||
//
|
||||
// Sample usage:
|
||||
//
|
||||
// class MyDialog: public wxDialog {
|
||||
// public:
|
||||
// MyDialog() : wxDialog(), keep_on_top_styler_(this) {}
|
||||
// ~MyDialog() override = default;
|
||||
|
||||
// private:
|
||||
// KeepOnTopStyler keep_on_top_styler_;
|
||||
// };
|
||||
class KeepOnTopStyler {
|
||||
public:
|
||||
// `window` must outlive this object. The easiest way to do so is to add
|
||||
// this object as a private member of the top-level window.
|
||||
explicit KeepOnTopStyler(wxTopLevelWindow* window);
|
||||
~KeepOnTopStyler();
|
||||
|
||||
// Disable copy and assignment.
|
||||
KeepOnTopStyler(const KeepOnTopStyler&) = delete;
|
||||
KeepOnTopStyler& operator=(const KeepOnTopStyler&) = delete;
|
||||
|
||||
private:
|
||||
// Callback for the `window` wxEVT_SHOW event.
|
||||
void OnShow(wxShowEvent& show_event);
|
||||
|
||||
// Callback fired when the KeepOnTop setting has changed.
|
||||
void OnKeepOnTopChanged(config::Option* option);
|
||||
|
||||
// The non-owned window whose style should be modified.
|
||||
wxTopLevelWindow *const window_;
|
||||
|
||||
// Observer for the KeepOnTop setting changed event.
|
||||
const config::OptionsObserver on_top_observer_;
|
||||
};
|
||||
|
||||
} // namespace widgets
|
||||
|
||||
#endif // VBAM_WX_DIALOGS_BASE_DIALOG_H_
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <wx/cmdline.h>
|
||||
#include <wx/display.h>
|
||||
#include <wx/file.h>
|
||||
#include <wx/filesys.h>
|
||||
#include <wx/fs_arc.h>
|
||||
|
@ -39,10 +40,10 @@
|
|||
|
||||
#ifdef __WXMSW__
|
||||
|
||||
int WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
int __stdcall WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
bool console_attached = AttachConsole(ATTACH_PARENT_PROCESS) != FALSE;
|
||||
#ifdef DEBUG
|
||||
// In debug builds, create a console if none is attached.
|
||||
|
@ -470,32 +471,45 @@ bool wxvbamApp::OnInit() {
|
|||
// and command line overrides have been applied.
|
||||
config::GameControlState::Instance().OnGameBindingsChanged();
|
||||
|
||||
// create the main window
|
||||
int x = OPTION(kGeomWindowX);
|
||||
int y = OPTION(kGeomWindowY);
|
||||
int width = OPTION(kGeomWindowHeight);
|
||||
int height = OPTION(kGeomWindowHeight);
|
||||
bool isFullscreen = OPTION(kGeomFullScreen);
|
||||
bool isMaximized = OPTION(kGeomIsMaximized);
|
||||
frame = wxDynamicCast(xr->LoadFrame(nullptr, "MainFrame"), MainFrame);
|
||||
// We need to gather this information before crating the MainFrame as the
|
||||
// OnSize / OnMove event handlers can fire during construction.
|
||||
const wxRect client_rect(
|
||||
OPTION(kGeomWindowX).Get(),
|
||||
OPTION(kGeomWindowY).Get(),
|
||||
OPTION(kGeomWindowWidth).Get(),
|
||||
OPTION(kGeomWindowHeight).Get());
|
||||
const bool is_fullscreen = OPTION(kGeomFullScreen);
|
||||
const bool is_maximized = OPTION(kGeomIsMaximized);
|
||||
|
||||
// Create the main window.
|
||||
frame = wxDynamicCast(xr->LoadFrame(nullptr, "MainFrame"), MainFrame);
|
||||
if (!frame) {
|
||||
wxLogError(_("Could not create main window"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create() cannot be overridden easily
|
||||
if (!frame->BindControls())
|
||||
if (!frame->BindControls()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (x >= 0 && y >= 0 && width > 0 && height > 0)
|
||||
frame->SetSize(x, y, width, height);
|
||||
// Measure the full display area.
|
||||
wxRect display_rect;
|
||||
for (unsigned int i = 0; i < wxDisplay::GetCount(); i++) {
|
||||
display_rect.Union(wxDisplay(i).GetClientArea());
|
||||
}
|
||||
|
||||
if (isMaximized)
|
||||
// Ensure we are not drawing out of bounds.
|
||||
if (display_rect.Intersects(client_rect)) {
|
||||
frame->SetSize(client_rect);
|
||||
}
|
||||
|
||||
if (is_maximized) {
|
||||
frame->Maximize();
|
||||
}
|
||||
if (is_fullscreen && wxGetApp().pending_load != wxEmptyString)
|
||||
frame->ShowFullScreen(is_fullscreen);
|
||||
|
||||
if (isFullscreen && wxGetApp().pending_load != wxEmptyString)
|
||||
frame->ShowFullScreen(isFullscreen);
|
||||
frame->Show(true);
|
||||
|
||||
#ifndef NO_ONLINEUPDATES
|
||||
|
@ -760,12 +774,12 @@ wxvbamApp::~wxvbamApp() {
|
|||
}
|
||||
|
||||
MainFrame::MainFrame()
|
||||
: wxFrame()
|
||||
, paused(false)
|
||||
, menus_opened(0)
|
||||
, dialog_opened(0)
|
||||
, focused(false)
|
||||
{
|
||||
: wxFrame(),
|
||||
paused(false),
|
||||
menus_opened(0),
|
||||
dialog_opened(0),
|
||||
focused(false),
|
||||
keep_on_top_styler_(this) {
|
||||
jpoll = new JoystickPoller();
|
||||
this->Connect(wxID_ANY, wxEVT_SHOW, wxShowEventHandler(JoystickPoller::ShowDialog), jpoll, jpoll);
|
||||
}
|
||||
|
@ -835,13 +849,10 @@ void MainFrame::OnMenu(wxContextMenuEvent& event)
|
|||
}
|
||||
|
||||
void MainFrame::OnMove(wxMoveEvent&) {
|
||||
wxPoint window_pos = GetScreenPosition();
|
||||
|
||||
if (!IsFullScreen() && !IsMaximized()) {
|
||||
if (window_pos.x >= 0 && window_pos.y >= 0) {
|
||||
OPTION(kGeomWindowX) = window_pos.x;
|
||||
OPTION(kGeomWindowY) = window_pos.y;
|
||||
}
|
||||
const wxPoint window_pos = GetScreenPosition();
|
||||
OPTION(kGeomWindowX) = window_pos.x;
|
||||
OPTION(kGeomWindowY) = window_pos.y;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -856,10 +867,8 @@ void MainFrame::OnSize(wxSizeEvent& event)
|
|||
OPTION(kGeomWindowHeight) = window_rect.GetHeight();
|
||||
OPTION(kGeomWindowWidth) = window_rect.GetWidth();
|
||||
}
|
||||
if (window_pos.x >= 0 && window_pos.y >= 0) {
|
||||
OPTION(kGeomWindowX) = window_pos.x;
|
||||
OPTION(kGeomWindowY) = window_pos.y;
|
||||
}
|
||||
OPTION(kGeomWindowX) = window_pos.x;
|
||||
OPTION(kGeomWindowY) = window_pos.y;
|
||||
}
|
||||
|
||||
OPTION(kGeomIsMaximized) = IsMaximized();
|
||||
|
@ -1161,7 +1170,7 @@ int MainFrame::ShowModal(wxDialog* dlg)
|
|||
{
|
||||
dlg->SetWindowStyle(dlg->GetWindowStyle() | wxCAPTION | wxRESIZE_BORDER);
|
||||
|
||||
if (gopts.keep_on_top)
|
||||
if (OPTION(kDispKeepOnTop))
|
||||
dlg->SetWindowStyle(dlg->GetWindowStyle() | wxSTAY_ON_TOP);
|
||||
else
|
||||
dlg->SetWindowStyle(dlg->GetWindowStyle() & ~wxSTAY_ON_TOP);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "config/option-observer.h"
|
||||
#include "widgets/dpi-support.h"
|
||||
#include "widgets/keep-on-top-styler.h"
|
||||
#include "wx/joyedit.h"
|
||||
#include "wx/keyedit.h"
|
||||
#include "wx/sdljoy.h"
|
||||
|
@ -212,7 +213,7 @@ extern bool pause_next;
|
|||
class MainFrame : public wxFrame {
|
||||
public:
|
||||
MainFrame();
|
||||
~MainFrame();
|
||||
~MainFrame() override;
|
||||
|
||||
bool BindControls();
|
||||
void MenuOptionIntMask(const wxString& menuName, int field, int mask);
|
||||
|
@ -361,14 +362,15 @@ private:
|
|||
// joystick reader
|
||||
wxJoyPoller joy;
|
||||
JoystickPoller* jpoll = nullptr;
|
||||
// quicker & more accurate than FindFocus() != NULL
|
||||
bool focused;
|
||||
const widgets::KeepOnTopStyler keep_on_top_styler_;
|
||||
|
||||
// helper function for adding menu to accel editor
|
||||
void add_menu_accels(wxTreeCtrl* tc, wxTreeItemId& parent, wxMenu* menu);
|
||||
|
||||
// for detecting window focus
|
||||
void OnActivate(wxActivateEvent&);
|
||||
// quicker & more accurate than FindFocus() != NULL
|
||||
bool focused;
|
||||
// may work, may not... if so, load dropped file
|
||||
void OnDropFile(wxDropFilesEvent&);
|
||||
// pop up menu in fullscreen mode
|
||||
|
@ -689,6 +691,7 @@ public:
|
|||
|
||||
private:
|
||||
wxTextCtrl* log;
|
||||
widgets::KeepOnTopStyler keep_on_top_styler_;
|
||||
void Save(wxCommandEvent& ev);
|
||||
void Clear(wxCommandEvent& ev);
|
||||
|
||||
|
|
Loading…
Reference in New Issue