Created
November 13, 2008 23:19
-
-
Save kirel/24683 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* CONDITIONS AND ACTIONS | |
*/ | |
// gimme some Properties | |
FloatProp foo(); | |
GroupProp group(); | |
// now certain conditions regarding properties can trigger actions but see yourself | |
group.conditioned_by( foo.valueEqual(7.3).Do(SetVisibleAction()).Else(SetInvisibleAction()) ); | |
// or more succinct | |
group.conditioned_by( foo.valueEqual(7.3, SetVisibleAction(), SetInvisibleAction()) ); | |
// another fava (there is more than one way to do it!) | |
foo.valueEqual(7.3) | |
.Do(SetVisibleAction()) | |
.Else(SetInvisibleAction()) | |
.targeting(group); | |
// example for sets | |
float myfloats[]= {1.1,1.2,1.3,1.4}; | |
std::set<float> myset(myfloats,myfloats+5); | |
group.conditioned_by( foo.valueIn(myset).Do(IncredibleAction()) ); | |
// on any change recompile Shaders | |
foo.onChange().Do(RecompileShaderAction()); | |
// equivalent | |
foo.onChange(RecompileShaderAction()); | |
// Actions are chainable | |
foo.onChange() | |
.Do(ThisAction()) | |
.Do(ThatAction()) | |
.Do(ThirdAction()) | |
.Else(AnotherAction()) | |
.Else(SomeAction()); | |
// manual version which you are not encouraged to use | |
foo.addCondition(EqualCondition(&enu, &foo, 7.3, SetVisibleAction(), SetInvisibleAction)); | |
// this is crazy shit | |
class HuntingSeasonProp : public BoolProp {}; | |
HuntingSeasonProp huntallowed(); | |
Rabbit cutelittlerabbit(); | |
Rabbit sweetwhiterabbit(); | |
huntallowed.valueEqual(true).Do(ShootRabbitAction().targeting(cutelittlerabbit)); | |
huntallowed.valueEqual(true, ShootRabbitAction(sweetwhiterabbit)); | |
DateProp date(); | |
StringProp st(); | |
date.valueEqual(24,12,2008) | |
.Do(SetAction("Merry christmas!")) | |
.targeting(st); | |
date.set(24,12,2008); | |
st.get() // => "Merry christmas!" | |
/* | |
* VALIDATIONS | |
*/ | |
// validations make sure a (Template)Property is only set when certain conditions are met | |
std::vector<Date> holidays = ... | |
date.verifies(date.valueIn(holidays)); | |
date.set(24,12,2008); // => true | |
date.get() // => 24.12.2008 | |
date.set(12,12,2008) // => false | |
date.get() // => 24.12.2008 | |
//Note: Validations do not trigger any actions |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************************************************** | |
* * | |
* Voreen - The Volume Rendering Engine * | |
* * | |
* Copyright (C) 2005-2008 Visualization and Computer Graphics Group, * | |
* Department of Computer Science, University of Muenster, Germany. * | |
* <http://viscg.uni-muenster.de> * | |
* * | |
* This file is part of the Voreen software package. Voreen is free * | |
* software: you can redistribute it and/or modify it under the terms * | |
* of the GNU General Public License version 2 as published by the * | |
* Free Software Foundation. * | |
* * | |
* Voreen 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 * | |
* in the file "LICENSE.txt" along with this program. * | |
* If not, see <http://www.gnu.org/licenses/>. * | |
* * | |
* The authors reserve all rights not expressly granted herein. For * | |
* non-commercial academic use see the license exception specified in * | |
* the file "LICENSE-academic.txt". To get information about * | |
* commercial licensing please contact the authors. * | |
* * | |
**********************************************************************/ | |
#include "voreen/core/vis/property.h" | |
namespace voreen { | |
Property::Property() : Serializable(), owner_(0) { | |
guiText_ = "empty"; | |
} | |
Property::~Property() {}; | |
std::string Property::getGuiText() const { | |
return guiText_; | |
} | |
const std::string Property::XmlElementName = "Property"; | |
std::string Property::getXmlElementName() const { | |
return XmlElementName; | |
} | |
TiXmlElement* Property::serializeToXml() const { | |
serializableSanityChecks(); | |
TiXmlElement* propElem = new TiXmlElement(XmlElementName); | |
// FIXME: Why do we not serialize the guiText_? (tr) | |
//propElem->SetAttribute("Property_text" , getGuiText()); | |
// TODO: use type_info instead of own type defines | |
//propElem->SetAttribute("type", PropertyType()); | |
//propElem->SetAttribute("autochange", getAutoChange() ? "true" : "false"); | |
return propElem; | |
} | |
void Property::setOwner(Processor* owner) { | |
owner_ = owner; | |
} | |
Processor* Property::getOwner() const { | |
return owner_; | |
} | |
//----------------------------------------------------------------------------------------------- | |
FloatProperty::FloatProperty(std::string guiText, float value, float minValue, float maxValue) | |
: NumericProperty<float>(value, minValue, maxValue) | |
, decimals_(2) | |
{ | |
guiText_ = guiText; | |
minValue_ = minValue; | |
maxValue_ = maxValue; | |
} | |
void FloatProperty::setDecimals(int decimals) { | |
decimals_ = decimals; | |
} | |
int FloatProperty::getDecimals() const { | |
return decimals_; | |
} | |
void FloatProperty::updateFromXml(TiXmlElement* propElem) { | |
Property::updateFromXml(propElem); | |
float value; | |
if (propElem->QueryFloatAttribute("value", &value) == TIXML_SUCCESS) | |
set(value); | |
else | |
errors_.store(XmlAttributeException("Attribute 'value' missing in Property element!")); | |
} | |
TiXmlElement* FloatProperty::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
propElem->SetDoubleAttribute("value", get()); | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
IntProperty::IntProperty(std::string guiText, int value, int minValue, int maxValue) | |
: NumericProperty<int>(value, minValue, maxValue) { | |
guiText_ = guiText; | |
minValue_ = minValue; | |
maxValue_ = maxValue; | |
} | |
void IntProperty::updateFromXml(TiXmlElement* propElem) { | |
Property::updateFromXml(propElem); | |
int value; | |
if (propElem->QueryIntAttribute("value", &value) == TIXML_SUCCESS) | |
set(value); | |
else | |
errors_.store(XmlAttributeException("Attribute 'value' missing in Property element!")); | |
} | |
TiXmlElement* IntProperty::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
propElem->SetAttribute("value", get()); | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
BoolProperty::BoolProperty(std::string guiText, bool value) : TemplateProperty<bool>(value) { | |
guiText_ = guiText; | |
} | |
void BoolProperty::updateFromXml(TiXmlElement* propElem) { | |
Property::updateFromXml(propElem); | |
if (propElem->Attribute("value")) | |
set(std::string("true").compare(propElem->Attribute("value")) == 0 ? true : false); | |
else | |
errors_.store(XmlAttributeException("Attribute 'value' missing in Property element!")); | |
} | |
TiXmlElement* BoolProperty::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
propElem->SetAttribute("value", get() ? "true" : "false"); | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
StringProperty::StringProperty(std::string guiText, std::string value) : TemplateProperty<std::string>(value) { | |
guiText_ = guiText; | |
} | |
void StringProperty::updateFromXml(TiXmlElement* propElem) { | |
Property::updateFromXml(propElem); | |
if (propElem->Attribute("value")) | |
set(propElem->Attribute("value")); | |
else | |
errors_.store(XmlAttributeException("Attribute 'value' missing in Property element!")); | |
} | |
TiXmlElement* StringProperty::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
propElem->SetAttribute("value", get()); | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
StringVectorProperty::StringVectorProperty(std::string guiText, std::vector<std::string> value) : TemplateProperty<std::vector<std::string> >(value) { | |
guiText_ = guiText; | |
} | |
//FIXME: needs serialization methods (tr) | |
//----------------------------------------------------------------------------------------------- | |
ColorProperty::ColorProperty(std::string guiText, tgt::Color value) : TemplateProperty<tgt::vec4>(value) { | |
guiText_ = guiText; | |
} | |
void ColorProperty::updateFromXml(TiXmlElement* propElem) { | |
Property::updateFromXml(propElem); | |
float r, g, b, a; | |
if (propElem->QueryFloatAttribute("r", &r) == TIXML_SUCCESS && | |
propElem->QueryFloatAttribute("g", &g) == TIXML_SUCCESS && | |
propElem->QueryFloatAttribute("b", &b) == TIXML_SUCCESS && | |
propElem->QueryFloatAttribute("a", &a) == TIXML_SUCCESS) | |
set(tgt::Color(r,g,b,a)); | |
else | |
errors_.store(XmlAttributeException("Attribute 'value' missing in Property element!")); | |
} | |
TiXmlElement* ColorProperty::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
propElem->SetDoubleAttribute("r", get().r); | |
propElem->SetDoubleAttribute("g", get().g); | |
propElem->SetDoubleAttribute("b", get().b); | |
propElem->SetDoubleAttribute("a", get().a); | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
EnumProperty::EnumProperty(std::string guiText, std::vector<std::string>& strings, int startindex) : TemplateProperty<int>(startindex) { | |
guiText_ = guiText; | |
strings_ = strings; | |
} | |
std::vector<std::string> EnumProperty::getStrings() { | |
return strings_; | |
} | |
void EnumProperty::setStrings(const std::vector<std::string>& strings) { | |
strings_ = strings; | |
} | |
void EnumProperty::updateFromXml(TiXmlElement* propElem) { | |
Property::updateFromXml(propElem); | |
if (propElem->Attribute("value")) { | |
for (size_t j = 0; j < strings_.size(); j++) { | |
if (strings_.at(j).compare(propElem->Attribute("value")) == 0) { | |
set(j); // The compiler might complain about size_t to int conversion | |
break; | |
} | |
} | |
} | |
else | |
errors_.store(XmlAttributeException("Attribute 'value' missing in Property element!")); | |
} | |
TiXmlElement* EnumProperty::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
propElem->SetAttribute("value", strings_.at(get())); | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
ButtonProperty::ButtonProperty(std::string guiText, std::string buttonText, | |
std::string iconFilename) | |
: TemplateProperty<bool>() | |
{ | |
guiText_ = guiText; | |
} | |
std::string ButtonProperty::getButtonText() { | |
return buttonText_; | |
} | |
std::string ButtonProperty::getIconFilename() { | |
return iconFilename_; | |
} | |
//FIXME: Do we not need an updateFromXML method? (tr) | |
TiXmlElement* ButtonProperty::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
FileDialogProperty::FileDialogProperty(std::string guiText, | |
std::string caption, std::string directory, | |
std::string filter) | |
: TemplateProperty<std::string>() | |
, caption_(caption) | |
, directory_(directory) | |
, filter_(filter) | |
{ | |
guiText_ = guiText; | |
} | |
std::string FileDialogProperty::getCaption() const { | |
return caption_; | |
} | |
std::string FileDialogProperty::getDirectory() const { | |
return directory_; | |
} | |
std::string FileDialogProperty::getFilter() const { | |
return filter_; | |
} | |
//FIXME: Do we not need an updateFromXML method? (tr) | |
TiXmlElement* FileDialogProperty::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
propElem->SetAttribute("value", get()); | |
propElem->SetAttribute("caption", getDialogCaption()); | |
propElem->SetAttribute("directory", getDirectory()); | |
propElem->SetAttribute("filefilter", getFileFilter()); | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
TransFuncAlphaProperty::TransFuncAlphaProperty(std::string guiText, TransFunc tf, const std::string& yAxisLabel) | |
: TemplateProperty<TransFunc>(tf) | |
, yAxisLabel_(yAxisLabel) | |
{ | |
guiText_ = guiText; | |
} | |
//----------------------------------------------------------------------------------------------- | |
TransFuncProperty::TransFuncProperty(std::string guiText, TransFunc tf, bool showThreshold) | |
: TemplateProperty<TransFunc>(tf) | |
, showThreshold_(showThreshold) { | |
guiText_ = guiText; | |
} | |
bool TransFuncProperty::getShowThreshold() { | |
return showThreshold_; | |
} | |
void TransFuncProperty::updateFromXml(TiXmlElement* propElem) { | |
Property::updateFromXml(propElem); | |
TransFuncIntensityKeys* tf = new TransFuncIntensityKeys(); | |
tf->clearKeys(); | |
//iterate through all markers | |
TiXmlElement* markerElem; | |
for (markerElem = propElem->FirstChildElement("Marker"); | |
markerElem; | |
markerElem = markerElem->NextSiblingElement("Marker")) | |
{ | |
//first get the color | |
float value, dest; | |
tgt::col4 color; | |
tgt::ivec4 tmp; | |
if (markerElem->QueryFloatAttribute("source", &value) == TIXML_SUCCESS && | |
markerElem->QueryFloatAttribute("dest", &dest) == TIXML_SUCCESS && | |
markerElem->QueryIntAttribute("r", &tmp.r) == TIXML_SUCCESS && | |
markerElem->QueryIntAttribute("g", &tmp.g) == TIXML_SUCCESS && | |
markerElem->QueryIntAttribute("b", &tmp.b) == TIXML_SUCCESS && | |
markerElem->QueryIntAttribute("a", &tmp.a) == TIXML_SUCCESS) | |
{ | |
color.r = (uint8_t)tmp.r; | |
color.g = (uint8_t)tmp.g; | |
color.b = (uint8_t)tmp.b; | |
color.a = (uint8_t)tmp.a; | |
TransFuncMappingKey* myKey = new TransFuncMappingKey(value, color); | |
myKey->setAlphaL(dest); | |
if (markerElem->QueryFloatAttribute("splitdest", &dest) == TIXML_SUCCESS && | |
markerElem->QueryIntAttribute("splitr", &tmp.r) == TIXML_SUCCESS && | |
markerElem->QueryIntAttribute("splitg", &tmp.g) == TIXML_SUCCESS && | |
markerElem->QueryIntAttribute("splitb", &tmp.b) == TIXML_SUCCESS && | |
markerElem->QueryIntAttribute("splita", &tmp.a) == TIXML_SUCCESS) | |
{ | |
myKey->setSplit(true); | |
color.r = (uint8_t)tmp.r; | |
color.g = (uint8_t)tmp.g; | |
color.b = (uint8_t)tmp.b; | |
color.a = (uint8_t)tmp.a; | |
myKey->setColorR(color); | |
myKey->setAlphaR(dest); | |
} else { | |
myKey->setSplit(false); | |
} | |
tf->addKey(myKey); | |
} | |
else | |
errors_.store(XmlElementException("A Key in a TransFunc is messed up")); | |
} // for ( pElem; pElem; pElem=pElem->NextSiblingElement()) | |
tf->updateTexture(); | |
set(&tf); | |
} | |
TiXmlElement* TransFuncProperty::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
TransFuncIntensityKeys* tf = dynamic_cast<TransFuncIntensityKeys*>(&get()); | |
if (tf) { | |
// iterate through all markers | |
for (int m = 0; m < tf->getNumKeys(); ++m) { | |
// prepare xml | |
TiXmlElement *xmlMarker = new TiXmlElement("Marker"); | |
//save markers to xml | |
xmlMarker->SetDoubleAttribute("source", tf->getKey(m)->getIntensity()); | |
xmlMarker->SetDoubleAttribute("dest", tf->getKey(m)->getAlphaL()); | |
xmlMarker->SetAttribute("r", tf->getKey(m)->getColorL().r); | |
xmlMarker->SetAttribute("g", tf->getKey(m)->getColorL().g); | |
xmlMarker->SetAttribute("b", tf->getKey(m)->getColorL().b); | |
xmlMarker->SetAttribute("a", tf->getKey(m)->getColorL().a); | |
if (tf->getKey(m)->isSplit()) { | |
xmlMarker->SetDoubleAttribute("splitdest", tf->getKey(m)->getAlphaR()); | |
xmlMarker->SetAttribute("splitr", tf->getKey(m)->getColorR().r); | |
xmlMarker->SetAttribute("splitg", tf->getKey(m)->getColorR().g); | |
xmlMarker->SetAttribute("splitb", tf->getKey(m)->getColorR().b); | |
xmlMarker->SetAttribute("splita", tf->getKey(m)->getColorR().a); | |
} | |
propElem->LinkEndChild(xmlMarker); | |
} // for (size_t m=0; m<transfer->getNumKeys(); ++m) | |
} | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
FloatVec2Property::FloatVec2Property(std::string guiText, tgt::vec2 value, | |
tgt::vec2 minValue, tgt::vec2 maxValue) | |
: NumericProperty<tgt::vec2>(value, minValue, maxValue) { | |
guiText_ = guiText; | |
minValue_ = minValue; | |
maxValue_ = maxValue; | |
} | |
void FloatVec2Property::updateFromXml(TiXmlElement* propElem) { | |
Property::updateFromXml(propElem); | |
tgt::vec2 vector; | |
if (propElem->QueryFloatAttribute("x", &vector.x) == TIXML_SUCCESS && | |
propElem->QueryFloatAttribute("y", &vector.y) == TIXML_SUCCESS) { | |
set(vector); | |
} | |
else | |
errors_.store(XmlAttributeException("Attribute 'value' missing in Property element!")); | |
} | |
TiXmlElement* FloatVec2Property::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
propElem->SetDoubleAttribute("x", get().x); | |
propElem->SetDoubleAttribute("y", get().y); | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
FloatVec3Property::FloatVec3Property(std::string guiText, tgt::vec3 value, | |
tgt::vec3 minValue, tgt::vec3 maxValue) | |
: NumericProperty<tgt::vec3>(value, minValue, maxValue) { | |
guiText_ = guiText; | |
minValue_ = minValue; | |
maxValue_ = maxValue; | |
} | |
void FloatVec3Property::updateFromXml(TiXmlElement* propElem) { | |
Property::updateFromXml(propElem); | |
tgt::vec3 vector; | |
if (propElem->QueryFloatAttribute("x", &vector.x) == TIXML_SUCCESS && | |
propElem->QueryFloatAttribute("y", &vector.y) == TIXML_SUCCESS && | |
propElem->QueryFloatAttribute("z", &vector.z) == TIXML_SUCCESS) { | |
set(vector); | |
} | |
else | |
errors_.store(XmlAttributeException("Attribute 'value' missing in Property element!")); | |
} | |
TiXmlElement* FloatVec3Property::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
propElem->SetDoubleAttribute("x", get().x); | |
propElem->SetDoubleAttribute("y", get().y); | |
propElem->SetDoubleAttribute("z", get().z); | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
FloatVec4Property::FloatVec4Property(std::string guiText, tgt::vec4 value, | |
tgt::vec4 minValue, tgt::vec4 maxValue) | |
: NumericProperty<tgt::vec4>(value, minValue, maxValue) { | |
guiText_ = guiText; | |
minValue_ = minValue; | |
maxValue_ = maxValue; | |
} | |
void FloatVec4Property::updateFromXml(TiXmlElement* propElem) { | |
Property::updateFromXml(propElem); | |
tgt::vec4 vector; | |
if (propElem->QueryFloatAttribute("x", &vector.x) == TIXML_SUCCESS && | |
propElem->QueryFloatAttribute("y", &vector.y) == TIXML_SUCCESS && | |
propElem->QueryFloatAttribute("z", &vector.z) == TIXML_SUCCESS && | |
propElem->QueryFloatAttribute("z", &vector.w) == TIXML_SUCCESS) { | |
set(vector); | |
} | |
else | |
errors_.store(XmlAttributeException("Attribute 'value' missing in Property element!")); | |
} | |
TiXmlElement* FloatVec4Property::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
propElem->SetDoubleAttribute("x", get().x); | |
propElem->SetDoubleAttribute("y", get().y); | |
propElem->SetDoubleAttribute("z", get().z); | |
propElem->SetDoubleAttribute("w", get().w); | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
IntVec2Property::IntVec2Property(std::string guiText, tgt::ivec2 value, | |
tgt::ivec2 minValue, tgt::ivec2 maxValue) | |
: NumericProperty<tgt::ivec2>(value, minValue, maxValue) { | |
guiText_ = guiText; | |
minValue_ = minValue; | |
maxValue_ = maxValue; | |
} | |
void IntVec2Property::updateFromXml(TiXmlElement* propElem) { | |
Property::updateFromXml(propElem); | |
tgt::ivec2 vector; | |
if (propElem->QueryIntAttribute("x", &vector.x) == TIXML_SUCCESS && | |
propElem->QueryIntAttribute("y", &vector.y) == TIXML_SUCCESS) { | |
set(vector); | |
} | |
else | |
errors_.store(XmlAttributeException("Attribute 'value' missing in Property element!")); | |
} | |
TiXmlElement* IntVec2Property::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
propElem->SetAttribute("x", get().x); | |
propElem->SetAttribute("y", get().y); | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
IntVec3Property::IntVec3Property(std::string guiText, tgt::ivec3 value, | |
tgt::ivec3 minValue, tgt::ivec3 maxValue) | |
: NumericProperty<tgt::ivec3>(value, minValue, maxValue) { | |
guiText_ = guiText; | |
minValue_ = minValue; | |
maxValue_ = maxValue; | |
} | |
void IntVec3Property::updateFromXml(TiXmlElement* propElem) { | |
Property::updateFromXml(propElem); | |
tgt::ivec3 vector; | |
if (propElem->QueryIntAttribute("x", &vector.x) == TIXML_SUCCESS && | |
propElem->QueryIntAttribute("y", &vector.y) == TIXML_SUCCESS && | |
propElem->QueryIntAttribute("z", &vector.z) == TIXML_SUCCESS) { | |
set(vector); | |
} | |
else | |
errors_.store(XmlAttributeException("Attribute 'value' missing in Property element!")); | |
} | |
TiXmlElement* IntVec3Property::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
propElem->SetAttribute("x", get().x); | |
propElem->SetAttribute("y", get().y); | |
propElem->SetAttribute("z", get().z); | |
return propElem; | |
} | |
//----------------------------------------------------------------------------------------------- | |
IntVec4Property::IntVec4Property(std::string guiText, tgt::ivec4 value, | |
tgt::ivec4 minValue, tgt::ivec4 maxValue) | |
: NumericProperty<tgt::ivec4>(value, minValue, maxValue) { | |
guiText_ = guiText; | |
minValue_ = minValue; | |
maxValue_ = maxValue; | |
} | |
void IntVec4Property::updateFromXml(TiXmlElement* propElem) { | |
Property::updateFromXml(propElem); | |
tgt::ivec4 vector; | |
if (propElem->QueryIntAttribute("x", &vector.x) == TIXML_SUCCESS && | |
propElem->QueryIntAttribute("y", &vector.y) == TIXML_SUCCESS && | |
propElem->QueryIntAttribute("z", &vector.z) == TIXML_SUCCESS && | |
propElem->QueryIntAttribute("z", &vector.w) == TIXML_SUCCESS) { | |
set(vector); | |
} | |
else | |
errors_.store(XmlAttributeException("Attribute 'value' missing in Property element!")); | |
} | |
TiXmlElement* IntVec4Property::serializeToXml() const { | |
TiXmlElement* propElem = Property::serializeToXml(); | |
propElem->SetAttribute("x", get().x); | |
propElem->SetAttribute("y", get().y); | |
propElem->SetAttribute("z", get().z); | |
propElem->SetAttribute("w", get().w); | |
return propElem; | |
} | |
} //namespace Voreen |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************************************************** | |
* * | |
* Voreen - The Volume Rendering Engine * | |
* * | |
* Copyright (C) 2005-2008 Visualization and Computer Graphics Group, * | |
* Department of Computer Science, University of Muenster, Germany. * | |
* <http://viscg.uni-muenster.de> * | |
* * | |
* This file is part of the Voreen software package. Voreen is free * | |
* software: you can redistribute it and/or modify it under the terms * | |
* of the GNU General Public License version 2 as published by the * | |
* Free Software Foundation. * | |
* * | |
* Voreen 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 * | |
* in the file "LICENSE.txt" along with this program. * | |
* If not, see <http://www.gnu.org/licenses/>. * | |
* * | |
* The authors reserve all rights not expressly granted herein. For * | |
* non-commercial academic use see the license exception specified in * | |
* the file "LICENSE-academic.txt". To get information about * | |
* commercial licensing please contact the authors. * | |
* * | |
**********************************************************************/ | |
#ifndef VRN_PROPERTY_H | |
#define VRN_PROPERTY_H | |
#include "voreen/core/xml/serializable.h" | |
#include "voreen/core/vis/transfunc/transfunc.h" | |
namespace voreen { | |
class Processor; | |
class Property : public Serializable { | |
public: | |
Property(); | |
virtual ~Property(); | |
std::string getGuiText() const; | |
void setOwner(Processor* processor); | |
Processor* getOwner() const; | |
protected: | |
std::string guiText_; | |
Processor* owner_; | |
}; | |
typedef std::vector<Property*> Properties; | |
//----------------------------------------------------------------------------------------------- | |
template<class T> | |
class PropertyWidget { | |
public: | |
virtual ~PropertyWidget() {} | |
inline virtual void updateValue(T value); | |
protected: | |
Property* myProperty_; | |
}; | |
template<class T> | |
void PropertyWidget<T>::updateValue(T /*value*/) {}; | |
//----------------------------------------------------------------------------------------------- | |
template<class T> | |
class TemplateProperty : public Property { | |
public: | |
TemplateProperty(); | |
TemplateProperty(const T& value); // third constructor version with needRecompileShader needed? | |
inline void set(const T& value); | |
T get() const; | |
protected: | |
T value_; | |
PropertyWidget<T>* myWidget_; | |
}; | |
template<class T> | |
TemplateProperty<T>::TemplateProperty() | |
: myWidget_(0) | |
{ | |
} | |
template<class T> | |
TemplateProperty<T>::TemplateProperty(const T& value) | |
: myWidget_(0) | |
, value_(value) | |
{ | |
} | |
template<class T> | |
void TemplateProperty<T>::set(const T& value) { | |
//if (value_ != value) { | |
value_ = value; | |
if (myWidget_) | |
myWidget_->updateValue(); | |
//} | |
} | |
template<class T> | |
T TemplateProperty<T>::get() const { | |
return value_; | |
} | |
//----------------------------------------------------------------------------------------------- | |
template<class T> | |
class NumericProperty : public TemplateProperty<T> { | |
public: | |
NumericProperty(); | |
NumericProperty(const T& value, const T& minValue, const T& maxValue); | |
T getMinValue() const; | |
void setMinValue(const T& minValue); | |
T getMaxValue() const; | |
void setMaxValue(const T& maxValue); | |
protected: | |
T minValue_; | |
T maxValue_; | |
}; | |
template<class T> | |
NumericProperty<T>::NumericProperty() { | |
} | |
template<class T> | |
NumericProperty<T>::NumericProperty(const T& value, const T& minValue, const T& maxValue) | |
: TemplateProperty<T>(value) | |
, minValue_(minValue) | |
, maxValue_(maxValue) { | |
} | |
template<class T> | |
T NumericProperty<T>::getMinValue() const { | |
return minValue_; | |
} | |
template<class T> | |
void NumericProperty<T>::setMinValue(const T& minValue) { | |
minValue_ = minValue; | |
} | |
template<class T> | |
T NumericProperty<T>::getMaxValue() const { | |
return maxValue_; | |
} | |
template<class T> | |
void NumericProperty<T>::setMaxValue(const T& maxValue) { | |
maxValue_ = maxValue; | |
} | |
//----------------------------------------------------------------------------------------------- | |
class FloatProperty : public NumericProperty<float> { | |
public: | |
FloatProperty(std::string guiText, float value=0.f, float minValue=0.f, float maxValue=1.f); | |
void setDecimals(int decimals); | |
int getDecimals() const; | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
protected: | |
int decimals_; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class IntProperty : public NumericProperty<int> { | |
public: | |
IntProperty(std::string guiText, int value=0, int minValue=0, int maxValue=100); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class BoolProperty : public TemplateProperty<bool> { | |
public: | |
BoolProperty(std::string guiText, bool value=false); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class StringProperty : public TemplateProperty<std::string> { | |
public: | |
StringProperty(std::string guiText, std::string value = ""); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class StringVectorProperty : public TemplateProperty<std::vector<std::string> > { | |
public: | |
StringVectorProperty(std::string guiText, std::vector<std::string> value); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class ColorProperty : public TemplateProperty<tgt::vec4> { | |
public: | |
ColorProperty(std::string guiText, tgt::Color value=tgt::Color(0.0)); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class EnumProperty : public TemplateProperty<int> { | |
public: | |
EnumProperty(std::string guiText, std::vector<std::string>& strings, int startIndex=0); | |
std::vector<std::string> getStrings(); | |
void setStrings(const std::vector<std::string>& strings); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
protected: | |
std::vector<std::string> strings_; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class ButtonProperty : public TemplateProperty<bool> { | |
public: | |
ButtonProperty(std::string guiText, std::string buttonText, std::string iconFilename=""); | |
std::string getButtonText(); | |
std::string getIconFilename(); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
protected: | |
std::string buttonText_; | |
std::string iconFilename_; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class FileDialogProperty : public TemplateProperty<std::string> { | |
public: | |
FileDialogProperty(std::string guiText, std::string caption, std::string directory, std::string filter); | |
std::string getCaption() const; | |
std::string getDirectory() const; | |
std::string getFilter() const; | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
protected: | |
std::string caption_; | |
std::string directory_; | |
std::string filter_; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class TransFuncAlphaProperty : public TemplateProperty<TransFunc> { | |
public: | |
TransFuncAlphaProperty(std::string guiText, TransFunc tf, const std::string& yAxisLabel="intensity"); | |
std::string getYAxisText() { return yAxisLabel_; }; | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
protected: | |
std::string yAxisLabel_; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class TransFuncProperty : public TemplateProperty<TransFunc> { | |
public: | |
TransFuncProperty(std::string guiText, TransFunc tf, bool showThreshold=true); | |
bool getShowThreshold(); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
protected: | |
bool showThreshold_; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class FloatVec2Property : public NumericProperty<tgt::vec2> { | |
public: | |
FloatVec2Property(std::string guiText, tgt::vec2 value, tgt::vec2 minValue=tgt::vec2(0.0f), tgt::vec2 maxValue=tgt::vec2(1.0f)); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class FloatVec3Property : public NumericProperty<tgt::vec3> { | |
public: | |
FloatVec3Property(std::string guiText, tgt::vec3 value, tgt::vec3 minValue=tgt::vec3(0.0f), tgt::vec3 maxValue=tgt::vec3(1.0f)); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class FloatVec4Property : public NumericProperty<tgt::vec4> { | |
public: | |
FloatVec4Property(std::string guiText, tgt::vec4 value, tgt::vec4 minValue=tgt::vec4(0.0f), tgt::vec4 maxValue=tgt::vec4(1.0f)); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class IntVec2Property : public NumericProperty<tgt::ivec2> { | |
public: | |
IntVec2Property(std::string guiText, tgt::ivec2 value, tgt::ivec2 minValue=tgt::ivec2(0), tgt::ivec2 maxValue=tgt::ivec2(100)); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class IntVec3Property : public NumericProperty<tgt::ivec3> { | |
public: | |
IntVec3Property(std::string guiText, tgt::ivec3 value, tgt::ivec3 minValue=tgt::ivec3(0), tgt::ivec3 maxValue=tgt::ivec3(100)); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
}; | |
//----------------------------------------------------------------------------------------------- | |
class IntVec4Property : public NumericProperty<tgt::ivec4> { | |
public: | |
IntVec4Property(std::string guiText, tgt::ivec4 value, tgt::ivec4 minValue=tgt::ivec4(0), tgt::ivec4 maxValue=tgt::ivec4(100)); | |
void updateFromXml(TiXmlElement* propElem); | |
TiXmlElement* serializeToXml() const; | |
}; | |
} // namespace voreen | |
#endif // VRN_PROPERTY_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// add methods to existing | |
template<class T> | |
class TemplateProperty<T> { | |
public: | |
// convenience methods | |
EqualCondition& valueEqual(const T& value, const ConditionalAction& action = NoAction(), const ConditionalAction& elseaction = NoAction()) { | |
return dynamic_cast<EqualCondition&>(addCondition(EqualCondition<T>(0, this, value, action, elseaction))); | |
} | |
LessCondition& valueLess(const T& value, const ConditionalAction& action = NoAction(), const ConditionalAction& elseaction = NoAction()) { | |
return dynamic_cast<LessCondition&>(addCondition(LessCondition<T>(0, this, value, action, elseaction))); | |
} | |
InCondition& valueIn(const std::set<T>& values, const ConditionalAction& action = NoAction(), const ConditionalAction& elseaction = NoAction()) { | |
return dynamic_cast<InCondition&>(addCondition(InCondition<T>(0, this, values, action, elseaction))); | |
} | |
TrueCondition& onChange(const &ConditionalAction action = NoAction()) { | |
return dynamic_cast<TrueCondition&>(addCondition(TrueCondition(0, action))); | |
} | |
// etc | |
PropertyCondition& addCondition(const PropertyCondition& condition) { | |
conditions_.push_back(condition); | |
return *conditions_.back(); | |
} | |
// this replaces the old method | |
void set(const T& value) { | |
value_ = value; | |
if (myWidget_) | |
myWidget_->updateValue(); | |
// check if conditions met and fire actions | |
for(std::vector<PropertyCondition>::iterator cond = conditions_.begin(); cond != conditions_.end(); ++cond) { | |
cond->check(); | |
} | |
} | |
// TODO way to remove conditions (especially if conditioned Properties are gone) | |
private: | |
std::vector<PropertyCondition> conditions_; | |
// + existing methods | |
}; | |
// add methods to existing | |
class Property { | |
public: | |
Property& addCondition(PropertyCondition& condition) { | |
condition.setConditioned(this); | |
return *this; | |
} | |
Property& conditioned_by(PropertyCondition& condition) { return addCondition(condition); } | |
// + existing methods | |
// TODO Property needs to know its Conditions to remove them on destruction | |
}; | |
/** | |
* A PropertyCondition can check any Condition and trigger ConditionalActions | |
* if the condition is met. The foremost purpose is to monitor the state of | |
* a Property (the conditioner ?better: controller?) and react to its changes. | |
*/ | |
class PropertyCondition { | |
public: | |
PropertyCondition(Property* conditioned = 0, const ConditionalAction& action = NoAction(), const ConditionalAction& elseaction = NoAction() ) : conditioned_(conditioned), addAction(action), addElseAction(elseaction) {} | |
// TODO Destructor | |
PropertyCondition& setConditioned(Property& conditioned) { | |
conditioned_ = &conditioned; | |
return *this; | |
} | |
PropertyCondition& targeting(Property& conditioned) { setConditioned(conditioned); } | |
Property* getConditioned() const { | |
return conditioned_; | |
} | |
PropertyCondition& addAction(const ConditionalAction& action) { | |
action_.push_back(action); | |
action_.back()->setCondition(this); | |
return *this; | |
} | |
PropertyCondition& Do(const ConditionalAction& action) { return addAction(action); } | |
PropertyCondition& addElseAction(const ConditionalAction& action) { | |
elseaction_.push_back(action); | |
elseaction_.back()->setCondition(this); | |
return *this; | |
} | |
PropertyCondition& Else(ConditionalAction action) { return addElseAction(action); } | |
virtual bool met() = 0; // implement this | |
void check() { | |
if (conditioned_) { | |
if (met()) { | |
for (size_t i; i < action_.size(); ++i) | |
action_.at(i)->fire(); | |
} | |
else { | |
for (size_t i; i < elseaction_.size(); ++i) | |
elseaction_.at(i)->fire(); | |
} | |
} | |
} | |
private: | |
Property* conditioned_; | |
std::vector<ConditionalAction> action_; | |
std::vector<ConditionalAction> elseaction_; | |
}; | |
class TrueCondition : public PropertyCondition { | |
TrueCondition(Property* conditioned, const ConditionalAction& action = NoAction()) : PropertyCondition(conditioned, action) {} | |
bool met() { return true; } | |
}; | |
/* Can be accomplished by simply exchanging action and elseaction | |
class NotCondition {}; | |
*/ | |
class HasObamaWonCondition : public TrueCondition {}; | |
template<class T> | |
class TemplateCondition : public PropertyCondition { | |
public: | |
TemplateCondition(Property* conditioned, TemplateProperty<T>* conditioner, T value, const ConditionalAction& action = NoAction(), const ConditionalAction& elseaction = NoAction()) | |
: PropertyCondition(conditioned, action, elseaction), conditioner_(conditioner), value_(value) {} | |
bool met() = 0; | |
private: | |
TemplateProperty<T>* conditioner_; | |
T value_; | |
}; | |
template<class T> | |
class EqualCondition : public TemplateCondition<T> { | |
public: | |
bool met() { | |
if (!conditioner_) return false; | |
return (conditioner_->get() == value_); | |
} | |
}; | |
template<class T> | |
class LessCondition : public TemplateCondition<T> { | |
public: | |
bool met() { | |
if (!conditioner_) return false; | |
return (conditioner_->get() < value_); | |
} | |
}; | |
template<class T> | |
class SetCondition : public PropertyCondition { | |
public: | |
SetCondition(Property* conditioned, TemplateProperty<T>* conditioner, std::set<T> values, const ConditionalAction& action = NoAction(), const ConditionalAction& elseaction = NoAction()) | |
: PropertyCondition(conditioned, action, elseaction), conditioner_(conditioner), values_(values) {} | |
virtual bool met() = 0; | |
private: | |
TemplateProperty<T>* conditioner_; | |
std::set<T> values_; | |
}; | |
template<class T> | |
class InCondition : public SetCondition<T> { | |
bool met() { | |
return (values_.find(conditioner_->get()) != values_.end()); | |
} | |
} | |
// etc | |
/** | |
* A ConditionalAction can be set to fire when a PropertyCondition is met. | |
* The action can be anything but the foremost purpose is to change the state | |
* of the Property conditioned by the PropertyCondition the action belongs to. | |
*/ | |
class ConditionalAction { | |
public: | |
ConditionalAction(PropertyCondition* condition = 0) : condition_(condition) {} | |
void setCondition(PropertyCondition* condition) { condition_ = condition; } | |
virtual void fire() = 0; // implement | |
Property* conditioned() { | |
if (condition_) { | |
return condition_->getConditioned(); // might be NULL | |
} | |
return 0; | |
} | |
private: | |
PropertyCondition* condition_; | |
}; | |
struct NoAction : public ConditionalAction { | |
void fire() {} // do nothing | |
} | |
struct SetVisibleAction : public ConditionalAction { | |
void fire() { | |
conditioned()->setVisible(); | |
} | |
}; | |
struct SetInvisibleAction : public ConditionalAction { | |
void fire() { | |
conditioned()->setInvisible(); | |
} | |
}; | |
template<class T> | |
class SetAction : public ConditionalAction { | |
public: | |
SetAction(T value) : value_(value) {} | |
void fire() { | |
dynamic_cast< TemplateProperty<T>* >(conditioned())->set(value); // Nullcheck? | |
} | |
private: | |
T value_; | |
}; | |
struct RecompileShaderAction : public ConditionalAction { | |
void fire() { | |
// notify system that shaders have to be recompiled | |
} | |
} | |
struct CureCancerAction : public ConditionalAction { | |
void fire() { | |
// cure cancer | |
} | |
} | |
template<class T> | |
class TargetAction : ConditionalAction { | |
public: | |
TargetAction() : ConditionalAction(0), target_(0) {} | |
TargetAction(T& target) : ConditionalAction(0), target_(&target) {} | |
TargetAction& setTarget(T* target) { | |
target_ = target; | |
return *this; | |
} | |
TargetAction& targeting(T& target) { return setTarget(&target); } | |
T* target() { | |
return target_; | |
} | |
virtual void fire() = 0; | |
} | |
class ShootRabbitAction : TargetAction<Rabbit> { | |
void fire() { | |
shoot(target()); | |
} | |
void shoot(Rabbit* rabbit) { | |
// pewpew - lazergunz! | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Let ConditionalActions have their own target |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment