Classes to describe settings in a generic way.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33903 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-11-05 17:32:16 +00:00
parent 76d24e95aa
commit 4924e2e9ae
6 changed files with 696 additions and 0 deletions
@@ -0,0 +1,265 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "Setting.h"
#include <new>
// #pragma mark - Setting
Setting::~Setting()
{
}
// #pragma mark - BoolSetting
setting_type
BoolSetting::Type() const
{
return SETTING_TYPE_BOOL;
}
BVariant
BoolSetting::DefaultValue() const
{
return DefaultBoolValue();
}
// #pragma mark - SettingsOption
SettingsOption::~SettingsOption()
{
}
// #pragma mark - OptionsSetting
setting_type
OptionsSetting::Type() const
{
return SETTING_TYPE_OPTIONS;
}
BVariant
OptionsSetting::DefaultValue() const
{
SettingsOption* option = DefaultOption();
return option != NULL
? BVariant(option->ID(), B_VARIANT_DONT_COPY_DATA) : BVariant();
}
// #pragma mark - RangeSetting
setting_type
RangeSetting::Type() const
{
return SETTING_TYPE_RANGE;
}
// #pragma mark - AbstractSetting
AbstractSetting::AbstractSetting(const BString& id, const BString& name)
:
fID(id),
fName(name)
{
}
const char*
AbstractSetting::ID() const
{
return fID;
}
const char*
AbstractSetting::Name() const
{
return fName;
}
// #pragma mark - BoolSettingImpl
BoolSettingImpl::BoolSettingImpl(const BString& id, const BString& name,
bool defaultValue)
:
AbstractSetting(id, name),
fDefaultValue(defaultValue)
{
}
bool
BoolSettingImpl::DefaultBoolValue() const
{
return fDefaultValue;
}
// #pragma mark - OptionsSettingImpl
class OptionsSettingImpl::Option : public SettingsOption {
public:
Option(const BString& id, const BString& name)
{
}
virtual const char* ID() const
{
return fID;
}
virtual const char* Name() const
{
return fName;
}
private:
BString fID;
BString fName;
};
OptionsSettingImpl::OptionsSettingImpl(const BString& id, const BString& name)
:
AbstractSetting(id, name),
fDefaultOption(NULL)
{
}
OptionsSettingImpl::~OptionsSettingImpl()
{
SetDefaultOption(NULL);
for (int32 i = 0; SettingsOption* option = fOptions.ItemAt(i); i++)
option->ReleaseReference();
}
SettingsOption*
OptionsSettingImpl::DefaultOption() const
{
return fDefaultOption != NULL ? fDefaultOption : fOptions.ItemAt(0);
}
int32
OptionsSettingImpl::CountOptions() const
{
return fOptions.CountItems();
}
SettingsOption*
OptionsSettingImpl::OptionAt(int32 index) const
{
return fOptions.ItemAt(index);
}
SettingsOption*
OptionsSettingImpl::OptionByID(const char* id) const
{
for (int32 i = 0; SettingsOption* option = fOptions.ItemAt(i); i++) {
if (strcmp(option->ID(), id) == 0)
return option;
}
return NULL;
}
bool
OptionsSettingImpl::AddOption(SettingsOption* option)
{
if (!fOptions.AddItem(option))
return false;
option->AddReference();
return true;
}
bool
OptionsSettingImpl::AddOption(const BString& id, const BString& name)
{
Option* option = new(std::nothrow) Option(id, name);
if (option == NULL)
return false;
Reference<Option> optionReference(option, true);
return AddOption(option);
}
void
OptionsSettingImpl::SetDefaultOption(SettingsOption* option)
{
if (option == fDefaultOption)
return;
if (fDefaultOption != NULL)
fDefaultOption->ReleaseReference();
fDefaultOption = option;
if (fDefaultOption != NULL)
fDefaultOption->AcquireReference();
}
// #pragma mark - RangeSettingImpl
RangeSettingImpl::RangeSettingImpl(const BString& id, const BString& name,
const BVariant& lowerBound, const BVariant& upperBound,
const BVariant& defaultValue)
:
AbstractSetting(id, name),
fLowerBound(lowerBound),
fUpperBound(upperBound),
fDefaultValue(defaultValue)
{
}
BVariant
RangeSettingImpl::DefaultValue() const
{
return fDefaultValue;
}
BVariant
RangeSettingImpl::LowerBound() const
{
return fLowerBound;
}
BVariant
RangeSettingImpl::UpperBound() const
{
return fUpperBound;
}
@@ -0,0 +1,152 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef SETTING_H
#define SETTING_H
#include <String.h>
#include <ObjectList.h>
#include <Referenceable.h>
#include <Variant.h>
enum setting_type {
SETTING_TYPE_BOOL,
SETTING_TYPE_OPTIONS,
SETTING_TYPE_RANGE
};
class Setting : public BReferenceable {
public:
virtual ~Setting();
virtual setting_type Type() const = 0;
virtual const char* ID() const = 0;
virtual const char* Name() const = 0;
virtual BVariant DefaultValue() const = 0;
};
class BoolSetting : public virtual Setting {
public:
virtual setting_type Type() const;
virtual BVariant DefaultValue() const;
virtual bool DefaultBoolValue() const = 0;
};
class SettingsOption : public BReferenceable {
public:
virtual ~SettingsOption();
virtual const char* ID() const = 0;
virtual const char* Name() const = 0;
};
class OptionsSetting : public virtual Setting {
public:
virtual setting_type Type() const;
virtual BVariant DefaultValue() const;
virtual int32 CountOptions() const = 0;
virtual SettingsOption* OptionAt(int32 index) const = 0;
virtual SettingsOption* OptionByID(const char* id) const = 0;
virtual SettingsOption* DefaultOption() const = 0;
};
class RangeSetting : public virtual Setting {
public:
virtual setting_type Type() const;
virtual BVariant LowerBound() const = 0;
virtual BVariant UpperBound() const = 0;
};
class AbstractSetting : public virtual Setting {
public:
AbstractSetting(const BString& id,
const BString& name);
virtual const char* ID() const;
virtual const char* Name() const;
private:
BString fID;
BString fName;
};
class BoolSettingImpl : public AbstractSetting, public BoolSetting {
public:
BoolSettingImpl(const BString& id,
const BString& name, bool defaultValue);
virtual bool DefaultBoolValue() const;
private:
bool fDefaultValue;
};
class OptionsSettingImpl : public AbstractSetting, public OptionsSetting {
public:
OptionsSettingImpl(const BString& id,
const BString& name);
virtual ~OptionsSettingImpl();
virtual SettingsOption* DefaultOption() const;
virtual int32 CountOptions() const;
virtual SettingsOption* OptionAt(int32 index) const;
virtual SettingsOption* OptionByID(const char* id) const;
bool AddOption(SettingsOption* option);
bool AddOption(const BString& id,
const BString& name);
void SetDefaultOption(SettingsOption* option);
private:
class Option;
typedef BObjectList<SettingsOption> OptionList;
private:
OptionList fOptions;
SettingsOption* fDefaultOption;
};
class RangeSettingImpl : public AbstractSetting, public RangeSetting {
public:
RangeSettingImpl(const BString& id,
const BString& name,
const BVariant& lowerBound,
const BVariant& upperBound,
const BVariant& defaultValue);
virtual BVariant DefaultValue() const;
virtual BVariant LowerBound() const;
virtual BVariant UpperBound() const;
private:
BVariant fLowerBound;
BVariant fUpperBound;
BVariant fDefaultValue;
};
#endif // SETTING_H
@@ -0,0 +1,115 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "Settings.h"
#include <AutoLocker.h>
#include "SettingsDescription.h"
// #pragma mark - Settings
Settings::Settings(SettingsDescription* description)
:
fLock("settings"),
fDescription(description)
{
fDescription->AcquireReference();
}
Settings::~Settings()
{
fDescription->ReleaseReference();
}
status_t
Settings::Init()
{
return fLock.InitCheck();
}
BVariant
Settings::Value(Setting* setting) const
{
AutoLocker<BLocker> locker(fLock);
BVariant value;
return value.SetFromMessage(fValues, setting->ID()) == B_OK
? value : setting->DefaultValue();
}
BVariant
Settings::Value(const char* settingID) const
{
AutoLocker<BLocker> locker(fLock);
BVariant value;
if (value.SetFromMessage(fValues, settingID) == B_OK)
return value;
Setting* setting = fDescription->SettingByID(settingID);
return setting != NULL ? setting->DefaultValue() : value;
}
bool
Settings::SetValue(Setting* setting, const BVariant& value)
{
AutoLocker<BLocker> locker(fLock);
// remove the message field and re-add it with the new value
const char* fieldName = setting->ID();
fValues.RemoveName(fieldName);
bool success = value.AddToMessage(fValues, fieldName) == B_OK;
// notify the listeners
int32 count = fListeners.CountItems();
for (int32 i = count - 1; i >= 0; i--)
fListeners.ItemAt(i)->SettingValueChanged(setting);
return success;
}
SettingsOption*
Settings::OptionValue(OptionsSetting* setting) const
{
BVariant value = Value(setting);
return value.Type() == B_STRING_TYPE
? setting->OptionByID(value.ToString())
: setting->DefaultOption();
}
bool
Settings::AddListener(Listener* listener)
{
AutoLocker<BLocker> locker(fLock);
return fListeners.AddItem(listener);
}
void
Settings::RemoveListener(Listener* listener)
{
AutoLocker<BLocker> locker(fLock);
fListeners.RemoveItem(listener);
}
// #pragma mark - Listener
Settings::Listener::~Listener()
{
}
@@ -0,0 +1,71 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef SETTINGS_H
#define SETTINGS_H
#include <Locker.h>
#include <Message.h>
#include <ObjectList.h>
#include <Referenceable.h>
#include <Variant.h>
#include "Setting.h"
class SettingsDescription;
class Settings : public BReferenceable {
public:
class Listener;
public:
Settings(SettingsDescription* description);
virtual ~Settings();
status_t Init();
bool Lock() { return fLock.Lock(); }
void Unlock() { fLock.Unlock(); }
SettingsDescription* Description() const { return fDescription; }
const BMessage& Message() const { return fValues; }
BVariant Value(Setting* setting) const;
BVariant Value(const char* settingID) const;
bool SetValue(Setting* setting,
const BVariant& value);
bool BoolValue(BoolSetting* setting) const
{ return Value(setting).ToBool(); }
SettingsOption* OptionValue(OptionsSetting* setting) const;
BVariant RangeValue(RangeSetting* setting) const
{ return Value(setting); }
bool AddListener(Listener* listener);
void RemoveListener(Listener* listener);
private:
typedef BObjectList<Listener> ListenerList;
private:
mutable BLocker fLock;
SettingsDescription* fDescription;
BMessage fValues;
ListenerList fListeners;
};
class Settings::Listener {
public:
virtual ~Listener();
virtual void SettingValueChanged(Setting* setting) = 0;
};
#endif // SETTINGS_H
@@ -0,0 +1,58 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "SettingsDescription.h"
#include "Setting.h"
SettingsDescription::SettingsDescription()
{
}
SettingsDescription::~SettingsDescription()
{
for (int32 i = 0; Setting* setting = SettingAt(i); i++)
setting->ReleaseReference();
}
int32
SettingsDescription::CountSettings() const
{
return fSettings.CountItems();
}
Setting*
SettingsDescription::SettingAt(int32 index) const
{
return fSettings.ItemAt(index);
}
Setting*
SettingsDescription::SettingByID(const char* id) const
{
for (int32 i = 0; Setting* setting = fSettings.ItemAt(i); i++) {
if (strcmp(setting->ID(), id) == 0)
return setting;
}
return NULL;
}
bool
SettingsDescription::AddSetting(Setting* setting)
{
if (!fSettings.AddItem(setting))
return false;
setting->AcquireReference();
return true;
}
@@ -0,0 +1,35 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef SETTINGS_DESCRIPTION_H
#define SETTINGS_DESCRIPTION_H
#include <ObjectList.h>
#include <Referenceable.h>
class Setting;
class SettingsDescription : public BReferenceable {
public:
SettingsDescription();
virtual ~SettingsDescription();
int32 CountSettings() const;
Setting* SettingAt(int32 index) const;
Setting* SettingByID(const char* id) const;
bool AddSetting(Setting* setting);
private:
typedef BObjectList<Setting> SettingsList;
private:
SettingsList fSettings;
};
#endif // SETTINGS_DESCRIPTION_H