* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "Property.h"
#include <new>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <Message.h>
#include "support.h"
using std::nothrow;
Property::Property(uint32 identifier)
: fIdentifier(identifier),
fEditable(true)
{
}
Property::Property(const Property& other)
: fIdentifier(other.fIdentifier),
fEditable(other.fEditable)
{
}
Property::Property(BMessage* archive)
: fIdentifier(0),
fEditable(true)
{
if (!archive)
return;
if (archive->FindInt32("id", (int32*)&fIdentifier) < B_OK)
fIdentifier = 0;
if (archive->FindBool("editable", &fEditable) < B_OK)
fEditable = true;
}
Property::~Property()
{
}
status_t
Property::Archive(BMessage* into, bool deep) const
{
status_t ret = BArchivable::Archive(into, deep);
if (ret == B_OK)
ret = into->AddInt32("id", fIdentifier);
if (ret == B_OK)
ret = into->AddBool("editable", fEditable);
if (ret >= B_OK)
ret = into->AddString("class", "Property");
return ret;
}
bool
Property::InterpolateTo(const Property* other, float scale)
{
return false;
}
void
Property::SetEditable(bool editable)
{
fEditable = editable;
}
IntProperty::IntProperty(uint32 identifier, int32 value,
int32 min, int32 max)
: Property(identifier),
fValue(value),
fMin(min),
fMax(max)
{
}
IntProperty::IntProperty(const IntProperty& other)
: Property(other),
fValue(other.fValue),
fMin(other.fMin),
fMax(other.fMax)
{
}
IntProperty::IntProperty(BMessage* archive)
: Property(archive),
fValue(0),
fMin(0),
fMax(0)
{
if (!archive)
return;
if (archive->FindInt32("value", &fValue) < B_OK)
fValue = 0;
if (archive->FindInt32("min", &fMin) < B_OK)
fMin = 0;
if (archive->FindInt32("max", &fMax) < B_OK)
fMax = 0;
}
IntProperty::~IntProperty()
{
}
status_t
IntProperty::Archive(BMessage* into, bool deep) const
{
status_t ret = Property::Archive(into, deep);
if (ret >= B_OK)
ret = into->AddInt32("value", fValue);
if (ret >= B_OK)
ret = into->AddInt32("min", fMin);
if (ret >= B_OK)
ret = into->AddInt32("max", fMax);
if (ret >= B_OK)
ret = into->AddString("class", "IntProperty");
return ret;
}
BArchivable*
IntProperty::Instantiate(BMessage* archive)
{
if (validate_instantiation(archive, "IntProperty"))
return new IntProperty(archive);
return NULL;
}
Property*
IntProperty::Clone() const
{
return new IntProperty(*this);
}
bool
IntProperty::SetValue(const char* value)
{
return SetValue(atoi(value));
}
bool
IntProperty::SetValue(const Property* other)
{
const IntProperty* i = dynamic_cast<const IntProperty*>(other);
if (i) {
return SetValue(i->Value());
}
return false;
}
void
IntProperty::GetValue(BString& string)
{
string << fValue;
}
bool
IntProperty::InterpolateTo(const Property* other, float scale)
{
const IntProperty* i = dynamic_cast<const IntProperty*>(other);
if (i) {
return SetValue(fValue + (int32)((float)(i->Value()
- fValue) * scale + 0.5));
}
return false;
}
bool
IntProperty::SetValue(int32 value)
{
if (value < fMin)
value = fMin;
if (value > fMax)
value = fMax;
if (value != fValue) {
fValue = value;
return true;
}
return false;
}
FloatProperty::FloatProperty(uint32 identifier, float value,
float min, float max)
: Property(identifier),
fValue(value),
fMin(min),
fMax(max)
{
}
FloatProperty::FloatProperty(const FloatProperty& other)
: Property(other),
fValue(other.fValue),
fMin(other.fMin),
fMax(other.fMax)
{
}
FloatProperty::FloatProperty(BMessage* archive)
: Property(archive),
fValue(0.0),
fMin(0.0),
fMax(0.0)
{
if (!archive)
return;
if (archive->FindFloat("value", &fValue) < B_OK)
fValue = 0.0;
if (archive->FindFloat("min", &fMin) < B_OK)
fMin = 0.0;
if (archive->FindFloat("max", &fMax) < B_OK)
fMax = 0.0;
}
FloatProperty::~FloatProperty()
{
}
status_t
FloatProperty::Archive(BMessage* into, bool deep) const
{
status_t ret = Property::Archive(into, deep);
if (ret >= B_OK)
ret = into->AddFloat("value", fValue);
if (ret >= B_OK)
ret = into->AddFloat("min", fMin);
if (ret >= B_OK)
ret = into->AddFloat("max", fMax);
if (ret >= B_OK)
ret = into->AddString("class", "FloatProperty");
return ret;
}
BArchivable*
FloatProperty::Instantiate(BMessage* archive)
{
if (validate_instantiation(archive, "FloatProperty"))
return new FloatProperty(archive);
return NULL;
}
Property*
FloatProperty::Clone() const
{
return new FloatProperty(*this);
}
bool
FloatProperty::SetValue(const char* value)
{
return SetValue(atof(value));
}
bool
FloatProperty::SetValue(const Property* other)
{
const FloatProperty* f = dynamic_cast<const FloatProperty*>(other);
if (f) {
return SetValue(f->Value());
}
return false;
}
void
FloatProperty::GetValue(BString& string)
{
append_float(string, fValue, 4);
}
bool
FloatProperty::InterpolateTo(const Property* other, float scale)
{
const FloatProperty* f = dynamic_cast<const FloatProperty*>(other);
if (f) {
return SetValue(fValue + (f->Value() - fValue) * scale);
}
return false;
}
bool
FloatProperty::SetValue(float value)
{
if (value < fMin)
value = fMin;
if (value > fMax)
value = fMax;
if (value != fValue) {
fValue = value;
return true;
}
return false;
}
UInt8Property::UInt8Property(uint32 identifier, uint8 value)
: Property(identifier),
fValue(value)
{
}
UInt8Property::UInt8Property(const UInt8Property& other)
: Property(other),
fValue(other.fValue)
{
}
UInt8Property::UInt8Property(BMessage* archive)
: Property(archive),
fValue(0)
{
if (!archive)
return;
if (archive->FindInt8("value", (int8*)&fValue) < B_OK)
fValue = 0;
}
UInt8Property::~UInt8Property()
{
}
status_t
UInt8Property::Archive(BMessage* into, bool deep) const
{
status_t ret = Property::Archive(into, deep);
if (ret >= B_OK)
ret = into->AddInt8("value", fValue);
if (ret >= B_OK)
ret = into->AddString("class", "UInt8Property");
return ret;
}
BArchivable*
UInt8Property::Instantiate(BMessage* archive)
{
if (validate_instantiation(archive, "UInt8Property"))
return new UInt8Property(archive);
return NULL;
}
Property*
UInt8Property::Clone() const
{
return new UInt8Property(*this);
}
bool
UInt8Property::SetValue(const char* value)
{
return SetValue((uint8)max_c(0, min_c(255, atoi(value))));
}
bool
UInt8Property::SetValue(const Property* other)
{
const UInt8Property* u = dynamic_cast<const UInt8Property*>(other);
if (u) {
return SetValue(u->Value());
}
return false;
}
void
UInt8Property::GetValue(BString& string)
{
string << fValue;
}
bool
UInt8Property::InterpolateTo(const Property* other, float scale)
{
const UInt8Property* u = dynamic_cast<const UInt8Property*>(other);
if (u) {
return SetValue(fValue + (uint8)((float)(u->Value()
- fValue) * scale + 0.5));
}
return false;
}
bool
UInt8Property::SetValue(uint8 value)
{
if (value != fValue) {
fValue = value;
return true;
}
return false;
}
BoolProperty::BoolProperty(uint32 identifier, bool value)
: Property(identifier),
fValue(value)
{
}
BoolProperty::BoolProperty(const BoolProperty& other)
: Property(other),
fValue(other.fValue)
{
}
BoolProperty::BoolProperty(BMessage* archive)
: Property(archive),
fValue(false)
{
if (!archive)
return;
if (archive->FindBool("value", &fValue) < B_OK)
fValue = false;
}
BoolProperty::~BoolProperty()
{
}
status_t
BoolProperty::Archive(BMessage* into, bool deep) const
{
status_t ret = Property::Archive(into, deep);
if (ret >= B_OK)
ret = into->AddBool("value", fValue);
if (ret >= B_OK)
ret = into->AddString("class", "BoolProperty");
return ret;
}
BArchivable*
BoolProperty::Instantiate(BMessage* archive)
{
if (validate_instantiation(archive, "BoolProperty"))
return new BoolProperty(archive);
return NULL;
}
Property*
BoolProperty::Clone() const
{
return new BoolProperty(*this);
}
bool
BoolProperty::SetValue(const char* value)
{
bool v;
if (strcasecmp(value, "true") == 0)
v = true;
else if (strcasecmp(value, "on") == 0)
v = true;
else
v = (bool)atoi(value);
return SetValue(v);
}
bool
BoolProperty::SetValue(const Property* other)
{
const BoolProperty* b = dynamic_cast<const BoolProperty*>(other);
if (b) {
return SetValue(b->Value());
}
return false;
}
void
BoolProperty::GetValue(BString& string)
{
if (fValue)
string << "on";
else
string << "off";
}
bool
BoolProperty::InterpolateTo(const Property* other, float scale)
{
const BoolProperty* b = dynamic_cast<const BoolProperty*>(other);
if (b) {
if (scale >= 0.5)
return SetValue(b->Value());
}
return false;
}
bool
BoolProperty::SetValue(bool value)
{
if (value != fValue) {
fValue = value;
return true;
}
return false;
}
StringProperty::StringProperty(uint32 identifier, const char* value)
: Property(identifier),
fValue(value)
{
}
StringProperty::StringProperty(const StringProperty& other)
: Property(other),
fValue(other.fValue)
{
}
StringProperty::StringProperty(BMessage* archive)
: Property(archive),
fValue()
{
if (!archive)
return;
if (archive->FindString("value", &fValue) < B_OK)
fValue = "";
}
StringProperty::~StringProperty()
{
}
status_t
StringProperty::Archive(BMessage* into, bool deep) const
{
status_t ret = Property::Archive(into, deep);
if (ret >= B_OK)
ret = into->AddString("value", fValue);
if (ret >= B_OK)
ret = into->AddString("class", "StringProperty");
return ret;
}
BArchivable*
StringProperty::Instantiate(BMessage* archive)
{
if (validate_instantiation(archive, "StringProperty"))
return new StringProperty(archive);
return NULL;
}
Property*
StringProperty::Clone() const
{
return new StringProperty(*this);
}
bool
StringProperty::SetValue(const char* value)
{
BString t(value);
if (fValue != t) {
fValue = t;
return true;
}
return false;
}
bool
StringProperty::SetValue(const Property* other)
{
const StringProperty* s = dynamic_cast<const StringProperty*>(other);
if (s) {
return SetValue(s->Value());
}
return false;
}
void
StringProperty::GetValue(BString& string)
{
string << fValue;
}