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
							 |