aboutsummaryrefslogtreecommitdiff
path: root/src/settings/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/settings/windows')
-rw-r--r--src/settings/windows/GUIControlSettings.cpp1138
-rw-r--r--src/settings/windows/GUIControlSettings.h225
-rw-r--r--src/settings/windows/GUIWindowSettings.cpp33
-rw-r--r--src/settings/windows/GUIWindowSettings.h31
-rw-r--r--src/settings/windows/GUIWindowSettingsCategory.cpp206
-rw-r--r--src/settings/windows/GUIWindowSettingsCategory.h53
-rw-r--r--src/settings/windows/GUIWindowSettingsScreenCalibration.cpp428
-rw-r--r--src/settings/windows/GUIWindowSettingsScreenCalibration.h48
-rw-r--r--src/settings/windows/GUIWindowTestPattern.cpp140
-rw-r--r--src/settings/windows/GUIWindowTestPattern.h60
-rw-r--r--src/settings/windows/Makefile10
11 files changed, 2372 insertions, 0 deletions
diff --git a/src/settings/windows/GUIControlSettings.cpp b/src/settings/windows/GUIControlSettings.cpp
new file mode 100644
index 0000000000..aa003a90ca
--- /dev/null
+++ b/src/settings/windows/GUIControlSettings.cpp
@@ -0,0 +1,1138 @@
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <set>
+
+#include "GUIControlSettings.h"
+#include "FileItem.h"
+#include "Util.h"
+#include "addons/AddonManager.h"
+#include "addons/GUIWindowAddonBrowser.h"
+#include "dialogs/GUIDialogFileBrowser.h"
+#include "dialogs/GUIDialogOK.h"
+#include "dialogs/GUIDialogSelect.h"
+#include "dialogs/GUIDialogSlider.h"
+#include "guilib/GUIEditControl.h"
+#include "guilib/GUIImage.h"
+#include "guilib/GUIRadioButtonControl.h"
+#include "guilib/GUISettingsSliderControl.h"
+#include "guilib/GUISpinControlEx.h"
+#include "guilib/GUIWindowManager.h"
+#include "guilib/LocalizeStrings.h"
+#include "settings/SettingAddon.h"
+#include "settings/SettingControl.h"
+#include "settings/SettingPath.h"
+#include "settings/Settings.h"
+#include "settings/SettingUtils.h"
+#include "settings/MediaSourceSettings.h"
+#include "settings/lib/Setting.h"
+#include "storage/MediaManager.h"
+#include "utils/StringUtils.h"
+
+using namespace ADDON;
+
+CGUIControlBaseSetting::CGUIControlBaseSetting(int id, CSetting *pSetting)
+ : m_id(id),
+ m_pSetting(pSetting),
+ m_delayed(false),
+ m_valid(true)
+{ }
+
+bool CGUIControlBaseSetting::IsEnabled() const
+{
+ return m_pSetting != NULL && m_pSetting->IsEnabled();
+}
+
+void CGUIControlBaseSetting::Update(bool updateDisplayOnly /* = false */)
+{
+ if (updateDisplayOnly)
+ return;
+
+ CGUIControl *control = GetControl();
+ if (control == NULL)
+ return;
+
+ control->SetEnabled(IsEnabled());
+ if (m_pSetting)
+ control->SetVisible(m_pSetting->IsVisible());
+ SetValid(true);
+}
+
+CGUIControlRadioButtonSetting::CGUIControlRadioButtonSetting(CGUIRadioButtonControl *pRadioButton, int id, CSetting *pSetting)
+ : CGUIControlBaseSetting(id, pSetting)
+{
+ m_pRadioButton = pRadioButton;
+ if (m_pRadioButton == NULL)
+ return;
+
+ m_pRadioButton->SetID(id);
+ Update();
+}
+
+CGUIControlRadioButtonSetting::~CGUIControlRadioButtonSetting()
+{ }
+
+bool CGUIControlRadioButtonSetting::OnClick()
+{
+ SetValid(((CSettingBool *)m_pSetting)->SetValue(!((CSettingBool *)m_pSetting)->GetValue()));
+ return IsValid();
+}
+
+void CGUIControlRadioButtonSetting::Update(bool updateDisplayOnly /* = false */)
+{
+ if (m_pRadioButton == NULL)
+ return;
+
+ CGUIControlBaseSetting::Update();
+
+ m_pRadioButton->SetSelected(((CSettingBool *)m_pSetting)->GetValue());
+}
+
+CGUIControlSpinExSetting::CGUIControlSpinExSetting(CGUISpinControlEx *pSpin, int id, CSetting *pSetting)
+ : CGUIControlBaseSetting(id, pSetting)
+{
+ m_pSpin = pSpin;
+ if (m_pSpin == NULL)
+ return;
+
+ m_pSpin->SetID(id);
+
+ FillControl();
+}
+
+CGUIControlSpinExSetting::~CGUIControlSpinExSetting()
+{ }
+
+bool CGUIControlSpinExSetting::OnClick()
+{
+ if (m_pSpin == NULL)
+ return false;
+
+ switch (m_pSetting->GetType())
+ {
+ case SettingTypeInteger:
+ SetValid(((CSettingInt *)m_pSetting)->SetValue(m_pSpin->GetValue()));
+ break;
+
+ case SettingTypeNumber:
+ SetValid(((CSettingNumber *)m_pSetting)->SetValue(m_pSpin->GetFloatValue()));
+ break;
+
+ case SettingTypeString:
+ SetValid(((CSettingString *)m_pSetting)->SetValue(m_pSpin->GetStringValue()));
+ break;
+
+ default:
+ return false;
+ }
+
+ return IsValid();
+}
+
+void CGUIControlSpinExSetting::Update(bool updateDisplayOnly /* = false */)
+{
+ if (updateDisplayOnly || m_pSpin == NULL)
+ return;
+
+ CGUIControlBaseSetting::Update();
+
+ FillControl();
+
+ // disable the spinner if it has less than two items
+ if (!m_pSpin->IsDisabled() && (m_pSpin->GetMaximum() - m_pSpin->GetMinimum()) == 0)
+ m_pSpin->SetEnabled(false);
+}
+
+void CGUIControlSpinExSetting::FillControl()
+{
+ if (m_pSpin == NULL)
+ return;
+
+ m_pSpin->Clear();
+
+ const std::string &controlFormat = m_pSetting->GetControl()->GetFormat();
+ if (controlFormat == "number")
+ {
+ CSettingNumber *pSettingNumber = (CSettingNumber *)m_pSetting;
+ m_pSpin->SetType(SPIN_CONTROL_TYPE_FLOAT);
+ m_pSpin->SetFloatRange((float)pSettingNumber->GetMinimum(), (float)pSettingNumber->GetMaximum());
+ m_pSpin->SetFloatInterval((float)pSettingNumber->GetStep());
+
+ m_pSpin->SetFloatValue((float)pSettingNumber->GetValue());
+ }
+ else if (controlFormat == "integer")
+ {
+ m_pSpin->SetType(SPIN_CONTROL_TYPE_TEXT);
+ FillIntegerSettingControl();
+ }
+ else if (controlFormat == "string")
+ {
+ m_pSpin->SetType(SPIN_CONTROL_TYPE_TEXT);
+
+ if (m_pSetting->GetType() == SettingTypeInteger)
+ FillIntegerSettingControl();
+ else if (m_pSetting->GetType() == SettingTypeString)
+ {
+ CSettingString *pSettingString = (CSettingString *)m_pSetting;
+ if (pSettingString->GetOptionsType() == SettingOptionsTypeDynamic)
+ {
+ DynamicStringSettingOptions options = pSettingString->UpdateDynamicOptions();
+ for (std::vector< std::pair<std::string, std::string> >::const_iterator option = options.begin(); option != options.end(); ++option)
+ m_pSpin->AddLabel(option->first, option->second);
+
+ m_pSpin->SetStringValue(pSettingString->GetValue());
+ }
+ }
+ }
+}
+
+void CGUIControlSpinExSetting::FillIntegerSettingControl()
+{
+ CSettingInt *pSettingInt = (CSettingInt *)m_pSetting;
+ switch (pSettingInt->GetOptionsType())
+ {
+ case SettingOptionsTypeStatic:
+ {
+ const StaticIntegerSettingOptions& options = pSettingInt->GetOptions();
+ for (StaticIntegerSettingOptions::const_iterator it = options.begin(); it != options.end(); ++it)
+ m_pSpin->AddLabel(g_localizeStrings.Get(it->first), it->second);
+
+ break;
+ }
+
+ case SettingOptionsTypeDynamic:
+ {
+ DynamicIntegerSettingOptions options = pSettingInt->UpdateDynamicOptions();
+ for (DynamicIntegerSettingOptions::const_iterator option = options.begin(); option != options.end(); ++option)
+ m_pSpin->AddLabel(option->first, option->second);
+
+ break;
+ }
+
+ case SettingOptionsTypeNone:
+ default:
+ {
+ std::string strLabel;
+ int i = pSettingInt->GetMinimum();
+ const CSettingControlSpinner *control = static_cast<const CSettingControlSpinner*>(pSettingInt->GetControl());
+ if (control->GetMinimumLabel() > -1)
+ {
+ strLabel = g_localizeStrings.Get(control->GetMinimumLabel());
+ m_pSpin->AddLabel(strLabel, pSettingInt->GetMinimum());
+ i += pSettingInt->GetStep();
+ }
+
+ for (; i <= pSettingInt->GetMaximum(); i += pSettingInt->GetStep())
+ {
+ if (control->GetFormatLabel() > -1)
+ strLabel = StringUtils::Format(g_localizeStrings.Get(control->GetFormatLabel()).c_str(), i);
+ else
+ strLabel = StringUtils::Format(control->GetFormatString().c_str(), i);
+ m_pSpin->AddLabel(strLabel, i);
+ }
+
+ break;
+ }
+ }
+
+ m_pSpin->SetValue(pSettingInt->GetValue());
+}
+
+CGUIControlListSetting::CGUIControlListSetting(CGUIButtonControl *pButton, int id, CSetting *pSetting)
+ : CGUIControlBaseSetting(id, pSetting)
+{
+ m_pButton = pButton;
+ if (m_pButton == NULL)
+ return;
+
+ m_pButton->SetID(id);
+ Update();
+}
+
+CGUIControlListSetting::~CGUIControlListSetting()
+{ }
+
+bool CGUIControlListSetting::OnClick()
+{
+ if (m_pButton == NULL)
+ return false;
+
+ CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
+ if (dialog == NULL)
+ return false;
+
+ CFileItemList options;
+ if (!GetItems(m_pSetting, options) || options.Size() <= 1)
+ return false;
+
+ const CSettingControlList *control = static_cast<const CSettingControlList*>(m_pSetting->GetControl());
+
+ dialog->Reset();
+ dialog->SetHeading(g_localizeStrings.Get(m_pSetting->GetLabel()));
+ dialog->SetItems(&options);
+ dialog->SetMultiSelection(control->CanMultiSelect());
+ dialog->DoModal();
+
+ if (!dialog->IsConfirmed())
+ return false;
+
+ const CFileItemList &items = dialog->GetSelectedItems();
+ std::vector<CVariant> values;
+ for (int index = 0; index < items.Size(); index++)
+ {
+ const CFileItemPtr item = items[index];
+ if (item == NULL || !item->HasProperty("value"))
+ return false;
+
+ values.push_back(item->GetProperty("value"));
+ }
+
+ bool ret = false;
+ switch (m_pSetting->GetType())
+ {
+ case SettingTypeInteger:
+ if (values.size() > 1)
+ return false;
+ ret = ((CSettingInt *)m_pSetting)->SetValue((int)values.at(0).asInteger());
+ break;
+
+ case SettingTypeString:
+ if (values.size() > 1)
+ return false;
+ ret = ((CSettingString *)m_pSetting)->SetValue(values.at(0).asString());
+ break;
+
+ case SettingTypeList:
+ ret = CSettingUtils::SetList(static_cast<CSettingList*>(m_pSetting), values);
+ break;
+
+ default:
+ return false;
+ }
+
+ if (ret)
+ Update();
+ else
+ SetValid(false);
+
+ return IsValid();
+}
+
+void CGUIControlListSetting::Update(bool updateDisplayOnly /* = false */)
+{
+ if (updateDisplayOnly || m_pButton == NULL)
+ return;
+
+ CGUIControlBaseSetting::Update();
+
+ CFileItemList options;
+ bool optionsValid = GetItems(m_pSetting, options);
+ if (optionsValid && !static_cast<const CSettingControlList*>(m_pSetting->GetControl())->HideValue())
+ {
+ std::vector<std::string> labels;
+ for (int index = 0; index < options.Size(); index++)
+ {
+ const CFileItemPtr pItem = options.Get(index);
+ if (pItem->IsSelected())
+ labels.push_back(pItem->GetLabel());
+ }
+
+ m_pButton->SetLabel2(StringUtils::Join(labels, ", "));
+ }
+ else
+ m_pButton->SetLabel2(StringUtils::Empty);
+
+ // disable the control if it has less than two items
+ if (!m_pButton->IsDisabled() && options.Size() <= 1)
+ m_pButton->SetEnabled(false);
+}
+
+static CFileItemPtr GetItem(const std::string &label, const CVariant &value)
+{
+ CFileItemPtr pItem(new CFileItem(label));
+ pItem->SetProperty("value", value);
+
+ return pItem;
+}
+
+bool CGUIControlListSetting::GetItems(const CSetting *setting, CFileItemList &items)
+{
+ const CSettingControlList *control = static_cast<const CSettingControlList*>(setting->GetControl());
+ const std::string &controlFormat = control->GetFormat();
+
+ if (controlFormat == "integer")
+ return GetIntegerItems(setting, items);
+ else if (controlFormat == "string")
+ {
+ if (setting->GetType() == SettingTypeInteger ||
+ (setting->GetType() == SettingTypeList && ((CSettingList *)setting)->GetElementType() == SettingTypeInteger))
+ return GetIntegerItems(setting, items);
+ else if (setting->GetType() == SettingTypeString ||
+ (setting->GetType() == SettingTypeList && ((CSettingList *)setting)->GetElementType() == SettingTypeString))
+ return GetStringItems(setting, items);
+ }
+ else
+ return false;
+
+ return true;
+}
+
+bool CGUIControlListSetting::GetIntegerItems(const CSetting *setting, CFileItemList &items)
+{
+ const CSettingInt *pSettingInt = NULL;
+ std::set<int> values;
+ if (setting->GetType() == SettingTypeInteger)
+ {
+ pSettingInt = static_cast<const CSettingInt*>(setting);
+ values.insert(pSettingInt->GetValue());
+ }
+ else if (setting->GetType() == SettingTypeList)
+ {
+ const CSettingList *settingList = static_cast<const CSettingList*>(setting);
+ if (settingList->GetElementType() != SettingTypeInteger)
+ return false;
+
+ pSettingInt = static_cast<const CSettingInt*>(settingList->GetDefinition());
+ std::vector<CVariant> list = CSettingUtils::GetList(settingList);
+ for (std::vector<CVariant>::const_iterator itValue = list.begin(); itValue != list.end(); ++itValue)
+ {
+ if (!itValue->isInteger())
+ return false;
+ values.insert((int)itValue->asInteger());
+ }
+ }
+ else
+ return false;
+
+ switch (pSettingInt->GetOptionsType())
+ {
+ case SettingOptionsTypeStatic:
+ {
+ const StaticIntegerSettingOptions& options = pSettingInt->GetOptions();
+ for (StaticIntegerSettingOptions::const_iterator it = options.begin(); it != options.end(); ++it)
+ {
+ CFileItemPtr pItem = GetItem(g_localizeStrings.Get(it->first), it->second);
+
+ if (values.find(it->second) != values.end())
+ pItem->Select(true);
+
+ items.Add(pItem);
+ }
+ break;
+ }
+
+ case SettingOptionsTypeDynamic:
+ {
+ DynamicIntegerSettingOptions options = const_cast<CSettingInt*>(pSettingInt)->UpdateDynamicOptions();
+ for (DynamicIntegerSettingOptions::const_iterator option = options.begin(); option != options.end(); ++option)
+ {
+ CFileItemPtr pItem = GetItem(option->first, option->second);
+
+ if (values.find(option->second) != values.end())
+ pItem->Select(true);
+
+ items.Add(pItem);
+ }
+ break;
+ }
+
+ case SettingOptionsTypeNone:
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool CGUIControlListSetting::GetStringItems(const CSetting *setting, CFileItemList &items)
+{
+ const CSettingString *pSettingString = NULL;
+ std::set<std::string> values;
+ if (setting->GetType() == SettingTypeString)
+ {
+ pSettingString = static_cast<const CSettingString*>(setting);
+ values.insert(pSettingString->GetValue());
+ }
+ else if (setting->GetType() == SettingTypeList)
+ {
+ const CSettingList *settingList = static_cast<const CSettingList*>(setting);
+ if (settingList->GetElementType() != SettingTypeString)
+ return false;
+
+ pSettingString = static_cast<const CSettingString*>(settingList->GetDefinition());
+ std::vector<CVariant> list = CSettingUtils::GetList(settingList);
+ for (std::vector<CVariant>::const_iterator itValue = list.begin(); itValue != list.end(); ++itValue)
+ {
+ if (!itValue->isString())
+ return false;
+ values.insert(itValue->asString());
+ }
+ }
+ else
+ return false;
+
+ if (pSettingString->GetOptionsType() == SettingOptionsTypeDynamic)
+ {
+ DynamicStringSettingOptions options = const_cast<CSettingString*>(pSettingString)->UpdateDynamicOptions();
+ for (DynamicStringSettingOptions::const_iterator option = options.begin(); option != options.end(); ++option)
+ {
+ CFileItemPtr pItem = GetItem(option->first, option->second);
+
+ if (values.find(option->second) != values.end())
+ pItem->Select(true);
+
+ items.Add(pItem);
+ }
+ }
+ else
+ return false;
+
+ return true;
+}
+
+CGUIControlButtonSetting::CGUIControlButtonSetting(CGUIButtonControl *pButton, int id, CSetting *pSetting)
+ : CGUIControlBaseSetting(id, pSetting)
+{
+ m_pButton = pButton;
+ if (m_pButton == NULL)
+ return;
+
+ m_pButton->SetID(id);
+ Update();
+}
+
+CGUIControlButtonSetting::~CGUIControlButtonSetting()
+{ }
+
+bool CGUIControlButtonSetting::OnClick()
+{
+ if (m_pButton == NULL)
+ return false;
+
+ const ISettingControl *control = m_pSetting->GetControl();
+ const std::string &controlType = control->GetType();
+ const std::string &controlFormat = control->GetFormat();
+ if (controlType == "button")
+ {
+ if (controlFormat == "addon")
+ {
+ // prompt for the addon
+ CSettingAddon *setting = (CSettingAddon *)m_pSetting;
+ CStdString addonID = setting->GetValue();
+ if (CGUIWindowAddonBrowser::SelectAddonID(setting->GetAddonType(), addonID, setting->AllowEmpty()) != 1)
+ return false;
+
+ SetValid(setting->SetValue(addonID));
+ }
+ else if (controlFormat == "path")
+ SetValid(GetPath((CSettingPath *)m_pSetting));
+ else if (controlFormat == "action")
+ {
+ // simply call the OnSettingAction callback and whoever knows what to
+ // do can do so (based on the setting's identification
+ CSettingAction *pSettingAction = (CSettingAction *)m_pSetting;
+ pSettingAction->OnSettingAction(pSettingAction);
+ SetValid(true);
+ }
+ }
+ else if (controlType == "slider")
+ {
+ float value, min, step, max;
+ if (m_pSetting->GetType() == SettingTypeInteger)
+ {
+ CSettingInt *settingInt = static_cast<CSettingInt*>(m_pSetting);
+ value = (float)settingInt->GetValue();
+ min = (float)settingInt->GetMinimum();
+ step = (float)settingInt->GetStep();
+ max = (float)settingInt->GetMaximum();
+ }
+ else if (m_pSetting->GetType() == SettingTypeNumber)
+ {
+ CSettingNumber *settingNumber = static_cast<CSettingNumber*>(m_pSetting);
+ value = (float)settingNumber->GetValue();
+ min = (float)settingNumber->GetMinimum();
+ step = (float)settingNumber->GetStep();
+ max = (float)settingNumber->GetMaximum();
+ }
+ else
+ return false;
+
+ const CSettingControlSlider *sliderControl = static_cast<const CSettingControlSlider*>(control);
+ CGUIDialogSlider::ShowAndGetInput(g_localizeStrings.Get(sliderControl->GetHeading()), value, min, step, max, this, NULL);
+ SetValid(true);
+ }
+
+ return IsValid();
+}
+
+void CGUIControlButtonSetting::Update(bool updateDisplayOnly /* = false */)
+{
+ if (updateDisplayOnly || m_pButton == NULL)
+ return;
+
+ CGUIControlBaseSetting::Update();
+
+ std::string strText;
+ const ISettingControl *control = m_pSetting->GetControl();
+ const std::string &controlType = control->GetType();
+ const std::string &controlFormat = control->GetFormat();
+
+ if (controlType == "button")
+ {
+ if (m_pSetting->GetType() == SettingTypeString &&
+ !static_cast<const CSettingControlButton*>(control)->HideValue())
+ {
+ std::string strValue = ((CSettingString *)m_pSetting)->GetValue();
+ if (controlFormat == "addon")
+ {
+ ADDON::AddonPtr addon;
+ if (ADDON::CAddonMgr::Get().GetAddon(strValue, addon))
+ strText = addon->Name();
+ if (strText.empty())
+ strText = g_localizeStrings.Get(231); // None
+ }
+ else if (controlFormat == "path")
+ {
+ CStdString shortPath;
+ if (CUtil::MakeShortenPath(strValue, shortPath, 30))
+ strText = shortPath;
+ }
+ }
+ }
+ else if (controlType == "slider")
+ {
+ switch (m_pSetting->GetType())
+ {
+ case SettingTypeInteger:
+ {
+ const CSettingInt *settingInt = static_cast<CSettingInt*>(m_pSetting);
+ strText = CGUIControlSliderSetting::GetText(static_cast<const CSettingControlSlider*>(m_pSetting->GetControl()),
+ settingInt->GetValue(), settingInt->GetMinimum(), settingInt->GetStep(), settingInt->GetMaximum());
+ break;
+ }
+
+ case SettingTypeNumber:
+ {
+ const CSettingNumber *settingNumber = static_cast<CSettingNumber*>(m_pSetting);
+ strText = CGUIControlSliderSetting::GetText(static_cast<const CSettingControlSlider*>(m_pSetting->GetControl()),
+ settingNumber->GetValue(), settingNumber->GetMinimum(), settingNumber->GetStep(), settingNumber->GetMaximum());
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ m_pButton->SetLabel2(strText);
+}
+
+bool CGUIControlButtonSetting::GetPath(CSettingPath *pathSetting)
+{
+ if (pathSetting == NULL)
+ return false;
+
+ CStdString path = pathSetting->GetValue();
+
+ VECSOURCES shares;
+ const std::vector<std::string>& sources = pathSetting->GetSources();
+ for (std::vector<std::string>::const_iterator source = sources.begin(); source != sources.end(); ++source)
+ {
+ VECSOURCES *sources = CMediaSourceSettings::Get().GetSources(*source);
+ if (sources != NULL)
+ shares.insert(shares.end(), sources->begin(), sources->end());
+ }
+
+ g_mediaManager.GetNetworkLocations(shares);
+ g_mediaManager.GetLocalDrives(shares);
+
+ if (!CGUIDialogFileBrowser::ShowAndGetDirectory(shares, g_localizeStrings.Get(static_cast<const CSettingControlButton*>(pathSetting->GetControl())->GetHeading()), path, pathSetting->Writable()))
+ return false;
+
+ return pathSetting->SetValue(path);
+}
+
+void CGUIControlButtonSetting::OnSliderChange(void *data, CGUISliderControl *slider)
+{
+ if (slider == NULL)
+ return;
+
+ std::string strText;
+ switch (m_pSetting->GetType())
+ {
+ case SettingTypeInteger:
+ {
+ CSettingInt *settingInt = static_cast<CSettingInt*>(m_pSetting);
+ if (settingInt->SetValue(slider->GetIntValue()))
+ strText = CGUIControlSliderSetting::GetText(static_cast<const CSettingControlSlider*>(m_pSetting->GetControl()),
+ settingInt->GetValue(), settingInt->GetMinimum(), settingInt->GetStep(), settingInt->GetMaximum());
+ break;
+ }
+
+ case SettingTypeNumber:
+ {
+ CSettingNumber *settingNumber = static_cast<CSettingNumber*>(m_pSetting);
+ if (settingNumber->SetValue(static_cast<double>(slider->GetFloatValue())))
+ strText = CGUIControlSliderSetting::GetText(static_cast<const CSettingControlSlider*>(m_pSetting->GetControl()),
+ settingNumber->GetValue(), settingNumber->GetMinimum(), settingNumber->GetStep(), settingNumber->GetMaximum());
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (!strText.empty())
+ slider->SetTextValue(strText);
+}
+
+CGUIControlEditSetting::CGUIControlEditSetting(CGUIEditControl *pEdit, int id, CSetting *pSetting)
+ : CGUIControlBaseSetting(id, pSetting)
+{
+ const CSettingControlEdit* control = static_cast<const CSettingControlEdit*>(pSetting->GetControl());
+ m_pEdit = pEdit;
+ if (m_pEdit == NULL)
+ return;
+
+ m_pEdit->SetID(id);
+ int heading = m_pSetting->GetLabel();
+ if (control->GetHeading() > 0)
+ heading = control->GetHeading();
+ if (heading < 0)
+ heading = 0;
+
+ CGUIEditControl::INPUT_TYPE inputType = CGUIEditControl::INPUT_TYPE_TEXT;
+ const std::string &controlFormat = control->GetFormat();
+ if (controlFormat == "string")
+ {
+ if (control->IsHidden())
+ inputType = CGUIEditControl::INPUT_TYPE_PASSWORD;
+ }
+ else if (controlFormat == "integer" || controlFormat == "number")
+ {
+ if (control->VerifyNewValue())
+ inputType = CGUIEditControl::INPUT_TYPE_PASSWORD_NUMBER_VERIFY_NEW;
+ else
+ inputType = CGUIEditControl::INPUT_TYPE_NUMBER;
+ }
+ else if (controlFormat == "ip")
+ inputType = CGUIEditControl::INPUT_TYPE_IPADDRESS;
+ else if (controlFormat == "md5")
+ inputType = CGUIEditControl::INPUT_TYPE_PASSWORD_MD5;
+
+ m_pEdit->SetInputType(inputType, heading);
+
+ Update();
+
+ // this will automatically trigger validation so it must be executed after
+ // having set the value of the control based on the value of the setting
+ m_pEdit->SetInputValidation(InputValidation, this);
+}
+
+CGUIControlEditSetting::~CGUIControlEditSetting()
+{ }
+
+bool CGUIControlEditSetting::OnClick()
+{
+ if (m_pEdit == NULL)
+ return false;
+
+ // update our string
+ SetValid(m_pSetting->FromString(m_pEdit->GetLabel2()));
+ return IsValid();
+}
+
+void CGUIControlEditSetting::Update(bool updateDisplayOnly /* = false */)
+{
+ if (updateDisplayOnly || m_pEdit == NULL)
+ return;
+
+ CGUIControlBaseSetting::Update();
+
+ m_pEdit->SetLabel2(m_pSetting->ToString());
+}
+
+bool CGUIControlEditSetting::InputValidation(const std::string &input, void *data)
+{
+ if (data == NULL)
+ return true;
+
+ CGUIControlEditSetting *editControl = reinterpret_cast<CGUIControlEditSetting*>(data);
+ if (editControl == NULL || editControl->GetSetting() == NULL)
+ return true;
+
+ editControl->SetValid(editControl->GetSetting()->CheckValidity(input));
+ return editControl->IsValid();
+}
+
+CGUIControlSliderSetting::CGUIControlSliderSetting(CGUISettingsSliderControl *pSlider, int id, CSetting *pSetting)
+ : CGUIControlBaseSetting(id, pSetting)
+{
+ m_pSlider = pSlider;
+ if (m_pSlider == NULL)
+ return;
+
+ m_pSlider->SetID(id);
+
+ switch (m_pSetting->GetType())
+ {
+ case SettingTypeInteger:
+ {
+ CSettingInt *settingInt = static_cast<CSettingInt*>(m_pSetting);
+ if (m_pSetting->GetControl()->GetFormat() == "percentage")
+ m_pSlider->SetType(SLIDER_CONTROL_TYPE_PERCENTAGE);
+ else
+ {
+ m_pSlider->SetType(SLIDER_CONTROL_TYPE_INT);
+ m_pSlider->SetRange(settingInt->GetMinimum(), settingInt->GetMaximum());
+ }
+ m_pSlider->SetIntInterval(settingInt->GetStep());
+ break;
+ }
+
+ case SettingTypeNumber:
+ {
+ CSettingNumber *settingNumber = static_cast<CSettingNumber*>(m_pSetting);
+ m_pSlider->SetType(SLIDER_CONTROL_TYPE_FLOAT);
+ m_pSlider->SetFloatRange((float)settingNumber->GetMinimum(), (float)settingNumber->GetMaximum());
+ m_pSlider->SetFloatInterval((float)settingNumber->GetStep());
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ Update();
+}
+
+CGUIControlSliderSetting::~CGUIControlSliderSetting()
+{ }
+
+bool CGUIControlSliderSetting::OnClick()
+{
+ if (m_pSlider == NULL)
+ return false;
+
+ switch (m_pSetting->GetType())
+ {
+ case SettingTypeInteger:
+ SetValid(static_cast<CSettingInt*>(m_pSetting)->SetValue(m_pSlider->GetIntValue()));
+ break;
+
+ case SettingTypeNumber:
+ SetValid(static_cast<CSettingNumber*>(m_pSetting)->SetValue(m_pSlider->GetFloatValue()));
+ break;
+
+ default:
+ return false;
+ }
+
+ return IsValid();
+}
+
+void CGUIControlSliderSetting::Update(bool updateDisplayOnly /* = false */)
+{
+ if (m_pSlider == NULL)
+ return;
+
+ CGUIControlBaseSetting::Update();
+
+ std::string strText;
+ switch (m_pSetting->GetType())
+ {
+ case SettingTypeInteger:
+ {
+ const CSettingInt *settingInt = static_cast<CSettingInt*>(m_pSetting);
+ int value;
+ if (updateDisplayOnly)
+ value = m_pSlider->GetIntValue();
+ else
+ {
+ value = static_cast<CSettingInt*>(m_pSetting)->GetValue();
+ m_pSlider->SetIntValue(value);
+ }
+
+ strText = CGUIControlSliderSetting::GetText(static_cast<const CSettingControlSlider*>(m_pSetting->GetControl()),
+ value, settingInt->GetMinimum(), settingInt->GetStep(), settingInt->GetMaximum());
+ break;
+ }
+
+ case SettingTypeNumber:
+ {
+ const CSettingNumber *settingNumber = static_cast<CSettingNumber*>(m_pSetting);
+ double value;
+ if (updateDisplayOnly)
+ value = (float)m_pSlider->GetFloatValue();
+ else
+ {
+ value = static_cast<CSettingNumber*>(m_pSetting)->GetValue();
+ m_pSlider->SetFloatValue((float)value);
+ }
+
+ strText = CGUIControlSliderSetting::GetText(static_cast<const CSettingControlSlider*>(m_pSetting->GetControl()),
+ value, settingNumber->GetMinimum(), settingNumber->GetStep(), settingNumber->GetMaximum());
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (!strText.empty())
+ m_pSlider->SetTextValue(strText);
+}
+
+std::string CGUIControlSliderSetting::GetText(const CSettingControlSlider *control, const CVariant &value, const CVariant &minimum, const CVariant &step, const CVariant &maximum)
+{
+ if (control == NULL ||
+ !(value.isInteger() || value.isDouble()))
+ return "";
+
+ SettingControlSliderFormatter formatter = control->GetFormatter();
+ if (formatter != NULL)
+ return formatter(control, value, minimum, step, maximum);
+
+ std::string formatString = control->GetFormatString();
+ if (control->GetFormatLabel() > -1)
+ formatString = g_localizeStrings.Get(control->GetFormatLabel());
+
+ if (value.isDouble())
+ return StringUtils::Format(formatString.c_str(), value.asDouble());
+
+ return StringUtils::Format(formatString.c_str(), static_cast<int>(value.asInteger()));
+}
+
+CGUIControlRangeSetting::CGUIControlRangeSetting(CGUISettingsSliderControl *pSlider, int id, CSetting *pSetting)
+ : CGUIControlBaseSetting(id, pSetting)
+{
+ m_pSlider = pSlider;
+ if (m_pSlider == NULL)
+ return;
+
+ m_pSlider->SetID(id);
+ m_pSlider->SetRangeSelection(true);
+
+ if (m_pSetting->GetType() == SettingTypeList)
+ {
+ CSettingList *settingList = static_cast<CSettingList*>(m_pSetting);
+ const CSetting *listDefintion = settingList->GetDefinition();
+ switch (listDefintion->GetType())
+ {
+ case SettingTypeInteger:
+ {
+ const CSettingInt *listDefintionInt = static_cast<const CSettingInt*>(listDefintion);
+ if (m_pSetting->GetControl()->GetFormat() == "percentage")
+ m_pSlider->SetType(SLIDER_CONTROL_TYPE_PERCENTAGE);
+ else
+ {
+ m_pSlider->SetType(SLIDER_CONTROL_TYPE_INT);
+ m_pSlider->SetRange(listDefintionInt->GetMinimum(), listDefintionInt->GetMaximum());
+ }
+ m_pSlider->SetIntInterval(listDefintionInt->GetStep());
+ break;
+ }
+
+ case SettingTypeNumber:
+ {
+ const CSettingNumber *listDefinitionNumber = static_cast<const CSettingNumber*>(listDefintion);
+ m_pSlider->SetType(SLIDER_CONTROL_TYPE_FLOAT);
+ m_pSlider->SetFloatRange((float)listDefinitionNumber->GetMinimum(), (float)listDefinitionNumber->GetMaximum());
+ m_pSlider->SetFloatInterval((float)listDefinitionNumber->GetStep());
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ Update();
+}
+
+CGUIControlRangeSetting::~CGUIControlRangeSetting()
+{ }
+
+bool CGUIControlRangeSetting::OnClick()
+{
+ if (m_pSlider == NULL ||
+ m_pSetting->GetType() != SettingTypeList)
+ return false;
+
+ CSettingList *settingList = static_cast<CSettingList*>(m_pSetting);
+ const SettingPtrList &settingListValues = settingList->GetValue();
+ if (settingListValues.size() != 2)
+ return false;
+
+ std::vector<CVariant> values;
+ const CSetting *listDefintion = settingList->GetDefinition();
+ switch (listDefintion->GetType())
+ {
+ case SettingTypeInteger:
+ values.push_back(m_pSlider->GetIntValue(CGUISliderControl::RangeSelectorLower));
+ values.push_back(m_pSlider->GetIntValue(CGUISliderControl::RangeSelectorUpper));
+ break;
+
+ case SettingTypeNumber:
+ values.push_back(m_pSlider->GetFloatValue(CGUISliderControl::RangeSelectorLower));
+ values.push_back(m_pSlider->GetFloatValue(CGUISliderControl::RangeSelectorUpper));
+ break;
+
+ default:
+ return false;
+ }
+
+ if (values.size() != 2)
+ return false;
+
+ SetValid(CSettingUtils::SetList(settingList, values));
+ return IsValid();
+}
+
+void CGUIControlRangeSetting::Update(bool updateDisplayOnly /* = false */)
+{
+ if (m_pSlider == NULL ||
+ m_pSetting->GetType() != SettingTypeList)
+ return;
+
+ CGUIControlBaseSetting::Update();
+
+ CSettingList *settingList = static_cast<CSettingList*>(m_pSetting);
+ const SettingPtrList &settingListValues = settingList->GetValue();
+ if (settingListValues.size() != 2)
+ return;
+
+ const CSetting *listDefintion = settingList->GetDefinition();
+ const CSettingControlRange *controlRange = static_cast<const CSettingControlRange*>(m_pSetting->GetControl());
+ const std::string &controlFormat = controlRange->GetFormat();
+
+ std::string strText;
+ std::string strTextLower, strTextUpper;
+ std::string formatString = g_localizeStrings.Get(controlRange->GetFormatLabel() > -1 ? controlRange->GetFormatLabel() : 21469);
+ std::string valueFormat = controlRange->GetValueFormat();
+ if (controlRange->GetValueFormatLabel() > -1)
+ valueFormat = g_localizeStrings.Get(controlRange->GetValueFormatLabel());
+
+ switch (listDefintion->GetType())
+ {
+ case SettingTypeInteger:
+ {
+ int valueLower, valueUpper;
+ if (updateDisplayOnly)
+ {
+ valueLower = m_pSlider->GetIntValue(CGUISliderControl::RangeSelectorLower);
+ valueUpper = m_pSlider->GetIntValue(CGUISliderControl::RangeSelectorUpper);
+ }
+ else
+ {
+ valueLower = static_cast<CSettingInt*>(settingListValues[0].get())->GetValue();
+ valueUpper = static_cast<CSettingInt*>(settingListValues[1].get())->GetValue();
+ m_pSlider->SetIntValue(valueLower, CGUISliderControl::RangeSelectorLower);
+ m_pSlider->SetIntValue(valueUpper, CGUISliderControl::RangeSelectorUpper);
+ }
+
+ if (controlFormat == "date" || controlFormat == "time")
+ {
+ CDateTime dateLower = (time_t)valueLower;
+ CDateTime dateUpper = (time_t)valueUpper;
+
+ if (controlFormat == "date")
+ {
+ if (valueFormat.empty())
+ {
+ strTextLower = dateLower.GetAsLocalizedDate();
+ strTextUpper = dateUpper.GetAsLocalizedDate();
+ }
+ else
+ {
+ strTextLower = dateLower.GetAsLocalizedDate(valueFormat);
+ strTextUpper = dateUpper.GetAsLocalizedDate(valueFormat);
+ }
+ }
+ else
+ {
+ if (valueFormat.empty())
+ valueFormat = "mm:ss";
+
+ strTextLower = dateLower.GetAsLocalizedTime(valueFormat);
+ strTextUpper = dateUpper.GetAsLocalizedTime(valueFormat);
+ }
+ }
+ else
+ {
+ strTextLower = StringUtils::Format(valueFormat.c_str(), valueLower);
+ strTextUpper = StringUtils::Format(valueFormat.c_str(), valueUpper);
+ }
+
+ if (valueLower != valueUpper)
+ strText = StringUtils::Format(formatString.c_str(), strTextLower.c_str(), strTextUpper.c_str());
+ else
+ strText = strTextLower;
+ break;
+ }
+
+ case SettingTypeNumber:
+ {
+ double valueLower, valueUpper;
+ if (updateDisplayOnly)
+ {
+ valueLower = static_cast<double>(m_pSlider->GetFloatValue(CGUISliderControl::RangeSelectorLower));
+ valueUpper = static_cast<double>(m_pSlider->GetFloatValue(CGUISliderControl::RangeSelectorUpper));
+ }
+ else
+ {
+ valueLower = static_cast<CSettingNumber*>(settingListValues[0].get())->GetValue();
+ valueUpper = static_cast<CSettingNumber*>(settingListValues[1].get())->GetValue();
+ m_pSlider->SetFloatValue((float)valueLower, CGUISliderControl::RangeSelectorLower);
+ m_pSlider->SetFloatValue((float)valueUpper, CGUISliderControl::RangeSelectorUpper);
+ }
+
+ strTextLower = StringUtils::Format(valueFormat.c_str(), valueLower);
+ if (valueLower != valueUpper)
+ {
+ strTextUpper = StringUtils::Format(valueFormat.c_str(), valueUpper);
+ strText = StringUtils::Format(formatString.c_str(), strTextLower.c_str(), strTextUpper.c_str());
+ }
+ else
+ strText = strTextLower;
+ break;
+ }
+
+ default:
+ strText.clear();
+ break;
+ }
+
+ if (!strText.empty())
+ m_pSlider->SetTextValue(strText);
+}
+
+CGUIControlSeparatorSetting::CGUIControlSeparatorSetting(CGUIImage *pImage, int id)
+ : CGUIControlBaseSetting(id, NULL)
+{
+ m_pImage = pImage;
+ if (m_pImage == NULL)
+ return;
+
+ m_pImage->SetID(id);
+}
+
+CGUIControlSeparatorSetting::~CGUIControlSeparatorSetting()
+{ }
diff --git a/src/settings/windows/GUIControlSettings.h b/src/settings/windows/GUIControlSettings.h
new file mode 100644
index 0000000000..28c93c43b4
--- /dev/null
+++ b/src/settings/windows/GUIControlSettings.h
@@ -0,0 +1,225 @@
+#pragma once
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "utils/StdString.h"
+#include "guilib/ISliderCallback.h"
+
+class CGUIControl;
+class CGUIImage;
+class CGUISpinControlEx;
+class CGUIEditControl;
+class CGUIButtonControl;
+class CGUIRadioButtonControl;
+class CGUISettingsSliderControl;
+
+class CSetting;
+class CSettingControlSlider;
+class CSettingString;
+class CSettingPath;
+
+class CFileItemList;
+class CVariant;
+
+class CGUIControlBaseSetting
+{
+public:
+ CGUIControlBaseSetting(int id, CSetting *pSetting);
+ virtual ~CGUIControlBaseSetting() {}
+
+ int GetID() const { return m_id; }
+ CSetting* GetSetting() { return m_pSetting; }
+
+ /*!
+ \brief Specifies that this setting should update after a delay
+ Useful for settings that have options to navigate through
+ and may take a while, or require additional input to update
+ once the final setting is chosen. Settings default to updating
+ instantly.
+ \sa IsDelayed()
+ */
+ void SetDelayed() { m_delayed = true; }
+
+ /*!
+ \brief Returns whether this setting should have delayed update
+ \return true if the setting's update should be delayed
+ \sa SetDelayed()
+ */
+ bool IsDelayed() const { return m_delayed; }
+
+ /*!
+ \brief Returns whether this setting is enabled or disabled
+ This state is independent of the real enabled state of a
+ setting control but represents the enabled state of the
+ setting itself based on specific conditions.
+ \return true if the setting is enabled otherwise false
+ \sa SetEnabled()
+ */
+ bool IsEnabled() const;
+
+ /*!
+ \brief Returns whether the setting's value is valid or not
+ */
+ bool IsValid() const { return m_valid; }
+
+ void SetValid(bool valid) { m_valid = valid; }
+
+ virtual CGUIControl* GetControl() { return NULL; }
+ virtual bool OnClick() { return false; }
+ virtual void Update(bool updateDisplayOnly = false);
+ virtual void Clear() = 0; ///< Clears the attached control
+protected:
+ int m_id;
+ CSetting* m_pSetting;
+ bool m_delayed;
+ bool m_valid;
+};
+
+class CGUIControlRadioButtonSetting : public CGUIControlBaseSetting
+{
+public:
+ CGUIControlRadioButtonSetting(CGUIRadioButtonControl* pRadioButton, int id, CSetting *pSetting);
+ virtual ~CGUIControlRadioButtonSetting();
+
+ void Select(bool bSelect);
+
+ virtual CGUIControl* GetControl() { return (CGUIControl*)m_pRadioButton; }
+ virtual bool OnClick();
+ virtual void Update(bool updateDisplayOnly = false);
+ virtual void Clear() { m_pRadioButton = NULL; }
+private:
+ CGUIRadioButtonControl *m_pRadioButton;
+};
+
+class CGUIControlSpinExSetting : public CGUIControlBaseSetting
+{
+public:
+ CGUIControlSpinExSetting(CGUISpinControlEx* pSpin, int id, CSetting *pSetting);
+ virtual ~CGUIControlSpinExSetting();
+
+ virtual CGUIControl* GetControl() { return (CGUIControl*)m_pSpin; }
+ virtual bool OnClick();
+ virtual void Update(bool updateDisplayOnly = false);
+ virtual void Clear() { m_pSpin = NULL; }
+private:
+ void FillControl();
+ void FillIntegerSettingControl();
+ CGUISpinControlEx *m_pSpin;
+};
+
+class CGUIControlListSetting : public CGUIControlBaseSetting
+{
+public:
+ CGUIControlListSetting(CGUIButtonControl* pButton, int id, CSetting *pSetting);
+ virtual ~CGUIControlListSetting();
+
+ virtual CGUIControl* GetControl() { return (CGUIControl*)m_pButton; }
+ virtual bool OnClick();
+ virtual void Update(bool updateDisplayOnly = false);
+ virtual void Clear() { m_pButton = NULL; }
+private:
+ static bool GetItems(const CSetting *setting, CFileItemList &items);
+ static bool GetIntegerItems(const CSetting *setting, CFileItemList &items);
+ static bool GetStringItems(const CSetting *setting, CFileItemList &items);
+
+ CGUIButtonControl *m_pButton;
+};
+
+class CGUIControlButtonSetting : public CGUIControlBaseSetting, protected ISliderCallback
+{
+public:
+ CGUIControlButtonSetting(CGUIButtonControl* pButton, int id, CSetting *pSetting);
+ virtual ~CGUIControlButtonSetting();
+
+ virtual CGUIControl* GetControl() { return (CGUIControl*)m_pButton; }
+ virtual bool OnClick();
+ virtual void Update(bool updateDisplayOnly = false);
+ virtual void Clear() { m_pButton = NULL; }
+
+ static bool GetPath(CSettingPath *pathSetting);
+protected:
+ // implementations of ISliderCallback
+ virtual void OnSliderChange(void *data, CGUISliderControl *slider);
+
+private:
+ CGUIButtonControl *m_pButton;
+};
+
+class CGUIControlEditSetting : public CGUIControlBaseSetting
+{
+public:
+ CGUIControlEditSetting(CGUIEditControl* pButton, int id, CSetting *pSetting);
+ virtual ~CGUIControlEditSetting();
+
+ virtual CGUIControl* GetControl() { return (CGUIControl*)m_pEdit; }
+ virtual bool OnClick();
+ virtual void Update(bool updateDisplayOnly = false);
+ virtual void Clear() { m_pEdit = NULL; }
+private:
+ static bool InputValidation(const std::string &input, void *data);
+
+ CGUIEditControl *m_pEdit;
+};
+
+class CGUIControlSliderSetting : public CGUIControlBaseSetting
+{
+public:
+ CGUIControlSliderSetting(CGUISettingsSliderControl* pSlider, int id, CSetting *pSetting);
+ virtual ~CGUIControlSliderSetting();
+
+ virtual CGUIControl* GetControl() { return (CGUIControl*)m_pSlider; }
+ virtual bool OnClick();
+ virtual void Update(bool updateDisplayOnly = false);
+ virtual void Clear() { m_pSlider = NULL; }
+
+ static std::string GetText(const CSettingControlSlider *control, const CVariant &value, const CVariant &minimum, const CVariant &step, const CVariant &maximum);
+
+private:
+ CGUISettingsSliderControl *m_pSlider;
+};
+
+class CGUIControlRangeSetting : public CGUIControlBaseSetting
+{
+public:
+ CGUIControlRangeSetting(CGUISettingsSliderControl* pSlider, int id, CSetting *pSetting);
+ virtual ~CGUIControlRangeSetting();
+
+ virtual CGUIControl* GetControl() { return (CGUIControl*)m_pSlider; }
+ virtual bool OnClick();
+ virtual void Update(bool updateDisplayOnly = false);
+ virtual void Clear() { m_pSlider = NULL; }
+
+private:
+ CGUISettingsSliderControl *m_pSlider;
+};
+
+class CGUIControlSeparatorSetting : public CGUIControlBaseSetting
+{
+public:
+ CGUIControlSeparatorSetting(CGUIImage* pImage, int id);
+ virtual ~CGUIControlSeparatorSetting();
+
+ virtual CGUIControl* GetControl() { return (CGUIControl*)m_pImage; }
+ virtual bool OnClick() { return false; }
+ virtual void Update() {}
+ virtual void Clear() { m_pImage = NULL; }
+private:
+ CGUIImage *m_pImage;
+};
diff --git a/src/settings/windows/GUIWindowSettings.cpp b/src/settings/windows/GUIWindowSettings.cpp
new file mode 100644
index 0000000000..a99e87bcaf
--- /dev/null
+++ b/src/settings/windows/GUIWindowSettings.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "system.h"
+#include "GUIWindowSettings.h"
+#include "guilib/WindowIDs.h"
+
+CGUIWindowSettings::CGUIWindowSettings(void)
+ : CGUIWindow(WINDOW_SETTINGS_MENU, "Settings.xml")
+{
+ m_loadType = KEEP_IN_MEMORY;
+}
+
+CGUIWindowSettings::~CGUIWindowSettings(void)
+{
+}
diff --git a/src/settings/windows/GUIWindowSettings.h b/src/settings/windows/GUIWindowSettings.h
new file mode 100644
index 0000000000..a12001ce4c
--- /dev/null
+++ b/src/settings/windows/GUIWindowSettings.h
@@ -0,0 +1,31 @@
+#pragma once
+
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "guilib/GUIWindow.h"
+
+class CGUIWindowSettings :
+ public CGUIWindow
+{
+public:
+ CGUIWindowSettings(void);
+ virtual ~CGUIWindowSettings(void);
+};
diff --git a/src/settings/windows/GUIWindowSettingsCategory.cpp b/src/settings/windows/GUIWindowSettingsCategory.cpp
new file mode 100644
index 0000000000..5f256a25fe
--- /dev/null
+++ b/src/settings/windows/GUIWindowSettingsCategory.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2005-2014 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "GUIWindowSettingsCategory.h"
+#include "GUIPassword.h"
+#include "GUIUserMessages.h"
+#include "guilib/Key.h"
+#include "settings/DisplaySettings.h"
+#include "settings/Settings.h"
+#include "settings/lib/SettingSection.h"
+#include "view/ViewStateSettings.h"
+
+using namespace std;
+
+#define SETTINGS_PICTURES WINDOW_SETTINGS_MYPICTURES - WINDOW_SETTINGS_START
+#define SETTINGS_PROGRAMS WINDOW_SETTINGS_MYPROGRAMS - WINDOW_SETTINGS_START
+#define SETTINGS_WEATHER WINDOW_SETTINGS_MYWEATHER - WINDOW_SETTINGS_START
+#define SETTINGS_MUSIC WINDOW_SETTINGS_MYMUSIC - WINDOW_SETTINGS_START
+#define SETTINGS_SYSTEM WINDOW_SETTINGS_SYSTEM - WINDOW_SETTINGS_START
+#define SETTINGS_VIDEOS WINDOW_SETTINGS_MYVIDEOS - WINDOW_SETTINGS_START
+#define SETTINGS_SERVICE WINDOW_SETTINGS_SERVICE - WINDOW_SETTINGS_START
+#define SETTINGS_APPEARANCE WINDOW_SETTINGS_APPEARANCE - WINDOW_SETTINGS_START
+#define SETTINGS_PVR WINDOW_SETTINGS_MYPVR - WINDOW_SETTINGS_START
+
+#define CONTRL_BTN_LEVELS 20
+
+typedef struct {
+ int id;
+ string name;
+} SettingGroup;
+
+static const SettingGroup s_settingGroupMap[] = { { SETTINGS_PICTURES, "pictures" },
+ { SETTINGS_PROGRAMS, "programs" },
+ { SETTINGS_WEATHER, "weather" },
+ { SETTINGS_MUSIC, "music" },
+ { SETTINGS_SYSTEM, "system" },
+ { SETTINGS_VIDEOS, "videos" },
+ { SETTINGS_SERVICE, "services" },
+ { SETTINGS_APPEARANCE, "appearance" },
+ { SETTINGS_PVR, "pvr" } };
+
+#define SettingGroupSize sizeof(s_settingGroupMap) / sizeof(SettingGroup)
+
+CGUIWindowSettingsCategory::CGUIWindowSettingsCategory()
+ : CGUIDialogSettingsManagerBase(WINDOW_SETTINGS_MYPICTURES, "SettingsCategory.xml"),
+ m_settings(CSettings::Get()),
+ m_iSection(0),
+ m_returningFromSkinLoad(false)
+{
+ m_settingsManager = m_settings.GetSettingsManager();
+
+ // set the correct ID range...
+ m_idRange.clear();
+ m_idRange.push_back(WINDOW_SETTINGS_MYPICTURES);
+ m_idRange.push_back(WINDOW_SETTINGS_MYPROGRAMS);
+ m_idRange.push_back(WINDOW_SETTINGS_MYWEATHER);
+ m_idRange.push_back(WINDOW_SETTINGS_MYMUSIC);
+ m_idRange.push_back(WINDOW_SETTINGS_SYSTEM);
+ m_idRange.push_back(WINDOW_SETTINGS_MYVIDEOS);
+ m_idRange.push_back(WINDOW_SETTINGS_SERVICE);
+ m_idRange.push_back(WINDOW_SETTINGS_APPEARANCE);
+ m_idRange.push_back(WINDOW_SETTINGS_MYPVR);
+}
+
+CGUIWindowSettingsCategory::~CGUIWindowSettingsCategory()
+{ }
+
+bool CGUIWindowSettingsCategory::OnMessage(CGUIMessage &message)
+{
+ switch (message.GetMessage())
+ {
+ case GUI_MSG_WINDOW_INIT:
+ {
+ m_iSection = (int)message.GetParam2() - (int)CGUIDialogSettingsManagerBase::GetID();
+ CGUIDialogSettingsManagerBase::OnMessage(message);
+ m_returningFromSkinLoad = false;
+ return true;
+ }
+
+ case GUI_MSG_FOCUSED:
+ {
+ if (!m_returningFromSkinLoad)
+ CGUIDialogSettingsManagerBase::OnMessage(message);
+ return true;
+ }
+
+ case GUI_MSG_LOAD_SKIN:
+ {
+ if (IsActive())
+ m_returningFromSkinLoad = true;
+ break;
+ }
+
+ case GUI_MSG_NOTIFY_ALL:
+ {
+ if (message.GetParam1() == GUI_MSG_WINDOW_RESIZE)
+ {
+ if (IsActive() && CDisplaySettings::Get().GetCurrentResolution() != g_graphicsContext.GetVideoResolution())
+ {
+ CDisplaySettings::Get().SetCurrentResolution(g_graphicsContext.GetVideoResolution(), true);
+ CreateSettings();
+ }
+ }
+ break;
+ }
+ }
+
+ return CGUIDialogSettingsManagerBase::OnMessage(message);
+}
+
+bool CGUIWindowSettingsCategory::OnAction(const CAction &action)
+{
+ switch (action.GetID())
+ {
+ case ACTION_SETTINGS_LEVEL_CHANGE:
+ {
+ //Test if we can access the new level
+ if (!g_passwordManager.CheckSettingLevelLock(CViewStateSettings::Get().GetNextSettingLevel(), true))
+ return false;
+
+ CViewStateSettings::Get().CycleSettingLevel();
+ CSettings::Get().Save();
+
+ // try to keep the current position
+ std::string oldCategory;
+ if (m_iCategory >= 0 && m_iCategory < (int)m_categories.size())
+ oldCategory = m_categories[m_iCategory]->GetId();
+
+ SET_CONTROL_LABEL(CONTRL_BTN_LEVELS, 10036 + (int)CViewStateSettings::Get().GetSettingLevel());
+ // only re-create the categories, the settings will be created later
+ SetupControls(false);
+
+ m_iCategory = 0;
+ // try to find the category that was previously selected
+ if (!oldCategory.empty())
+ {
+ for (int i = 0; i < (int)m_categories.size(); i++)
+ {
+ if (m_categories[i]->GetId() == oldCategory)
+ {
+ m_iCategory = i;
+ break;
+ }
+ }
+ }
+
+ CreateSettings();
+ return true;
+ }
+
+ default:
+ break;
+ }
+
+ return CGUIDialogSettingsManagerBase::OnAction(action);
+}
+
+bool CGUIWindowSettingsCategory::OnBack(int actionID)
+{
+ Save();
+ return CGUIDialogSettingsManagerBase::OnBack(actionID);
+}
+
+void CGUIWindowSettingsCategory::OnWindowLoaded()
+{
+ SET_CONTROL_LABEL(CONTRL_BTN_LEVELS, 10036 + (int)CViewStateSettings::Get().GetSettingLevel());
+ CGUIDialogSettingsManagerBase::OnWindowLoaded();
+}
+
+int CGUIWindowSettingsCategory::GetSettingLevel() const
+{
+ return (int)CViewStateSettings::Get().GetSettingLevel();
+}
+
+CSettingSection* CGUIWindowSettingsCategory::GetSection()
+{
+ for (size_t index = 0; index < SettingGroupSize; index++)
+ {
+ if (s_settingGroupMap[index].id == m_iSection)
+ return m_settings.GetSection(s_settingGroupMap[index].name);
+ }
+
+ return NULL;
+}
+
+void CGUIWindowSettingsCategory::Save()
+{
+ m_settings.Save();
+}
diff --git a/src/settings/windows/GUIWindowSettingsCategory.h b/src/settings/windows/GUIWindowSettingsCategory.h
new file mode 100644
index 0000000000..60106ff1cf
--- /dev/null
+++ b/src/settings/windows/GUIWindowSettingsCategory.h
@@ -0,0 +1,53 @@
+#pragma once
+/*
+ * Copyright (C) 2005-2014 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "settings/dialogs/GUIDialogSettingsManagerBase.h"
+
+class CSettings;
+
+class CGUIWindowSettingsCategory : public CGUIDialogSettingsManagerBase
+{
+public:
+ CGUIWindowSettingsCategory();
+ virtual ~CGUIWindowSettingsCategory();
+
+ // specialization of CGUIControl
+ virtual bool OnMessage(CGUIMessage &message);
+ virtual bool OnAction(const CAction &action);
+ virtual bool OnBack(int actionID);
+ virtual int GetID() const { return CGUIDialogSettingsManagerBase::GetID() + m_iSection; };
+
+ // specialization of CGUIWindow
+ virtual bool IsDialog() const { return false; }
+
+protected:
+ // specialization of CGUIWindow
+ virtual void OnWindowLoaded();
+
+ // implementation of CGUIDialogSettingsBase
+ virtual int GetSettingLevel() const;
+ virtual CSettingSection* GetSection();
+ virtual void Save();
+
+ CSettings& m_settings;
+ int m_iSection;
+ bool m_returningFromSkinLoad; // true if we are returning from loading the skin
+};
diff --git a/src/settings/windows/GUIWindowSettingsScreenCalibration.cpp b/src/settings/windows/GUIWindowSettingsScreenCalibration.cpp
new file mode 100644
index 0000000000..61addfa1c0
--- /dev/null
+++ b/src/settings/windows/GUIWindowSettingsScreenCalibration.cpp
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "system.h"
+#include "GUIWindowSettingsScreenCalibration.h"
+#include "guilib/GUIMoverControl.h"
+#include "guilib/GUIResizeControl.h"
+#ifdef HAS_VIDEO_PLAYBACK
+#include "cores/VideoRenderers/RenderManager.h"
+#endif
+#include "Application.h"
+#include "settings/DisplaySettings.h"
+#include "settings/Settings.h"
+#include "guilib/GUIWindowManager.h"
+#include "dialogs/GUIDialogYesNo.h"
+#include "guilib/Key.h"
+#include "guilib/LocalizeStrings.h"
+#include "utils/log.h"
+#include "utils/StringUtils.h"
+#include "windowing/WindowingFactory.h"
+
+using namespace std;
+
+#define CONTROL_LABEL_ROW1 2
+#define CONTROL_LABEL_ROW2 3
+#define CONTROL_TOP_LEFT 8
+#define CONTROL_BOTTOM_RIGHT 9
+#define CONTROL_SUBTITLES 10
+#define CONTROL_PIXEL_RATIO 11
+#define CONTROL_VIDEO 20
+#define CONTROL_NONE 0
+
+CGUIWindowSettingsScreenCalibration::CGUIWindowSettingsScreenCalibration(void)
+ : CGUIWindow(WINDOW_SCREEN_CALIBRATION, "SettingsScreenCalibration.xml")
+{
+ m_iCurRes = 0;
+ m_iControl = 0;
+ m_fPixelRatioBoxHeight = 0.0f;
+ m_needsScaling = false; // we handle all the scaling
+}
+
+CGUIWindowSettingsScreenCalibration::~CGUIWindowSettingsScreenCalibration(void)
+{}
+
+
+bool CGUIWindowSettingsScreenCalibration::OnAction(const CAction &action)
+{
+ switch (action.GetID())
+ {
+ case ACTION_CALIBRATE_SWAP_ARROWS:
+ {
+ NextControl();
+ return true;
+ }
+ break;
+
+ case ACTION_CALIBRATE_RESET:
+ {
+ CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
+ pDialog->SetHeading(20325);
+ CStdString strText = StringUtils::Format(g_localizeStrings.Get(20326).c_str(), g_graphicsContext.GetResInfo(m_Res[m_iCurRes]).strMode.c_str());
+ pDialog->SetLine(0, strText);
+ pDialog->SetLine(1, 20327);
+ pDialog->SetChoice(0, 222);
+ pDialog->SetChoice(1, 186);
+ pDialog->DoModal();
+ if (pDialog->IsConfirmed())
+ {
+ g_graphicsContext.ResetScreenParameters(m_Res[m_iCurRes]);
+ ResetControls();
+ }
+ return true;
+ }
+ break;
+
+ case ACTION_CHANGE_RESOLUTION:
+ // choose the next resolution in our list
+ {
+ m_iCurRes = (m_iCurRes+1) % m_Res.size();
+ g_graphicsContext.SetVideoResolution(m_Res[m_iCurRes]);
+ ResetControls();
+ return true;
+ }
+ break;
+ }
+ return CGUIWindow::OnAction(action); // base class to handle basic movement etc.
+}
+
+void CGUIWindowSettingsScreenCalibration::AllocResources(bool forceLoad)
+{
+ CGUIWindow::AllocResources(forceLoad);
+}
+
+void CGUIWindowSettingsScreenCalibration::FreeResources(bool forceUnload)
+{
+ CGUIWindow::FreeResources(forceUnload);
+}
+
+
+bool CGUIWindowSettingsScreenCalibration::OnMessage(CGUIMessage& message)
+{
+ switch ( message.GetMessage() )
+ {
+ case GUI_MSG_WINDOW_DEINIT:
+ {
+ CDisplaySettings::Get().UpdateCalibrations();
+ CSettings::Get().Save();
+ g_graphicsContext.SetCalibrating(false);
+ g_windowManager.ShowOverlay(OVERLAY_STATE_SHOWN);
+ // reset our screen resolution to what it was initially
+ g_graphicsContext.SetVideoResolution(CDisplaySettings::Get().GetCurrentResolution());
+ // Inform the player so we can update the resolution
+#ifdef HAS_VIDEO_PLAYBACK
+ g_renderManager.Update();
+#endif
+ g_windowManager.SendMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_WINDOW_RESIZE);
+ }
+ break;
+
+ case GUI_MSG_WINDOW_INIT:
+ {
+ CGUIWindow::OnMessage(message);
+ g_windowManager.ShowOverlay(OVERLAY_STATE_HIDDEN);
+ g_graphicsContext.SetCalibrating(true);
+
+ // Get the allowable resolutions that we can calibrate...
+ m_Res.clear();
+ if (g_application.m_pPlayer->IsPlayingVideo())
+ { // don't allow resolution switching if we are playing a video
+
+#ifdef HAS_VIDEO_PLAYBACK
+ RESOLUTION res = g_renderManager.GetResolution();
+ g_graphicsContext.SetVideoResolution(res);
+ // Inform the renderer so we can update the resolution
+ g_renderManager.Update();
+#endif
+
+ m_iCurRes = 0;
+ m_Res.push_back(g_graphicsContext.GetVideoResolution());
+ SET_CONTROL_VISIBLE(CONTROL_VIDEO);
+ }
+ else
+ {
+ SET_CONTROL_HIDDEN(CONTROL_VIDEO);
+ m_iCurRes = (unsigned int)-1;
+ g_graphicsContext.GetAllowedResolutions(m_Res);
+ // find our starting resolution
+ m_iCurRes = FindCurrentResolution();
+ }
+ if (m_iCurRes==(unsigned int)-1)
+ {
+ CLog::Log(LOGERROR, "CALIBRATION: Reported current resolution: %d", (int)g_graphicsContext.GetVideoResolution());
+ CLog::Log(LOGERROR, "CALIBRATION: Could not determine current resolution, falling back to default");
+ m_iCurRes = 0;
+ }
+
+ // Setup the first control
+ m_iControl = CONTROL_TOP_LEFT;
+ ResetControls();
+ return true;
+ }
+ break;
+ case GUI_MSG_CLICKED:
+ {
+ // clicked - change the control...
+ NextControl();
+ }
+ break;
+ case GUI_MSG_NOTIFY_ALL:
+ {
+ if (message.GetParam1() == GUI_MSG_WINDOW_RESIZE)
+ {
+ m_iCurRes = FindCurrentResolution();
+ }
+ }
+ break;
+ }
+ return CGUIWindow::OnMessage(message);
+}
+
+unsigned int CGUIWindowSettingsScreenCalibration::FindCurrentResolution()
+{
+ RESOLUTION curRes = g_graphicsContext.GetVideoResolution();
+ for (unsigned int i = 0; i < m_Res.size(); i++)
+ {
+ // If it's a CUSTOM (monitor) resolution, then g_graphicsContext.GetAllowedResolutions()
+ // returns just one entry with CUSTOM in it. Update that entry to point to the current
+ // CUSTOM resolution.
+ if (curRes>=RES_CUSTOM)
+ {
+ if (m_Res[i]==RES_CUSTOM)
+ {
+ m_Res[i] = curRes;
+ return i;
+ }
+ }
+ else if (m_Res[i] == g_graphicsContext.GetVideoResolution())
+ return i;
+ }
+ return 0;
+}
+
+void CGUIWindowSettingsScreenCalibration::NextControl()
+{ // set the old control invisible and not focused, and choose the next control
+ CGUIControl *pControl = GetControl(m_iControl);
+ if (pControl)
+ {
+ pControl->SetVisible(false);
+ pControl->SetFocus(false);
+ }
+ // switch to the next control
+ m_iControl++;
+ if (m_iControl > CONTROL_PIXEL_RATIO)
+ m_iControl = CONTROL_TOP_LEFT;
+ // enable the new control
+ EnableControl(m_iControl);
+}
+
+void CGUIWindowSettingsScreenCalibration::EnableControl(int iControl)
+{
+ SET_CONTROL_VISIBLE(CONTROL_TOP_LEFT);
+ SET_CONTROL_VISIBLE(CONTROL_BOTTOM_RIGHT);
+ SET_CONTROL_VISIBLE(CONTROL_SUBTITLES);
+ SET_CONTROL_VISIBLE(CONTROL_PIXEL_RATIO);
+ SET_CONTROL_FOCUS(iControl, 0);
+}
+
+void CGUIWindowSettingsScreenCalibration::ResetControls()
+{
+ // disable the video control, so that our other controls take mouse clicks etc.
+ CONTROL_DISABLE(CONTROL_VIDEO);
+ // disable the UI calibration for our controls
+ // and set their limits
+ // also, set them to invisible if they don't have focus
+ CGUIMoverControl *pControl = dynamic_cast<CGUIMoverControl*>(GetControl(CONTROL_TOP_LEFT));
+ RESOLUTION_INFO info = g_graphicsContext.GetResInfo(m_Res[m_iCurRes]);
+ if (pControl)
+ {
+ pControl->SetLimits( -info.iWidth / 4,
+ -info.iHeight / 4,
+ info.iWidth / 4,
+ info.iHeight / 4);
+ pControl->SetPosition((float)info.Overscan.left,
+ (float)info.Overscan.top);
+ pControl->SetLocation(info.Overscan.left,
+ info.Overscan.top, false);
+ }
+ pControl = dynamic_cast<CGUIMoverControl*>(GetControl(CONTROL_BOTTOM_RIGHT));
+ if (pControl)
+ {
+ pControl->SetLimits(info.iWidth*3 / 4,
+ info.iHeight*3 / 4,
+ info.iWidth*5 / 4,
+ info.iHeight*5 / 4);
+ pControl->SetPosition((float)info.Overscan.right - (int)pControl->GetWidth(),
+ (float)info.Overscan.bottom - (int)pControl->GetHeight());
+ pControl->SetLocation(info.Overscan.right,
+ info.Overscan.bottom, false);
+ }
+ // Subtitles and OSD controls can only move up and down
+ pControl = dynamic_cast<CGUIMoverControl*>(GetControl(CONTROL_SUBTITLES));
+ if (pControl)
+ {
+ pControl->SetLimits(0, info.iHeight*3 / 4,
+ 0, info.iHeight*5 / 4);
+ pControl->SetPosition((info.iWidth - pControl->GetWidth()) * 0.5f,
+ info.iSubtitles - pControl->GetHeight());
+ pControl->SetLocation(0, info.iSubtitles, false);
+ }
+ // lastly the pixel ratio control...
+ CGUIResizeControl *pResize = dynamic_cast<CGUIResizeControl*>(GetControl(CONTROL_PIXEL_RATIO));
+ if (pResize)
+ {
+ pResize->SetLimits(info.iWidth*0.25f, info.iHeight*0.5f,
+ info.iWidth*0.75f, info.iHeight*0.5f);
+ pResize->SetHeight(info.iHeight * 0.5f);
+ pResize->SetWidth(pResize->GetHeight() / info.fPixelRatio);
+ pResize->SetPosition((info.iWidth - pResize->GetWidth()) / 2,
+ (info.iHeight - pResize->GetHeight()) / 2);
+ }
+ // Enable the default control
+ EnableControl(m_iControl);
+}
+
+void CGUIWindowSettingsScreenCalibration::UpdateFromControl(int iControl)
+{
+ CStdString strStatus;
+ RESOLUTION_INFO info = g_graphicsContext.GetResInfo(m_Res[m_iCurRes]);
+
+ if (iControl == CONTROL_PIXEL_RATIO)
+ {
+ CGUIControl *pControl = GetControl(CONTROL_PIXEL_RATIO);
+ if (pControl)
+ {
+ float fWidth = (float)pControl->GetWidth();
+ float fHeight = (float)pControl->GetHeight();
+ info.fPixelRatio = fHeight / fWidth;
+ // recenter our control...
+ pControl->SetPosition((info.iWidth - pControl->GetWidth()) / 2,
+ (info.iHeight - pControl->GetHeight()) / 2);
+ strStatus = StringUtils::Format("%s (%5.3f)", g_localizeStrings.Get(275).c_str(), info.fPixelRatio);
+ SET_CONTROL_LABEL(CONTROL_LABEL_ROW2, 278);
+ }
+ }
+ else
+ {
+ const CGUIMoverControl *pControl = dynamic_cast<const CGUIMoverControl*>(GetControl(iControl));
+ if (pControl)
+ {
+ switch (iControl)
+ {
+ case CONTROL_TOP_LEFT:
+ {
+ info.Overscan.left = pControl->GetXLocation();
+ info.Overscan.top = pControl->GetYLocation();
+ strStatus = StringUtils::Format("%s (%i,%i)", g_localizeStrings.Get(272).c_str(), pControl->GetXLocation(), pControl->GetYLocation());
+ SET_CONTROL_LABEL(CONTROL_LABEL_ROW2, 276);
+ }
+ break;
+
+ case CONTROL_BOTTOM_RIGHT:
+ {
+ info.Overscan.right = pControl->GetXLocation();
+ info.Overscan.bottom = pControl->GetYLocation();
+ int iXOff1 = info.iWidth - pControl->GetXLocation();
+ int iYOff1 = info.iHeight - pControl->GetYLocation();
+ strStatus = StringUtils::Format("%s (%i,%i)", g_localizeStrings.Get(273).c_str(), iXOff1, iYOff1);
+ SET_CONTROL_LABEL(CONTROL_LABEL_ROW2, 276);
+ }
+ break;
+
+ case CONTROL_SUBTITLES:
+ {
+ info.iSubtitles = pControl->GetYLocation();
+ strStatus = StringUtils::Format("%s (%i)", g_localizeStrings.Get(274).c_str(), pControl->GetYLocation());
+ SET_CONTROL_LABEL(CONTROL_LABEL_ROW2, 277);
+ }
+ break;
+ }
+ }
+ }
+
+ g_graphicsContext.SetResInfo(m_Res[m_iCurRes], info);
+
+ // set the label control correctly
+ CStdString strText;
+ if (g_Windowing.IsFullScreen())
+ strText = StringUtils::Format("%ix%i@%.2f - %s | %s",
+ info.iScreenWidth,
+ info.iScreenHeight,
+ info.fRefreshRate,
+ g_localizeStrings.Get(244).c_str(),
+ strStatus.c_str());
+ else
+ strText = StringUtils::Format("%ix%i - %s | %s",
+ info.iScreenWidth,
+ info.iScreenHeight,
+ g_localizeStrings.Get(242).c_str(),
+ strStatus.c_str());
+
+ SET_CONTROL_LABEL(CONTROL_LABEL_ROW1, strText);
+}
+
+void CGUIWindowSettingsScreenCalibration::FrameMove()
+{
+ // g_Windowing.Get3DDevice()->Clear(0, NULL, D3DCLEAR_TARGET, 0, 0, 0);
+ m_iControl = GetFocusedControlID();
+ if (m_iControl >= 0)
+ {
+ UpdateFromControl(m_iControl);
+ }
+ else
+ {
+ SET_CONTROL_LABEL(CONTROL_LABEL_ROW1, "");
+ SET_CONTROL_LABEL(CONTROL_LABEL_ROW2, "");
+ }
+ CGUIWindow::FrameMove();
+}
+
+void CGUIWindowSettingsScreenCalibration::DoProcess(unsigned int currentTime, CDirtyRegionList &dirtyregions)
+{
+ MarkDirtyRegion();
+
+ for (int i = CONTROL_TOP_LEFT; i <= CONTROL_PIXEL_RATIO; i++)
+ SET_CONTROL_HIDDEN(i);
+
+ m_needsScaling = true;
+ CGUIWindow::DoProcess(currentTime, dirtyregions);
+ m_needsScaling = false;
+
+ g_graphicsContext.SetRenderingResolution(m_Res[m_iCurRes], false);
+ g_graphicsContext.AddGUITransform();
+
+ // process the movers etc.
+ for (int i = CONTROL_TOP_LEFT; i <= CONTROL_PIXEL_RATIO; i++)
+ {
+ SET_CONTROL_VISIBLE(i);
+ CGUIControl *control = GetControl(i);
+ if (control)
+ control->DoProcess(currentTime, dirtyregions);
+ }
+ g_graphicsContext.RemoveTransform();
+}
+
+void CGUIWindowSettingsScreenCalibration::DoRender()
+{
+ // we set that we need scaling here to render so that anything else on screen scales correctly
+ m_needsScaling = true;
+ CGUIWindow::DoRender();
+ m_needsScaling = false;
+}
diff --git a/src/settings/windows/GUIWindowSettingsScreenCalibration.h b/src/settings/windows/GUIWindowSettingsScreenCalibration.h
new file mode 100644
index 0000000000..671c09bed7
--- /dev/null
+++ b/src/settings/windows/GUIWindowSettingsScreenCalibration.h
@@ -0,0 +1,48 @@
+#pragma once
+
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "guilib/GUIWindow.h"
+
+class CGUIWindowSettingsScreenCalibration : public CGUIWindow
+{
+public:
+ CGUIWindowSettingsScreenCalibration(void);
+ virtual ~CGUIWindowSettingsScreenCalibration(void);
+ virtual bool OnMessage(CGUIMessage& message);
+ virtual bool OnAction(const CAction &action);
+ virtual void DoProcess(unsigned int currentTime, CDirtyRegionList &dirtyregions);
+ virtual void FrameMove();
+ virtual void DoRender();
+ virtual void AllocResources(bool forceLoad = false);
+ virtual void FreeResources(bool forceUnLoad = false);
+
+protected:
+ unsigned int FindCurrentResolution();
+ void NextControl();
+ void ResetControls();
+ void EnableControl(int iControl);
+ void UpdateFromControl(int iControl);
+ UINT m_iCurRes;
+ std::vector<RESOLUTION> m_Res;
+ int m_iControl;
+ float m_fPixelRatioBoxHeight;
+};
diff --git a/src/settings/windows/GUIWindowTestPattern.cpp b/src/settings/windows/GUIWindowTestPattern.cpp
new file mode 100644
index 0000000000..64f36fa462
--- /dev/null
+++ b/src/settings/windows/GUIWindowTestPattern.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "GUIWindowTestPattern.h"
+#include "settings/DisplaySettings.h"
+#include "guilib/GUIWindowManager.h"
+#include "guilib/Key.h"
+#include "guilib/WindowIDs.h"
+#include "windowing/WindowingFactory.h"
+
+
+CGUIWindowTestPattern::CGUIWindowTestPattern(void)
+ : CGUIWindow(WINDOW_TEST_PATTERN, "")
+ , m_white(1.0)
+ , m_black(0.0)
+{
+ m_pattern = 0;
+ m_bounceX = 0;
+ m_bounceY = 0;
+ m_bounceDirectionX = 0;
+ m_bounceDirectionY = 0;
+ m_blinkFrame = 0;
+ m_needsScaling = false;
+}
+
+CGUIWindowTestPattern::~CGUIWindowTestPattern(void)
+{}
+
+
+bool CGUIWindowTestPattern::OnAction(const CAction &action)
+{
+ switch (action.GetID())
+ {
+ case ACTION_MOVE_UP:
+ case ACTION_MOVE_LEFT:
+ m_pattern = m_pattern > 0 ? m_pattern - 1 : TEST_PATTERNS_COUNT - 1;
+ SetInvalid();
+ return true;
+
+ case ACTION_MOVE_DOWN:
+ case ACTION_MOVE_RIGHT:
+ m_pattern = (m_pattern + 1) % TEST_PATTERNS_COUNT;
+ SetInvalid();
+ return true;
+ }
+ return CGUIWindow::OnAction(action); // base class to handle basic movement etc.
+}
+
+bool CGUIWindowTestPattern::OnMessage(CGUIMessage& message)
+{
+ switch (message.GetMessage())
+ {
+ case GUI_MSG_WINDOW_INIT:
+ m_pattern = 0;
+ m_bounceDirectionX = 1;
+ m_bounceDirectionY = 1;
+ m_bounceX = 0;
+ m_bounceY = 0;
+ m_blinkFrame = 0;
+ break;
+
+ }
+ return CGUIWindow::OnMessage(message);
+}
+
+void CGUIWindowTestPattern::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
+{
+ if (m_pattern == 0 || m_pattern == 4)
+ MarkDirtyRegion();
+ CGUIWindow::Process(currentTime, dirtyregions);
+ m_renderRegion.SetRect(0, 0, (float)g_graphicsContext.GetWidth(), (float)g_graphicsContext.GetHeight());
+
+
+ if(g_Windowing.UseLimitedColor())
+ {
+ m_white = 235.0f / 255;
+ m_black = 16.0f / 255;
+ }
+ else
+ {
+ m_white = 1.0f;
+ m_black = 0.0f;
+ }
+}
+
+void CGUIWindowTestPattern::Render()
+{
+ BeginRender();
+ const RESOLUTION_INFO info = g_graphicsContext.GetResInfo();
+
+ int top = info.Overscan.top;
+ int bottom = info.Overscan.bottom;
+ int left = info.Overscan.left;
+ int right = info.Overscan.right;
+
+ switch (m_pattern)
+ {
+ case 0:
+ DrawContrastBrightnessPattern(top, left, bottom, right);
+ break;
+
+ case 1:
+ DrawVerticalLines(top, left, bottom, right);
+ break;
+
+ case 2:
+ DrawHorizontalLines(top, left, bottom, right);
+ break;
+
+ case 3:
+ DrawCheckers(top, left, bottom, right);
+ break;
+
+ case 4:
+ DrawBouncingRectangle(top, left, bottom, right);
+ break;
+ }
+
+ EndRender();
+
+ CGUIWindow::Render();
+}
+
diff --git a/src/settings/windows/GUIWindowTestPattern.h b/src/settings/windows/GUIWindowTestPattern.h
new file mode 100644
index 0000000000..ebba3c3781
--- /dev/null
+++ b/src/settings/windows/GUIWindowTestPattern.h
@@ -0,0 +1,60 @@
+#pragma once
+
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "guilib/GUIWindow.h"
+
+#define TEST_PATTERNS_COUNT 5
+#define TEST_PATTERNS_BOUNCE_SQUARE_SIZE 100
+#define TEST_PATTERNS_BLINK_CYCLE 100
+
+class CGUIWindowTestPattern : public CGUIWindow
+{
+public:
+ CGUIWindowTestPattern(void);
+ virtual ~CGUIWindowTestPattern(void);
+ virtual bool OnMessage(CGUIMessage& message);
+ virtual bool OnAction(const CAction &action);
+ virtual void Render();
+ virtual void Process(unsigned int currentTime, CDirtyRegionList &dirtyregions);
+
+protected:
+ virtual void DrawVerticalLines(int top, int left, int bottom, int right) = 0;
+ virtual void DrawHorizontalLines(int top, int left, int bottom, int right) = 0;
+ virtual void DrawCheckers(int top, int left, int bottom, int right) = 0;
+ virtual void DrawBouncingRectangle(int top, int left, int bottom, int right) = 0;
+ virtual void DrawContrastBrightnessPattern(int top, int left, int bottom, int right) = 0;
+ virtual void DrawCircle(int originX, int originY, int radius) = 0;
+ virtual void BeginRender() = 0;
+ virtual void EndRender() = 0;
+
+ int m_pattern;
+ int m_bounceX;
+ int m_bounceY;
+ int m_bounceDirectionX;
+ int m_bounceDirectionY;
+ int m_blinkFrame;
+
+ float m_white;
+ float m_black;
+};
+
+
diff --git a/src/settings/windows/Makefile b/src/settings/windows/Makefile
new file mode 100644
index 0000000000..8f9761601e
--- /dev/null
+++ b/src/settings/windows/Makefile
@@ -0,0 +1,10 @@
+SRCS=GUIControlSettings.cpp \
+ GUIWindowSettings.cpp \
+ GUIWindowSettingsCategory.cpp \
+ GUIWindowSettingsScreenCalibration.cpp \
+ GUIWindowTestPattern.cpp \
+
+LIB=settings_windows.a
+
+include ../../../Makefile.include
+-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS)))