diff --git a/application/core/Configurators/ManiaControlSettings.php b/application/core/Configurators/ManiaControlSettings.php index 9dd93a54..6f26ce45 100644 --- a/application/core/Configurators/ManiaControlSettings.php +++ b/application/core/Configurators/ManiaControlSettings.php @@ -2,6 +2,7 @@ namespace ManiaControl\Configurators; +use FML\Components\ValuePicker; use FML\Controls\Control; use FML\Controls\Entry; use FML\Controls\Frame; @@ -126,6 +127,8 @@ class ManiaControlSettings implements ConfiguratorMenu, CallbackListener { $index = 0; $y = 0; foreach ($settings as $setting) { + /** @var Setting $setting */ + if (!$pageFrame) { $pageFrame = new Frame(); $frame->add($pageFrame); @@ -162,22 +165,33 @@ class ManiaControlSettings implements ConfiguratorMenu, CallbackListener { $nameLabel->setText($setting->setting); $nameLabel->setTextColor("FFF"); + $settingName = self::ACTION_PREFIX_SETTING . $setting->index; if ($setting->type === Setting::TYPE_BOOL) { + // TODO: implement fml checkbox $quad = new Quad_Icons64x64_1(); $settingFrame->add($quad); - $quad->setX($width / 2 * 0.6); - $quad->setZ(-0.01); - $quad->setSubStyle(($setting->value ? $quad::SUBSTYLE_LvlGreen : $quad::SUBSTYLE_LvlRed)); + $quad->setPosition($width * 0.33, 0, -0.01); $quad->setSize(4, 4); - $quad->setAction(self::ACTION_SETTING_BOOL . $setting->index); + $quad->setSubStyle(($setting->value ? $quad::SUBSTYLE_LvlGreen : $quad::SUBSTYLE_LvlRed)); + $quad->setAction($settingName); + } else if ($setting->type === Setting::TYPE_SET) { + // SET value picker + $label = new Label_Text(); + $label->setX($width * 0.33); + $label->setSize($width * 0.3, $settingHeight * 0.9); + $label->setStyle($label::STYLE_TextValueSmall); + $label->setTextSize(1); + $valuePicker = new ValuePicker($settingName, $setting->set, $setting->value, $label); + $settingFrame->add($valuePicker); } else { + // Standard entry $entry = new Entry(); $settingFrame->add($entry); - $entry->setStyle(Label_Text::STYLE_TextValueSmall); - $entry->setX($width / 2 * 0.65); - $entry->setTextSize(1); + $entry->setX($width * 0.33); $entry->setSize($width * 0.3, $settingHeight * 0.9); - $entry->setName(self::ACTION_PREFIX_SETTING . $setting->index); + $entry->setStyle(Label_Text::STYLE_TextValueSmall); + $entry->setTextSize(1); + $entry->setName($settingName); $entry->setDefault($setting->value); } @@ -364,19 +378,17 @@ class ManiaControlSettings implements ConfiguratorMenu, CallbackListener { return; } - $maniaControlSettings = $this->maniaControl->settingManager->getSettings(); - $prefixLength = strlen(self::ACTION_PREFIX_SETTING); + foreach ($configData[3] as $settingData) { + $settingIndex = substr($settingData['Name'], $prefixLength); - foreach ($configData[3] as $setting) { - $settingName = substr($setting['Name'], $prefixLength); - - $oldSetting = $maniaControlSettings[$settingName]; - if ($setting['Value'] == $oldSetting->value || $oldSetting->type == 'bool') { + $setting = $this->maniaControl->settingManager->getSettingObjectByIndex($settingIndex); + if (!$setting || $settingData['Value'] == $setting->value || $setting->type === Setting::TYPE_BOOL) { continue; } - $this->maniaControl->settingManager->setSetting($oldSetting->class, $oldSetting->setting, $setting['Value']); + $setting->value = $settingData['Value']; + $this->maniaControl->settingManager->saveSetting($setting); } $this->maniaControl->chat->sendSuccess('Settings saved!', $player); diff --git a/application/core/Libs/FML/Script/Features/ValuePickerFeature.php b/application/core/Libs/FML/Script/Features/ValuePickerFeature.php index 6f6d57f8..5a76e3c5 100644 --- a/application/core/Libs/FML/Script/Features/ValuePickerFeature.php +++ b/application/core/Libs/FML/Script/Features/ValuePickerFeature.php @@ -50,6 +50,29 @@ class ValuePickerFeature extends ScriptFeature { $this->setDefault($default); } + /** + * Set the possible Values + * + * @param array $values Possible Values + * @return \FML\Script\Features\ValuePickerFeature + */ + public function setValues(array $values) { + $this->values = array(); + foreach ($values as $value) { + array_push($this->values, (string)$value); + } + return $this; + } + + /** + * Get the ValuePicker Label + * + * @return \FML\Controls\Label + */ + public function getLabel() { + return $this->label; + } + /** * Set the ValuePicker Label * @@ -66,12 +89,12 @@ class ValuePickerFeature extends ScriptFeature { } /** - * Get the ValuePicker Label + * Get the hidden Entry * - * @return \FML\Controls\Label + * @return \FML\Controls\Entry */ - public function getLabel() { - return $this->label; + public function getEntry() { + return $this->entry; } /** @@ -88,54 +111,6 @@ class ValuePickerFeature extends ScriptFeature { return $this; } - /** - * Get the hidden Entry - * - * @return \FML\Controls\Entry - */ - public function getEntry() { - return $this->entry; - } - - /** - * Set the possible Values - * - * @param array $values Possible Values - * @return \FML\Script\Features\ValuePickerFeature - */ - public function setValues(array $values) { - $this->values = array(); - foreach ($values as $value) { - array_push($this->values, (string)$value); - } - return $this; - } - - /** - * Set the default Value - * - * @param string $default Default Value - * @return \FML\Script\Features\ValuePickerFeature - */ - public function setDefault($default) { - $this->default = (string)$default; - } - - /** - * Get the default Value - * - * @return string - */ - public function getDefault() { - if ($this->default) { - return $this->default; - } - if ($this->values) { - return reset($this->values); - } - return null; - } - /** * @see \FML\Script\Features\ScriptFeature::prepare() */ @@ -144,7 +119,7 @@ class ValuePickerFeature extends ScriptFeature { $script->setScriptInclude(ScriptInclude::TEXTLIB); $script->addScriptFunction(self::FUNCTION_UPDATE_PICKER_VALUE, $this->buildUpdatePickerValueFunction()); $script->appendGenericScriptLabel(ScriptLabel::ONINIT, $this->buildInitScriptText(), true); - $script->appendGenericScriptLabel(ScriptLabel::ONINIT, $this->buildClickScriptText()); + $script->appendGenericScriptLabel(ScriptLabel::MOUSECLICK, $this->buildClickScriptText()); } return $this; } @@ -158,12 +133,14 @@ class ValuePickerFeature extends ScriptFeature { $functionText = " Void " . self::FUNCTION_UPDATE_PICKER_VALUE . "(CMlLabel _Label) { declare " . self::VAR_PICKER_VALUES . " as Values for _Label = Text[]; - declare NewValueIndex = 0; - if (Values.exists(_Label.Value) { - declare ValueIndex = _Label.keyof(_Label.Value); + declare NewValueIndex = -1; + if (Values.exists(_Label.Value)) { + declare ValueIndex = Values.keyof(_Label.Value); ValueIndex += 1; if (Values.existskey(ValueIndex)) { NewValueIndex = ValueIndex; + } else { + NewValueIndex = 0; } } declare NewValue = \"\"; @@ -209,6 +186,31 @@ EntryId = \"{$entryId}\"; return $scriptText; } + /** + * Get the default Value + * + * @return string + */ + public function getDefault() { + if ($this->default) { + return $this->default; + } + if ($this->values) { + return reset($this->values); + } + return null; + } + + /** + * Set the default Value + * + * @param string $default Default Value + * @return \FML\Script\Features\ValuePickerFeature + */ + public function setDefault($default) { + $this->default = (string)$default; + } + /** * Build the Script Text for Label Clicks * diff --git a/application/core/Settings/Setting.php b/application/core/Settings/Setting.php index 968555df..4f9808ed 100644 --- a/application/core/Settings/Setting.php +++ b/application/core/Settings/Setting.php @@ -123,6 +123,15 @@ class Setting { return null; } + /** + * Get whether the Setting has been persisted at some point + * + * @return bool + */ + public function isPersisted() { + return ($this->index > 0); + } + /** * Get the Formatted Value of the Setting * diff --git a/application/core/Settings/SettingManager.php b/application/core/Settings/SettingManager.php index 31d8df5c..0d85c64b 100644 --- a/application/core/Settings/SettingManager.php +++ b/application/core/Settings/SettingManager.php @@ -100,20 +100,49 @@ class SettingManager implements CallbackListener { return false; } if ($result) { - $this->storedSettings = array(); + $this->clearStorage(); return true; } return false; } /** - * Get a Setting by its Index + * Clear the Settings Storage + */ + public function clearStorage() { + $this->storedSettings = array(); + } + + /** + * @deprecated + * @see SettingManager::getSettingValueByIndex() + */ + public function getSettingByIndex($settingIndex, $defaultValue = null) { + return $this->getSettingValueByIndex($settingIndex, $defaultValue); + } + + /** + * Get a Setting Value by its Index * * @param int $settingIndex * @param mixed $defaultValue + * @return mixed + */ + public function getSettingValueByIndex($settingIndex, $defaultValue = null) { + $setting = $this->getSettingObjectByIndex($settingIndex); + if (!$setting) { + return $defaultValue; + } + return $setting->value; + } + + /** + * Get a Setting Object by its Index + * + * @param int $settingIndex * @return Setting */ - public function getSettingByIndex($settingIndex, $defaultValue = null) { + public function getSettingObjectByIndex($settingIndex) { $mysqli = $this->maniaControl->database->mysqli; $settingQuery = "SELECT * FROM `" . self::TABLE_SETTINGS . "` WHERE `index` = {$settingIndex};"; @@ -123,44 +152,58 @@ class SettingManager implements CallbackListener { return null; } if ($result->num_rows <= 0) { - $result->close(); - return $defaultValue; + $result->free(); + return null; } /** @var Setting $setting */ $setting = $result->fetch_object(Setting::CLASS_NAME, array(false, null, null)); - $result->close(); + $result->free(); + + $this->storeSetting($setting); return $setting; } + /** + * Store the given Setting + * + * @param Setting $setting + */ + private function storeSetting(Setting $setting) { + $this->storedSettings[$setting->class . $setting->setting] = $setting; + } + /** * Set a Setting for the given Object * * @param mixed $object * @param string $settingName * @param mixed $value - * @return Setting + * @return bool */ public function setSetting($object, $settingName, $value) { - $className = ClassUtil::getClass($object); - $setting = $this->getSettingObject($object, $settingName); if ($setting) { $setting->value = $value; - if (!$this->saveSetting($setting)) { - return null; + $saved = $this->saveSetting($setting); + if (!$saved) { + return false; } } else { - $setting = $this->initSetting($object, $settingName, $value); + $saved = $this->initSetting($object, $settingName, $value); + if (!$saved) { + return false; + } + $setting = $this->getSettingObject($object, $settingName, $value); } - $this->storedSettings[$className . $settingName] = $setting; + $this->storeSetting($setting); // Trigger Settings Changed Callback $this->maniaControl->callbackManager->triggerCallback(self::CB_SETTING_CHANGED, $setting); - return $setting; + return true; } /** @@ -175,8 +218,9 @@ class SettingManager implements CallbackListener { $settingClass = ClassUtil::getClass($object); // Retrieve from Storage if possible - if (isset($this->storedSettings[$settingClass . $settingName])) { - return $this->storedSettings[$settingClass . $settingName]; + $storedSetting = $this->getStoredSetting($object, $settingName); + if ($storedSetting) { + return $storedSetting; } // Fetch setting @@ -190,48 +234,71 @@ class SettingManager implements CallbackListener { return null; } if ($result->num_rows <= 0) { + $result->free(); if ($default === null) { return null; } - $setting = $this->initSetting($object, $settingName, $default); - return $setting; + $saved = $this->initSetting($object, $settingName, $default); + if ($saved) { + return $this->getSettingObject($object, $settingName, $default); + } else { + return null; + } } /** @var Setting $setting */ $setting = $result->fetch_object(Setting::CLASS_NAME, array(false, null, null)); $result->free(); - // Store setting - $this->storedSettings[$settingClass . $settingName] = $setting; + $this->storeSetting($setting); return $setting; } + /** + * Retrieve a stored Setting + * + * @param mixed $settingClass + * @param string $settingName + * @return Setting + */ + private function getStoredSetting($settingClass, $settingName) { + $settingClass = ClassUtil::getClass($settingClass); + if (isset($this->storedSettings[$settingClass . $settingName])) { + return $this->storedSettings[$settingClass . $settingName]; + } + return null; + } + /** * Initialize a Setting for the given Object * * @param mixed $object * @param string $settingName * @param mixed $defaultValue - * @return Setting + * @return bool */ public function initSetting($object, $settingName, $defaultValue) { $setting = new Setting($object, $settingName, $defaultValue); - $saved = $this->saveSetting($setting); - if ($saved) { - return $setting; - } - return null; + return $this->saveSetting($setting, true); } /** * Save the given Setting in the Database * * @param Setting $setting + * @param bool $init * @return bool */ - public function saveSetting(Setting &$setting) { - $mysqli = $this->maniaControl->database->mysqli; + public function saveSetting(Setting $setting, $init = false) { + $mysqli = $this->maniaControl->database->mysqli; + if ($init) { + // Init - Keep old value if the default didn't change + $valueUpdateString = '`value` = IF(`default` = VALUES(`default`), `value`, VALUES(`default`))'; + } else { + // Set - Update value in any case + $valueUpdateString = '`value` = VALUES(`value`)'; + } $settingQuery = "INSERT INTO `" . self::TABLE_SETTINGS . "` ( `class`, `setting`, @@ -249,7 +316,7 @@ class SettingManager implements CallbackListener { ) ON DUPLICATE KEY UPDATE `index` = LAST_INSERT_ID(`index`), `type` = VALUES(`type`), - `value` = IF(`default` = VALUES(`default`), `value`, VALUES(`default`)), + {$valueUpdateString}, `default` = VALUES(`default`), `set` = VALUES(`set`), `changed` = NOW();"; @@ -268,7 +335,6 @@ class SettingManager implements CallbackListener { $settingStatement->close(); return false; } - $setting->index = $settingStatement->insert_id; $settingStatement->close(); return true; }