mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
WX: HiDPI Support Framework
Portable flexible HiDPI image loading and other support for Windows/GTK/OSX.
This commit is contained in:
126
Source/Core/DolphinWX/DolphinSlider.cpp
Normal file
126
Source/Core/DolphinWX/DolphinSlider.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
// Copyright 2016 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <wx/utils.h>
|
||||
|
||||
#include "DolphinWX/DolphinSlider.h"
|
||||
|
||||
#ifdef __WXMSW__
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
// clang-format off
|
||||
#include <Windows.h>
|
||||
#include <CommCtrl.h>
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
static constexpr int SLIDER_MIN_LENGTH = 100;
|
||||
|
||||
DolphinSlider::DolphinSlider() = default;
|
||||
DolphinSlider::~DolphinSlider() = default;
|
||||
|
||||
bool DolphinSlider::Create(wxWindow* parent, wxWindowID id, int value, int min_val, int max_val,
|
||||
const wxPoint& pos, const wxSize& size, long style,
|
||||
const wxValidator& validator, const wxString& name)
|
||||
{
|
||||
// Sanitize the style flags.
|
||||
// We don't want any label flags because those break DPI scaling on wxMSW,
|
||||
// wxWidgets will internally lock the height of the slider to 32 pixels.
|
||||
style &= ~wxSL_LABELS;
|
||||
|
||||
return wxSlider::Create(parent, id, value, min_val, max_val, pos, size, style, validator, name);
|
||||
}
|
||||
|
||||
wxSize DolphinSlider::DoGetBestClientSize() const
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
int ticks = 0;
|
||||
int default_length = FromDIP(SLIDER_MIN_LENGTH);
|
||||
if (HasFlag(wxSL_TICKS))
|
||||
{
|
||||
// NOTE: Ticks do not scale at all (on Win7)
|
||||
default_length += 4;
|
||||
ticks = 6;
|
||||
}
|
||||
|
||||
int metric = 0;
|
||||
{
|
||||
// We need to determine the maximum thumb size because unfortunately the thumb size
|
||||
// is controlled by the theme so may have a varying maximum size limit.
|
||||
// NOTE: We can't use ourself because we're const so we can't change our size.
|
||||
// NOTE: This is less inefficient then it seems, DoGetBestSize() is only called once
|
||||
// per instance and cached until InvalidateBestSize() is called.
|
||||
wxSlider* helper = new wxSlider(GetParent(), wxID_ANY, GetValue(), GetMin(), GetMax(),
|
||||
wxDefaultPosition, FromDIP(wxSize(100, 100)), GetWindowStyle());
|
||||
::RECT r{};
|
||||
::SendMessageW(reinterpret_cast<HWND>(helper->GetHWND()), TBM_GETTHUMBRECT, 0,
|
||||
reinterpret_cast<LPARAM>(&r));
|
||||
helper->Destroy();
|
||||
|
||||
// Breakdown metrics
|
||||
int computed_size;
|
||||
int scroll_size;
|
||||
if (HasFlag(wxSL_VERTICAL))
|
||||
{
|
||||
// Trackbar thumb does not directly touch the edge, we add the padding
|
||||
// a second time to pad the other edge to make it symmetric.
|
||||
computed_size = static_cast<int>(r.right + r.left);
|
||||
scroll_size = ::GetSystemMetrics(SM_CXVSCROLL);
|
||||
}
|
||||
else
|
||||
{
|
||||
computed_size = static_cast<int>(r.bottom + r.top);
|
||||
scroll_size = ::GetSystemMetrics(SM_CYHSCROLL);
|
||||
}
|
||||
|
||||
// This is based on how Microsoft calculates trackbar sizes in the .Net Framework
|
||||
// when using automatic sizing in WinForms.
|
||||
int max = scroll_size * 2;
|
||||
|
||||
metric = wxClip(computed_size, scroll_size, max);
|
||||
}
|
||||
|
||||
if (HasFlag(wxSL_VERTICAL))
|
||||
return wxSize(metric + ticks, default_length);
|
||||
return wxSize(default_length, metric + ticks);
|
||||
#else
|
||||
wxSize base_size = wxSlider::DoGetBestClientSize();
|
||||
// If the base class is not using DoGetBestClientSize(), fallback to DoGetBestSize()
|
||||
if (base_size == wxDefaultSize)
|
||||
return wxDefaultSize;
|
||||
return CorrectMinSize(base_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
wxSize DolphinSlider::DoGetBestSize() const
|
||||
{
|
||||
return CorrectMinSize(wxSlider::DoGetBestSize());
|
||||
}
|
||||
|
||||
wxSize DolphinSlider::CorrectMinSize(wxSize size) const
|
||||
{
|
||||
wxSize default_length = FromDIP(wxSize(SLIDER_MIN_LENGTH, SLIDER_MIN_LENGTH));
|
||||
// GTK Styles sometimes don't return a default length.
|
||||
// NOTE: Vertical is the dominant flag if both are set.
|
||||
if (HasFlag(wxSL_VERTICAL))
|
||||
{
|
||||
if (size.GetHeight() < default_length.GetHeight())
|
||||
{
|
||||
size.SetHeight(default_length.GetHeight());
|
||||
}
|
||||
}
|
||||
else if (size.GetWidth() < default_length.GetWidth())
|
||||
{
|
||||
size.SetWidth(default_length.GetWidth());
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
#ifdef __WXMSW__
|
||||
WXLRESULT DolphinSlider::MSWWindowProc(WXUINT msg, WXWPARAM wp, WXLPARAM lp)
|
||||
{
|
||||
if (msg == WM_THEMECHANGED)
|
||||
InvalidateBestSize();
|
||||
return wxSlider::MSWWindowProc(msg, wp, lp);
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user