forked from dolphin-emu/dolphin
		
	
		
			
				
	
	
		
			127 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// 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
 |