Play-/Source/ui_win32/PH_DirectInput/ControllerSettingsWnd.cpp
Jean-Philip Desjardins 52925f7ed6 Win32 cleanup build fix.
2017-01-09 22:01:09 -05:00

216 lines
6.4 KiB
C++

#include "ControllerSettingsWnd.h"
#include "win32/Rect.h"
#include "win32/DpiUtils.h"
#include "InputBindingSelectionWindow.h"
#include <vector>
#include <stdexcept>
#include <boost/lexical_cast.hpp>
#include "layout/LayoutEngine.h"
#include "string_cast.h"
#include "Types.h"
#include "placeholder_def.h"
#define CLSNAME _T("ContollerSettingsWnd")
#define WNDSTYLE (WS_CAPTION | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU)
#define WNDSTYLEEX (WS_EX_DLGMODALFRAME)
using namespace PH_DirectInput;
CControllerSettingsWnd::CControllerSettingsWnd(HWND parent, CInputManager& inputManager)
: CModalWindow(parent)
, m_inputManager(inputManager)
, m_autoConfigButton(NULL)
, m_bindingList(NULL)
, m_valuesCached(false)
{
if(!DoesWindowClassExist(CLSNAME))
{
WNDCLASSEX wc;
memset(&wc, 0, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = CLSNAME;
wc.lpfnWndProc = CWindow::WndProc;
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&wc);
}
auto windowRect = Framework::Win32::PointsToPixels(Framework::Win32::CRect(0, 0, 550, 400));
Create(WNDSTYLEEX, CLSNAME, _T("Controller Settings"), WNDSTYLE, windowRect, parent, NULL);
SetClassPtr();
m_bindingList = new Framework::Win32::CListView(m_hWnd, Framework::Win32::CRect(0, 0, 1, 1), LVS_REPORT | LVS_NOSORTHEADER);
m_ok = new Framework::Win32::CButton(_T("OK"), m_hWnd, Framework::Win32::CRect(0, 0, 1, 1));
m_cancel = new Framework::Win32::CButton(_T("Cancel"), m_hWnd, Framework::Win32::CRect(0, 0, 1, 1));
m_autoConfigButton = new Framework::Win32::CButton(_T("Auto Config"), m_hWnd, Framework::Win32::CRect(0, 0, 1, 1));
m_bindingList->SetExtendedListViewStyle(m_bindingList->GetExtendedListViewStyle() | LVS_EX_FULLROWSELECT);
m_layout =
Framework::VerticalLayoutContainer(
Framework::Win32::CLayoutWindow::CreateCustomBehavior(100, 100, 1, 1, m_bindingList) +
Framework::HorizontalLayoutContainer(
Framework::Win32::CLayoutWindow::CreateButtonBehavior(Framework::Win32::PointsToPixels(100), Framework::Win32::PointsToPixels(23), m_autoConfigButton) +
Framework::CLayoutStretch::Create() +
Framework::Win32::CLayoutWindow::CreateButtonBehavior(Framework::Win32::PointsToPixels(100), Framework::Win32::PointsToPixels(23), m_ok) +
Framework::Win32::CLayoutWindow::CreateButtonBehavior(Framework::Win32::PointsToPixels(100), Framework::Win32::PointsToPixels(23), m_cancel)
)
);
m_inputManager.PushFocusWindow(m_hWnd);
RefreshLayout();
PopulateList();
UpdateBindings();
UpdateBindingValues();
SetTimer(m_hWnd, 0, 16, NULL);
}
CControllerSettingsWnd::~CControllerSettingsWnd()
{
m_inputManager.PopFocusWindow();
}
void CControllerSettingsWnd::RefreshLayout()
{
RECT rc = GetClientRect();
auto margin = Framework::Win32::PointsToPixels(10);
SetRect(&rc, rc.left + margin, rc.top + margin, rc.right - margin, rc.bottom - margin);
m_layout->SetRect(rc.left, rc.top, rc.right, rc.bottom);
m_layout->RefreshGeometry();
Redraw();
}
long CControllerSettingsWnd::OnCommand(unsigned short id, unsigned short cmd, HWND from)
{
if(m_autoConfigButton && from == m_autoConfigButton->m_hWnd)
{
AutoConfigKeyboard();
}
if(CWindow::IsCommandSource(m_ok, from))
{
m_inputManager.Save();
Destroy();
}
if(CWindow::IsCommandSource(m_cancel, from))
{
m_inputManager.Load();
Destroy();
}
return TRUE;
}
LRESULT CControllerSettingsWnd::OnNotify(WPARAM param, NMHDR* header)
{
if(m_bindingList && m_bindingList->m_hWnd == header->hwndFrom)
{
if(header->code == NM_DBLCLK)
{
OnListItemDblClick();
}
}
return FALSE;
}
long CControllerSettingsWnd::OnTimer(WPARAM)
{
UpdateBindingValues();
return FALSE;
}
void CControllerSettingsWnd::AutoConfigKeyboard()
{
m_inputManager.AutoConfigureKeyboard();
UpdateBindings();
}
void CControllerSettingsWnd::UpdateBindings()
{
for(int i = 0; i < m_bindingList->GetItemCount(); i++)
{
PS2::CControllerInfo::BUTTON button = static_cast<PS2::CControllerInfo::BUTTON>(m_bindingList->GetItemData(i));
std::tstring description = m_inputManager.GetBindingDescription(button);
m_bindingList->SetItemText(i, 1, description.c_str());
}
}
void CControllerSettingsWnd::UpdateBindingValues()
{
for(unsigned int i = 0; i < PS2::CControllerInfo::MAX_BUTTONS; i++)
{
PS2::CControllerInfo::BUTTON button = static_cast<PS2::CControllerInfo::BUTTON>(m_bindingList->GetItemData(i));
int listViewIndex = m_bindingList->FindItemData(button);
if(listViewIndex == -1) continue;
uint32 value = m_inputManager.GetBindingValue(button);
if(m_valuesCached && m_cachedValues[button] == value) continue;
m_cachedValues[button] = value;
if(PS2::CControllerInfo::IsAxis(button))
{
m_bindingList->SetItemText(listViewIndex, 2, boost::lexical_cast<std::tstring>(value).c_str());
}
else
{
m_bindingList->SetItemText(listViewIndex, 2, value ? _T("pressed") : _T(""));
}
}
m_valuesCached = true;
}
void CControllerSettingsWnd::OnListItemDblClick()
{
int selection = m_bindingList->GetSelection();
if(selection == -1) return;
{
PS2::CControllerInfo::BUTTON button = static_cast<PS2::CControllerInfo::BUTTON>(m_bindingList->GetItemData(selection));
if(button < PS2::CControllerInfo::MAX_BUTTONS)
{
CInputBindingSelectionWindow dialog(m_hWnd, m_inputManager, button);
dialog.DoModal();
UpdateBindings();
m_inputManager.ResetBindingValues();
}
}
}
void CControllerSettingsWnd::PopulateList()
{
LVCOLUMN column;
RECT rc = m_bindingList->GetClientRect();
memset(&column, 0, sizeof(LVCOLUMN));
column.pszText = _T("Button");
column.mask = LVCF_TEXT | LVCF_WIDTH;
column.cx = 1 * rc.right / 5;
m_bindingList->InsertColumn(0, column);
memset(&column, 0, sizeof(LVCOLUMN));
column.pszText = _T("Binding");
column.mask = LVCF_TEXT | LVCF_WIDTH;
column.cx = 3 * rc.right / 5;
m_bindingList->InsertColumn(1, column);
memset(&column, 0, sizeof(LVCOLUMN));
column.pszText = _T("Current Value");
column.mask = LVCF_TEXT | LVCF_WIDTH;
column.cx = 1 * rc.right / 5;
m_bindingList->InsertColumn(2, column);
for(int i = PS2::CControllerInfo::MAX_BUTTONS - 1; i >= 0; i--)
{
std::tstring text = string_cast<std::tstring>(PS2::CControllerInfo::m_buttonName[i]);
LVITEM itm;
memset(&itm, 0, sizeof(LVITEM));
itm.mask = LVIF_TEXT | LVIF_PARAM;
itm.pszText = const_cast<TCHAR*>(text.c_str());
itm.lParam = i;
m_bindingList->InsertItem(itm);
}
}