MuseScore/libmscore/property.h

236 lines
8.9 KiB
C
Raw Normal View History

2012-05-26 14:26:10 +02:00
//=============================================================================
// MuseScore
// Music Composition & Notation
// $Id:$
//
// Copyright (C) 2011 Werner Schweer
//
// This program 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 and appearing in
// the file LICENCE.GPL
//=============================================================================
#ifndef __PROPERTY_H__
#define __PROPERTY_H__
//------------------------------------------------------------------------
// Element Properties
// accessible through
// virtual QVariant Element::getProperty(int propertyId)
// virtual void Element::setProperty(int propertyId, const QVariant&)
//------------------------------------------------------------------------
enum P_ID {
P_SUBTYPE,
P_SELECTED,
P_COLOR,
P_VISIBLE,
P_SMALL,
P_SHOW_COURTESY,
P_LINE_TYPE,
P_PITCH,
P_TPC,
P_HEAD_TYPE,
P_HEAD_GROUP,
P_VELO_TYPE,
P_VELO_OFFSET,
P_ARTICULATION_ANCHOR,
P_DIRECTION,
P_STEM_DIRECTION,
P_NO_STEM,
P_SLUR_DIRECTION,
P_LEADING_SPACE,
P_TRAILING_SPACE,
P_DISTRIBUTE,
P_MIRROR_HEAD,
P_DOT_POSITION,
P_ONTIME_OFFSET,
P_OFFTIME_OFFSET,
P_TUNING,
P_PAUSE,
P_BARLINE_SPAN,
P_USER_OFF,
P_FRET,
P_STRING,
P_GHOST,
P_TIMESIG_NOMINAL,
P_TIMESIG_ACTUAL,
P_NUMBER_TYPE,
P_BRACKET_TYPE,
P_NORMAL_NOTES,
P_ACTUAL_NOTES,
P_P1,
P_P2,
P_GROW_LEFT,
P_GROW_RIGHT,
P_BOX_HEIGHT,
P_BOX_WIDTH,
P_TOP_GAP,
P_BOTTOM_GAP,
P_LEFT_MARGIN,
P_RIGHT_MARGIN,
P_TOP_MARGIN,
P_BOTTOM_MARGIN,
P_LAYOUT_BREAK,
P_AUTOSCALE,
P_SIZE,
P_SCALE,
P_LOCK_ASPECT_RATIO,
P_SIZE_IS_SPATIUM,
P_TEXT_STYLE,
P_USER_MODIFIED,
P_BEAM_POS,
P_BEAM_MODE,
P_USER_LEN, // used for stems
P_SPACE, // used for spacer
P_END
};
enum P_TYPE {
T_SUBTYPE,
T_BOOL,
T_INT,
T_REAL,
T_SREAL,
T_FRACTION,
T_POINT,
T_SIZE,
T_SCALE,
T_COLOR,
T_DIRECTION, // enum Direction
T_DIRECTION_H, // enum DirectionH
T_LAYOUT_BREAK,
T_VALUE_TYPE,
T_BEAM_MODE,
};
extern QVariant getProperty(P_ID type, const QDomElement& e);
extern P_TYPE propertyType(P_ID);
extern const char* propertyName(P_ID);
//---------------------------------------------------------
// template Property
//---------------------------------------------------------
template <class T>
class Property {
public:
P_ID id;
void* (T::*data)(); // member function returns pointer to data
void* defaultVal; // pointer to default data
};
//---------------------------------------------------------
// property
//---------------------------------------------------------
template <class T>
Property<T>* property(Property<T>* list, int id)
{
for (int i = 0; ; ++i) {
if (list[i].id == P_END)
break;
else if (list[i].id == id)
return &list[i];
}
return 0;
}
template <class T>
Property<T>* property(Property<T>* list, const QString& name)
{
for (int i = 0; ; ++i) {
if (list[i].id == P_END)
break;
else if (propertyName((P_ID)i) == name)
return &list[i];
}
return 0;
}
#include "xml.h"
//---------------------------------------------------------
// writeProperties
//---------------------------------------------------------
#define WRITE_PROPERTIES(T) \
for (int i = 0;; ++i) { \
const Property<T>& p = propertyList[i]; \
if (p.id == P_END) \
break; \
xml.tag(p.id, ((*(T*)this).*(p.data))(), p.defaultVal); \
}
#define PROPERTY_DECLARATIONS(T) \
virtual QVariant getProperty(P_ID propertyId) const; \
virtual bool setProperty(P_ID propertyId, const QVariant&); \
virtual bool setProperty(const QString&, const QDomElement&); \
Property<T>* property(P_ID id) const; \
virtual QVariant propertyDefault(P_ID) const; \
static Property<T> propertyList[];
//---------------------------------------------------------
// PROPERTY_FUNCTIONS
//---------------------------------------------------------
#define PROPERTY_FUNCTIONS(T) \
\
Property<T>* T::property(P_ID id) const \
{ \
for (int i = 0;; ++i) { \
if (propertyList[i].id == P_END) \
break; \
if (propertyList[i].id == id) \
return &propertyList[i]; \
} \
return 0; \
} \
QVariant T::getProperty(P_ID propertyId) const \
{ \
Property<T>* p = property(propertyId); \
if (p) \
return getVariant(propertyId, ((*(T*)this).*(p->data))()); \
return Element::getProperty(propertyId); \
} \
bool T::setProperty(P_ID propertyId, const QVariant& v) \
{ \
score()->addRefresh(canvasBoundingRect()); \
Property<T>* p = property(propertyId); \
bool rv = true; \
if (p) { \
setVariant(propertyId, ((*this).*(p->data))(), v); \
setGenerated(false); \
} \
else \
rv = Element::setProperty(propertyId, v); \
score()->setLayoutAll(true); \
return rv; \
} \
bool T::setProperty(const QString& name, const QDomElement& e) \
{ \
for (int i = 0;; ++i) { \
P_ID id = propertyList[i].id; \
if (id == P_END) \
break; \
if (propertyName(id) == name) { \
QVariant v = ::getProperty(id, e); \
setVariant(id, ((*this).*(propertyList[i].data))(), v); \
setGenerated(false); \
return true; \
} \
} \
return Element::setProperty(name, e); \
} \
QVariant T::propertyDefault(P_ID id) const \
{ \
Property<T>* p = property(id); \
return getVariant(id, p->defaultVal); \
}
#endif