425 lines
14 KiB
C++
425 lines
14 KiB
C++
/********************************************************************************
|
|
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
|
********************************************************************************/
|
|
|
|
#define NOMINMAX
|
|
#include "Main.h"
|
|
#include "Settings.h"
|
|
|
|
//============================================================================
|
|
// Helpers
|
|
|
|
int LoadSettingEditInt(HWND hwnd, CTSTR lpConfigSection, CTSTR lpConfigName, int defVal)
|
|
{
|
|
int iLoadVal;
|
|
if(!AppConfig->HasKey(lpConfigSection, lpConfigName))
|
|
{
|
|
AppConfig->SetInt(lpConfigSection, lpConfigName, defVal);
|
|
iLoadVal = defVal;
|
|
}
|
|
else
|
|
iLoadVal = AppConfig->GetInt(lpConfigSection, lpConfigName, defVal);
|
|
|
|
SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)IntString(iLoadVal).Array());
|
|
|
|
return iLoadVal;
|
|
}
|
|
|
|
String LoadSettingEditString(HWND hwnd, CTSTR lpConfigSection, CTSTR lpConfigName, CTSTR lpDefault)
|
|
{
|
|
String strLoadVal;
|
|
if(!AppConfig->HasKey(lpConfigSection, lpConfigName))
|
|
{
|
|
if(lpDefault)
|
|
AppConfig->SetString(lpConfigSection, lpConfigName, lpDefault);
|
|
|
|
strLoadVal = lpDefault;
|
|
}
|
|
else
|
|
strLoadVal = AppConfig->GetString(lpConfigSection, lpConfigName, lpDefault);
|
|
|
|
SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)strLoadVal.Array());
|
|
|
|
return strLoadVal;
|
|
}
|
|
|
|
int LoadSettingComboInt(HWND hwnd, CTSTR lpConfigSection, CTSTR lpConfigName, int defVal, int maxVal)
|
|
{
|
|
int curVal = AppConfig->GetInt(lpConfigSection, lpConfigName, defVal);
|
|
int id = curVal;
|
|
|
|
if(!AppConfig->HasKey(lpConfigSection, lpConfigName) || curVal < 0 || (maxVal != 0 && curVal > maxVal))
|
|
{
|
|
AppConfig->SetInt(lpConfigSection, lpConfigName, defVal);
|
|
curVal = defVal;
|
|
}
|
|
|
|
SendMessage(hwnd, CB_SETCURSEL, (WPARAM)id, 0);
|
|
|
|
return curVal;
|
|
}
|
|
|
|
String LoadSettingComboString(HWND hwnd, CTSTR lpConfigSection, CTSTR lpConfigName, CTSTR lpDefault)
|
|
{
|
|
String strVal = AppConfig->GetString(lpConfigSection, lpConfigName, lpDefault);
|
|
int id = (int)SendMessage(hwnd, CB_FINDSTRINGEXACT, 0, (LPARAM)strVal.Array());
|
|
if(!AppConfig->HasKey(lpConfigSection, lpConfigName) || id == CB_ERR)
|
|
{
|
|
if(lpDefault)
|
|
{
|
|
AppConfig->SetString(lpConfigSection, lpConfigName, lpDefault);
|
|
|
|
if(id == CB_ERR)
|
|
{
|
|
id = (int)SendMessage(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)lpDefault);
|
|
strVal = lpDefault;
|
|
}
|
|
}
|
|
else
|
|
id = 0;
|
|
}
|
|
|
|
SendMessage(hwnd, CB_SETCURSEL, (WPARAM)id, 0);
|
|
|
|
return strVal;
|
|
}
|
|
|
|
String LoadSettingTextComboString(HWND hwnd, CTSTR lpConfigSection, CTSTR lpConfigName, CTSTR lpDefault)
|
|
{
|
|
String strVal = AppConfig->GetString(lpConfigSection, lpConfigName, lpDefault);
|
|
int id = (int)SendMessage(hwnd, CB_FINDSTRINGEXACT, -1, (LPARAM)strVal.Array());
|
|
if(!AppConfig->HasKey(lpConfigSection, lpConfigName))
|
|
{
|
|
if(lpDefault)
|
|
AppConfig->SetString(lpConfigSection, lpConfigName, lpDefault);
|
|
}
|
|
|
|
SendMessage(hwnd, CB_SETCURSEL, (WPARAM)id, 0);
|
|
|
|
return strVal;
|
|
}
|
|
|
|
//============================================================================
|
|
|
|
void OBS::AddSettingsPane(SettingsPane *pane)
|
|
{
|
|
settingsPanes.Add(pane);
|
|
}
|
|
|
|
void OBS::RemoveSettingsPane(SettingsPane *pane)
|
|
{
|
|
settingsPanes.RemoveItem(pane);
|
|
}
|
|
|
|
template <class T, class U>
|
|
static inline void saturate(T &t, U val)
|
|
{
|
|
if (val > std::numeric_limits<T>::max())
|
|
t = std::numeric_limits<T>::max();
|
|
else if (val < std::numeric_limits<T>::min())
|
|
t = std::numeric_limits<T>::min();
|
|
else
|
|
t = static_cast<T>(val);
|
|
}
|
|
|
|
void OBS::AddBuiltInSettingsPanes()
|
|
{
|
|
SettingsPane *panes[] = {
|
|
new SettingsGeneral(),
|
|
new SettingsEncoding(),
|
|
new SettingsPublish(),
|
|
new SettingsVideo(),
|
|
new SettingsAudio(),
|
|
new SettingsHotkeys(),
|
|
new SettingsAdvanced(),
|
|
};
|
|
|
|
for (auto pane : panes)
|
|
AddSettingsPane(pane);
|
|
saturate(numberOfBuiltInSettingsPanes, std::distance(std::begin(panes), std::end(panes)));
|
|
}
|
|
|
|
void OBS::AddEncoderSettingsPanes()
|
|
{
|
|
SettingsPane *panes[] = {
|
|
new SettingsQSV(),
|
|
};
|
|
|
|
for (auto pane : panes)
|
|
AddSettingsPane(pane);
|
|
saturate(numberOfEncoderSettingsPanes, std::distance(std::begin(panes), std::end(panes)));
|
|
}
|
|
|
|
void OBS::SetChangedSettings(bool bChanged)
|
|
{
|
|
if(hwndSettings == NULL)
|
|
return;
|
|
EnableWindow(GetDlgItem(hwndSettings, IDC_APPLY), (bSettingsChanged = bChanged));
|
|
}
|
|
|
|
void OBS::SetAbortApplySettings(bool abort)
|
|
{
|
|
bApplySettingsAborted = abort;
|
|
}
|
|
|
|
void OBS::CancelSettings()
|
|
{
|
|
if(App->currentSettingsPane != NULL)
|
|
App->currentSettingsPane->CancelSettings();
|
|
}
|
|
|
|
void OBS::ApplySettings()
|
|
{
|
|
bApplySettingsAborted = false;
|
|
if(App->currentSettingsPane != NULL)
|
|
App->currentSettingsPane->ApplySettings();
|
|
if (bApplySettingsAborted)
|
|
return;
|
|
|
|
bSettingsChanged = false;
|
|
EnableWindow(GetDlgItem(hwndSettings, IDC_APPLY), FALSE);
|
|
}
|
|
|
|
void OBS::SetCanOptimizeSettings(bool canOptimize)
|
|
{
|
|
if (hwndSettings == NULL)
|
|
return;
|
|
ShowWindow(GetDlgItem(hwndSettings, IDC_OPTIMIZE), canOptimize);
|
|
}
|
|
|
|
void OBS::OptimizeSettings()
|
|
{
|
|
if (!App->currentSettingsPane)
|
|
return;
|
|
App->currentSettingsPane->OptimizeSettings();
|
|
}
|
|
|
|
INT_PTR CALLBACK OBS::SettingsDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
App->hwndSettings = hwnd;
|
|
|
|
LocalizeWindow(hwnd);
|
|
|
|
// Add setting categories from the pane list
|
|
for(unsigned int i = 0; i < App->settingsPanes.Num(); i++)
|
|
{
|
|
SettingsPane *pane = App->settingsPanes[i];
|
|
if(pane == NULL)
|
|
continue;
|
|
SendMessage(GetDlgItem(hwnd, IDC_SETTINGSLIST), LB_ADDSTRING, 0, (LPARAM)pane->GetCategory());
|
|
}
|
|
|
|
RECT subDialogRect;
|
|
GetWindowRect(GetDlgItem(hwnd, IDC_SUBDIALOG), &subDialogRect);
|
|
MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&subDialogRect, 2);
|
|
|
|
SendMessage(GetDlgItem(hwnd, IDC_SETTINGSLIST), LB_SETCURSEL, 0, 0);
|
|
|
|
// Load the first settings pane from the list
|
|
App->curSettingsSelection = 0;
|
|
App->hwndCurrentSettings = NULL;
|
|
App->currentSettingsPane = NULL;
|
|
|
|
if(App->settingsPanes.Num() >= 1)
|
|
App->currentSettingsPane = App->settingsPanes[0];
|
|
|
|
if(App->currentSettingsPane != NULL)
|
|
App->hwndCurrentSettings = App->currentSettingsPane->CreatePane(hwnd);
|
|
|
|
if(App->hwndCurrentSettings != NULL)
|
|
{
|
|
SetWindowPos(App->hwndCurrentSettings, NULL,
|
|
subDialogRect.left, subDialogRect.top,
|
|
subDialogRect.right - subDialogRect.left,
|
|
subDialogRect.bottom - subDialogRect.top,
|
|
SWP_NOZORDER);
|
|
ShowWindow(App->hwndCurrentSettings, SW_SHOW);
|
|
ShowWindow(GetDlgItem(hwnd, IDC_DEFAULTS), App->currentSettingsPane->HasDefaults());
|
|
ShowWindow(GetDlgItem(hwnd, IDC_OPTIMIZE), false);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
case WM_DRAWITEM:
|
|
PDRAWITEMSTRUCT pdis;
|
|
pdis = (PDRAWITEMSTRUCT) lParam;
|
|
|
|
if(pdis->CtlID != IDC_SETTINGSLIST || pdis->itemID == -1)
|
|
break;
|
|
|
|
switch(pdis->itemAction)
|
|
{
|
|
case ODA_SELECT:
|
|
case ODA_DRAWENTIRE:
|
|
{
|
|
int cy, bkMode;
|
|
TEXTMETRIC tm;
|
|
COLORREF oldTextColor;
|
|
TCHAR itemText[MAX_PATH];
|
|
|
|
oldTextColor = GetTextColor(pdis->hDC);
|
|
|
|
if(pdis->itemState & ODS_SELECTED)
|
|
{
|
|
FillRect(pdis->hDC, &pdis->rcItem, (HBRUSH)(COLOR_HIGHLIGHT + 1));
|
|
SetTextColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
|
|
}
|
|
else
|
|
{
|
|
FillRect(pdis->hDC, &pdis->rcItem, (HBRUSH)(COLOR_WINDOW + 1));
|
|
SetTextColor(pdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
|
|
}
|
|
|
|
SendMessage(pdis->hwndItem, LB_GETTEXT, pdis->itemID, (LPARAM)itemText);
|
|
|
|
GetTextMetrics(pdis->hDC, &tm);
|
|
cy = (pdis->rcItem.bottom + pdis->rcItem.top - tm.tmHeight) / 2;
|
|
|
|
bkMode = SetBkMode(pdis->hDC, TRANSPARENT);
|
|
|
|
if(slen(itemText) > 0)
|
|
TextOut(pdis->hDC, 6, cy, itemText, slen(itemText));
|
|
|
|
SetBkMode(pdis->hDC, bkMode);
|
|
SetTextColor(pdis->hDC, oldTextColor);
|
|
|
|
UINT builtinAndEncoderPanes = App->numberOfBuiltInSettingsPanes + App->numberOfEncoderSettingsPanes;
|
|
|
|
if ((App->settingsPanes.Num() > (UINT)App->numberOfBuiltInSettingsPanes && pdis->itemID == App->numberOfBuiltInSettingsPanes)
|
|
|| (App->settingsPanes.Num() > (UINT)builtinAndEncoderPanes && pdis->itemID == builtinAndEncoderPanes))
|
|
{
|
|
HGDIOBJ origPen;
|
|
origPen = SelectObject(pdis->hDC, GetStockObject(DC_PEN));
|
|
SetDCPenColor(pdis->hDC, GetSysColor(COLOR_BTNSHADOW));
|
|
|
|
MoveToEx(pdis->hDC, pdis->rcItem.left, pdis->rcItem.top, NULL);
|
|
LineTo(pdis->hDC, pdis->rcItem.right, pdis->rcItem.top);
|
|
|
|
SelectObject(pdis->hDC, origPen);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case ODA_FOCUS:
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_SETTINGSLIST:
|
|
{
|
|
if(HIWORD(wParam) != LBN_SELCHANGE)
|
|
break;
|
|
|
|
int sel = (int)SendMessage((HWND)lParam, LB_GETCURSEL, 0, 0);
|
|
|
|
// No need to continue if we're on the same panel
|
|
if(sel == App->curSettingsSelection)
|
|
break;
|
|
|
|
if(App->bSettingsChanged)
|
|
{
|
|
int id = OBSMessageBox(hwnd, Str("Settings.SaveChangesPrompt"), Str("Settings.SaveChangesTitle"), MB_YESNOCANCEL);
|
|
|
|
if (id == IDNO)
|
|
App->CancelSettings();
|
|
|
|
if(id == IDCANCEL)
|
|
{
|
|
SendMessage((HWND)lParam, LB_SETCURSEL, App->curSettingsSelection, 0);
|
|
break;
|
|
}
|
|
else if(id == IDYES)
|
|
App->ApplySettings();
|
|
}
|
|
|
|
App->curSettingsSelection = sel;
|
|
|
|
if(App->currentSettingsPane != NULL)
|
|
App->currentSettingsPane->DestroyPane();
|
|
App->currentSettingsPane = NULL;
|
|
App->hwndCurrentSettings = NULL;
|
|
ShowWindow(GetDlgItem(hwnd, IDC_OPTIMIZE), false);
|
|
|
|
RECT subDialogRect;
|
|
GetWindowRect(GetDlgItem(hwnd, IDC_SUBDIALOG), &subDialogRect);
|
|
MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&subDialogRect, 2);
|
|
|
|
if(sel >= 0 && sel < (int)App->settingsPanes.Num())
|
|
App->currentSettingsPane = App->settingsPanes[sel];
|
|
if(App->currentSettingsPane != NULL)
|
|
App->hwndCurrentSettings = App->currentSettingsPane->CreatePane(hwnd);
|
|
if(App->hwndCurrentSettings)
|
|
{
|
|
SetWindowPos(App->hwndCurrentSettings, NULL,
|
|
subDialogRect.left, subDialogRect.top,
|
|
subDialogRect.right - subDialogRect.left,
|
|
subDialogRect.bottom - subDialogRect.top,
|
|
SWP_NOZORDER);
|
|
ShowWindow(App->hwndCurrentSettings, SW_SHOW);
|
|
|
|
ShowWindow(GetDlgItem(hwnd, IDC_DEFAULTS), App->currentSettingsPane->HasDefaults());
|
|
SetFocus(GetDlgItem(hwnd, IDC_SETTINGSLIST));
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case IDC_DEFAULTS:
|
|
App->currentSettingsPane->SetDefaults();
|
|
break;
|
|
|
|
case IDOK:
|
|
if(App->bSettingsChanged)
|
|
App->ApplySettings();
|
|
if (App->bApplySettingsAborted)
|
|
break;
|
|
EndDialog(hwnd, IDOK);
|
|
App->hwndSettings = NULL;
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
if(App->bSettingsChanged)
|
|
App->CancelSettings();
|
|
EndDialog(hwnd, IDCANCEL);
|
|
App->hwndSettings = NULL;
|
|
break;
|
|
|
|
case IDC_APPLY:
|
|
if(App->bSettingsChanged)
|
|
App->ApplySettings();
|
|
break;
|
|
|
|
case IDC_OPTIMIZE:
|
|
App->OptimizeSettings();
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|