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:
@@ -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
|
||||
Reference in New Issue
Block a user