diff --git a/resources/data/skins/dark-mode.surge-skin/skin.xml b/resources/data/skins/dark-mode.surge-skin/skin.xml
index f47451a8543..9f1a322ff9b 100644
--- a/resources/data/skins/dark-mode.surge-skin/skin.xml
+++ b/resources/data/skins/dark-mode.surge-skin/skin.xml
@@ -85,174 +85,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/resources/data/skins/tests/test-minimal-position.surge-skin/skin.xml b/resources/data/skins/tests/test-minimal-position.surge-skin/skin.xml
new file mode 100644
index 00000000000..5cb9967bc44
--- /dev/null
+++ b/resources/data/skins/tests/test-minimal-position.surge-skin/skin.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/common/gui/CLFOGui.cpp b/src/common/gui/CLFOGui.cpp
index 4bc1f9e201e..f9fed021736 100644
--- a/src/common/gui/CLFOGui.cpp
+++ b/src/common/gui/CLFOGui.cpp
@@ -462,8 +462,10 @@ void CLFOGui::drawVectorized(CDrawContext* dc)
CRect tb(leftpanel);
tb.top = leftpanel.top + 10 * i;
tb.bottom = tb.top + 10;
+ //std::cout << std::hex << this << std::dec << " CHECK " << i << " " << lfodata->shape.val.i;
if (i == lfodata->shape.val.i)
{
+ //std::cout << " ON" << std::endl;
CRect tb2(tb);
tb2.left++;
tb2.top += 0.5;
@@ -475,6 +477,7 @@ void CLFOGui::drawVectorized(CDrawContext* dc)
}
else
{
+ //std::cout << " OFF" << std::endl;
dc->setFontColor(skin->getColor( "lfo.type.unselected.foreground", kBlackCColor) );
}
// else dc->setFillColor(cgray);
@@ -858,7 +861,10 @@ void CLFOGui::drawStepSeq(VSTGUI::CDrawContext *dc, VSTGUI::CRect &maindisp, VST
v.bottom = max(p1, p2) + 1;
}
// if (p1 == p2) p2++;
- cdisurf->fillRect(v, stepMarker);
+ if ((i >= ss->loop_start) && (i <= ss->loop_end))
+ cdisurf->fillRect(v, stepMarker);
+ else
+ cdisurf->fillRect(v, disStepMarker);
}
diff --git a/src/common/gui/SkinSupport.cpp b/src/common/gui/SkinSupport.cpp
index 891b080497d..8c088fd62fa 100644
--- a/src/common/gui/SkinSupport.cpp
+++ b/src/common/gui/SkinSupport.cpp
@@ -309,47 +309,11 @@ void Skin::reloadSkin(std::shared_ptr bitmapStore)
return std::string( av );
};
- for (auto gchild = controlsxml->FirstChild(); gchild; gchild = gchild->NextSibling())
- {
- auto lkid = TINYXML_SAFE_TO_ELEMENT(gchild);
- if (!lkid)
- continue;
-
- if (std::string(lkid->Value()) != "control")
- {
- FIXMEERROR << "INVALID CONTROL" << std::endl;
- continue;
- }
-
- Skin::Control c;
- c.x = attrint(lkid, "x");
- c.y = attrint(lkid, "y");
- c.w = attrint(lkid, "w");
- c.h = attrint(lkid, "h");
- c.posx = attrint(lkid, "posx");
- c.posy = attrint(lkid, "posy");
- c.posy_offset = attrint(lkid, "posy_offset");
-
- c.classname = attrstr(lkid, "class" );
- if( lkid->Attribute( "tag_value" ) )
- {
- c.type = Control::Type::ENUM;
- c.enum_id = attrint( lkid, "tag_value" );
- c.enum_name = attrstr( lkid, "tag_name" );
- }
- else
- {
- c.type = Control::Type::UIID;
- c.ui_id = attrstr( lkid, "ui_identifier" );
- }
-
- for (auto a = lkid->FirstAttribute(); a; a = a->Next())
- c.allprops[a->Name()] = a->Value();
-
- controls.push_back(c);
- }
+ controls.clear();
+ rootControl = std::make_shared();
+ recursiveGroupParse( rootControl, controlsxml );
- // TODO: add component-classes section
+ componentClasses.clear();
for (auto gchild = componentclassesxml->FirstChild(); gchild; gchild = gchild->NextSibling())
{
auto lkid = TINYXML_SAFE_TO_ELEMENT(gchild);
@@ -362,27 +326,27 @@ void Skin::reloadSkin(std::shared_ptr bitmapStore)
continue;
}
- Skin::ComponentClass c;
+ auto c = std::make_shared();
- c.name = attrstr( lkid, "name" );
- if( c.name == "" )
+ c->name = attrstr( lkid, "name" );
+ if( c->name == "" )
{
FIXMEERROR << "INVALUD NAME" << std::endl;
}
- if( componentClasses.find( c.name ) != componentClasses.end() )
+ if( componentClasses.find( c->name ) != componentClasses.end() )
{
FIXMEERROR << "Double Definition" << std::endl;
}
for (auto a = lkid->FirstAttribute(); a; a = a->Next())
- c.allprops[a->Name()] = a->Value();
+ c->allprops[a->Name()] = a->Value();
- componentClasses[c.name] = c;
+ componentClasses[c->name] = c;
};
- // process the images
+ // process the images and colors
for (auto g : globals)
{
if (g.first == "defaultimage")
@@ -457,6 +421,96 @@ void Skin::reloadSkin(std::shared_ptr bitmapStore)
}
}
}
+
+ // Resolve the ultimate parent classes
+ for( auto &c : controls )
+ {
+ c->ultimateparentclassname = c->classname;
+ while( componentClasses.find( c->ultimateparentclassname ) != componentClasses.end() )
+ {
+ auto comp = componentClasses[c->ultimateparentclassname];
+ if( comp->allprops.find( "parent" ) != comp->allprops.end() )
+ {
+ c->ultimateparentclassname = componentClasses[c->ultimateparentclassname]->allprops["parent"];
+ }
+ else
+ {
+ FIXMEERROR << "PARENT CLASS DOESN'T RESOLVE FOR " << c->ultimateparentclassname << std::endl;
+ break;
+ }
+ }
+ }
+
+}
+
+void Skin::recursiveGroupParse( ControlGroup::ptr_t parent, TiXmlElement *controlsxml, std::string pfx )
+{
+ // I know I am gross for copying these
+ auto attrint = [](TiXmlElement* e, const char* a) {
+ const char* av = e->Attribute(a);
+ if (!av)
+ return -1;
+ return std::atoi(av);
+ };
+
+ auto attrstr = [](TiXmlElement *e, const char* a ) {
+ const char* av = e->Attribute(a);
+ if( !av )
+ return std::string();
+ return std::string( av );
+ };
+
+ for (auto gchild = controlsxml->FirstChild(); gchild; gchild = gchild->NextSibling())
+ {
+ auto lkid = TINYXML_SAFE_TO_ELEMENT(gchild);
+ if (!lkid)
+ continue;
+
+ if( std::string( lkid->Value()) == "group" )
+ {
+ auto g = std::make_shared();
+
+ g->x = attrint( lkid, "x" ); if( g->x < 0 ) g->x = 0; g->x += parent->x;
+ g->y = attrint( lkid, "y" ); if( g->y < 0 ) g->y = 0; g->y += parent->y;
+ g->w = attrint( lkid, "w" );
+ g->h = attrint( lkid, "h" );
+
+ parent->childGroups.push_back(g);
+ recursiveGroupParse( g, lkid, pfx + "|--" );
+ }
+ else if (std::string(lkid->Value()) == "control")
+ {
+ auto c = std::make_shared();
+ c->x = attrint(lkid, "x") + parent->x;
+ c->y = attrint(lkid, "y") + parent->y;
+ c->w = attrint(lkid, "w");
+ c->h = attrint(lkid, "h");
+
+ c->classname = attrstr(lkid, "class" );
+ if( lkid->Attribute( "tag_value" ) )
+ {
+ c->type = Control::Type::ENUM;
+ c->enum_id = attrint( lkid, "tag_value" );
+ c->enum_name = attrstr( lkid, "tag_name" );
+ }
+ else
+ {
+ c->type = Control::Type::UIID;
+ c->ui_id = attrstr( lkid, "ui_identifier" );
+ }
+
+ for (auto a = lkid->FirstAttribute(); a; a = a->Next())
+ c->allprops[a->Name()] = a->Value();
+
+ controls.push_back(c);
+ parent->childControls.push_back(c);
+ }
+ else
+ {
+ FIXMEERROR << "INVALID CONTROL" << std::endl;
+ }
+ }
+
}
bool Skin::hasColor(std::string id)
@@ -491,5 +545,28 @@ VSTGUI::CColor Skin::getColor(std::string id, const VSTGUI::CColor& def, std::un
}
return def;
}
+
+
+CScalableBitmap *Skin::backgroundBitmapForControl( Skin::Control::ptr_t c, std::shared_ptr bitmapStore )
+{
+ CScalableBitmap *bmp = nullptr;
+ auto ms = propertyValue( c, "bg_id" );
+ if( ms.isJust() )
+ {
+ bmp = bitmapStore->getBitmap(std::atoi(ms.fromJust().c_str()));
+ }
+ else
+ {
+ auto mr = propertyValue( c, "bg_resource" );
+ if( mr.isJust() )
+ {
+ bmp = bitmapStore->getBitmapByStringID( mr.fromJust() );
+ if( ! bmp )
+ bmp = bitmapStore->loadBitmapByPathForStringID( resourceName( mr.fromJust() ), mr.fromJust() );
+ }
+ }
+ return bmp;
+}
+
} // namespace UI
} // namespace Surge
diff --git a/src/common/gui/SkinSupport.h b/src/common/gui/SkinSupport.h
index f14a6d33f07..cd90facac6f 100644
--- a/src/common/gui/SkinSupport.h
+++ b/src/common/gui/SkinSupport.h
@@ -26,6 +26,7 @@
class SurgeStorage;
class SurgeBitmaps;
class CScalableBitmap;
+class TiXmlElement;
namespace VSTGUI {
class CFrame;
@@ -35,12 +36,37 @@ namespace VSTGUI {
namespace Surge
{
+
+
+template
+class Maybe {
+public:
+ Maybe() : _empty(true){};
+ explicit Maybe(T value) : _empty(false), _value(value){};
+
+ T fromJust() const {
+ if (isJust()) {
+ return _value;
+ } else {
+ throw "Cannot get value from Nothing";
+ }
+ }
+
+ bool isJust() const { return !_empty; }
+ bool isNothing() const { return _empty; }
+
+ static bool isJust(Maybe &m) { return m.isJust(); }
+ static bool isNothing(Maybe &m) { return m.isNothing(); }
+private:
+ bool _empty;
+ T _value;
+};
+
namespace UI
{
-
class SkinDB;
-
+
class Skin
{
public:
@@ -67,42 +93,89 @@ class Skin
struct ComponentClass
{
+ typedef std::shared_ptr ptr_t;
std::string name;
props_t allprops;
};
-
+
struct Control
{
- int x, y, w, h, posx, posy, posy_offset;
+ typedef std::shared_ptr ptr_t;
+ int x, y, w, h;
int enum_id;
std::string ui_id, enum_name;
typedef enum {
ENUM,
- UIID
+ UIID,
} Type;
Type type;
std::string classname;
+ std::string ultimateparentclassname;
props_t allprops;
};
+ struct ControlGroup
+ {
+ typedef std::shared_ptr ptr_t;
+ std::vector childGroups;
+ std::vector childControls;
+
+ int x = 0, y = 0, w = -1, h = -1;
+
+ props_t allprops;
+ };
+
bool hasColor( std::string id );
VSTGUI::CColor getColor( std::string id, const VSTGUI::CColor &def, std::unordered_set noLoops = std::unordered_set() );
std::unordered_set getQueriedColors() { return queried_colors; }
- bool controlForUIID( std::string ui_id, Skin::Control &c ) {
+ Skin::Control::ptr_t controlForUIID( std::string ui_id ) {
// FIXME don't be stupid like this of course
for( auto ic : controls )
{
- if( ic.type == Control::Type::UIID && ic.ui_id == ui_id )
+ if( ic->type == Control::Type::UIID && ic->ui_id == ui_id )
{
- c = ic;
- return true;
+ return ic;
}
}
- return false;
+ return nullptr;
+ }
+
+ Maybe propertyValue( Skin::Control::ptr_t c, std::string key ) {
+ /*
+ ** Traverse class heirarchy looking for value
+ */
+ if( c->allprops.find(key) != c->allprops.end() )
+ return Maybe(c->allprops[key]);
+ auto cl = componentClasses[c->classname];
+
+ do {
+ if( cl->allprops.find(key) != cl->allprops.end() )
+ return Maybe(cl->allprops[key]);
+
+ if( cl->allprops.find( "parent" ) !=cl->allprops.end() &&
+ componentClasses.find(cl->allprops["parent"]) != componentClasses.end() )
+ {
+ cl = componentClasses[cl->allprops["parent"]];
+ }
+ else
+ return Maybe();
+ } while( true );
+
+ return Maybe();
}
+
+ std::string propertyValue( Skin::Control::ptr_t c, std::string key, std::string defaultValue ) {
+ auto pv = propertyValue( c, key );
+ if( pv.isJust() )
+ return pv.fromJust();
+ else
+ return defaultValue;
+ }
+
+ CScalableBitmap *backgroundBitmapForControl( Skin::Control::ptr_t c, std::shared_ptr bitmapStore );
private:
static std::atomic instances;
@@ -125,8 +198,11 @@ class Skin
std::unordered_map colors;
std::unordered_set queried_colors;
std::unordered_map imageIds;
- std::vector controls;
- std::unordered_map componentClasses;
+ ControlGroup::ptr_t rootControl;
+ std::vector controls;
+ std::unordered_map componentClasses;
+
+ void recursiveGroupParse( ControlGroup::ptr_t parent, TiXmlElement *groupList, std::string pfx="" );
};
class SkinDB
diff --git a/src/common/gui/SurgeGUIEditor.cpp b/src/common/gui/SurgeGUIEditor.cpp
index 2005f0ddb95..0a40b3a0a1d 100644
--- a/src/common/gui/SurgeGUIEditor.cpp
+++ b/src/common/gui/SurgeGUIEditor.cpp
@@ -205,7 +205,7 @@ SurgeGUIEditor::SurgeGUIEditor(void* effect, SurgeSynthesizer* synth, void* user
editor_open = false;
queue_refresh = false;
memset(param, 0, 1024 * sizeof(void*));
- polydisp = 0;
+ polydisp = 0; // FIXME - when changing skins and rebuilding we need to reset these state variables too
clear_infoview_countdown = -1;
vu[0] = 0;
vu[1] = 0;
@@ -412,7 +412,7 @@ void SurgeGUIEditor::idle()
int prior = cnpd->getPoly();
cnpd->setPoly( synth->polydisplay );
if( prior != synth->polydisplay )
- cnpd->invalid();
+ cnpd->invalid();
}
bool patchChanged = false;
@@ -795,6 +795,13 @@ void SurgeGUIEditor::openOrRecreateEditor()
CPoint nopoint(0, 0);
+ /*
+ ** There are a collection of member states we need to reset
+ */
+ polydisp = 0;
+ lfodisplay = 0;
+ for( int i=0; i<16; ++i ) vu[i] = 0;
+
current_scene = synth->storage.getPatch().scene_active.val.i;
{
@@ -976,16 +983,181 @@ void SurgeGUIEditor::openOrRecreateEditor()
{
Parameter* p = *iter;
+ bool paramIsVisible = ((p->scene == (current_scene + 1)) || (p->scene == 0)) &&
+ isControlVisible(p->ctrlgroup, p->ctrlgroup_entry) && (p->ctrltype != ct_none);
+
std::string uiid = p->ui_identifier;
- Surge::UI::Skin::Control c;
- if( currentSkin->controlForUIID(uiid, c) )
+ bool handledBySkins = false;
+
+ /*
+ ** OK so we basically have two paths here. One which is skin specified, and one which is
+ ** default specified. The skin specified one delegates almost all the decisions to the skin
+ ** engine data structure if it can find it
+ */
+ auto c = currentSkin->controlForUIID(uiid);
+ if( c.get() && paramIsVisible )
{
- // std::cout << "Was able to get a control for the uiid '" << c.ui_id << "' class is '" << c.classname << "'" << std::endl;
+ // borrow from 1.6.6
+ long style = p->ctrlstyle;
+
+ switch (p->ctrltype)
+ {
+ case ct_decibel:
+ case ct_decibel_narrow:
+ case ct_decibel_narrow_extendable:
+ case ct_decibel_extra_narrow:
+ case ct_decibel_extendable:
+ case ct_freq_mod:
+ case ct_percent_bidirectional:
+ case ct_freq_shift:
+ style |= kBipolar;
+ break;
+ };
+
+ auto parentClassName = c->ultimateparentclassname;
+ handledBySkins = true; // by default assume we are handled
+
+ // Would be great to change this to a switch by making it an enum. FIXME
+ if( parentClassName == "CSurgeSlider" )
+ {
+ CSurgeSlider* hs =
+ new CSurgeSlider(CPoint(c->x, c->y), style, this, p->id + start_paramtags, true, bitmapStore);
+ hs->setSkin(currentSkin);
+ hs->setMoveRate(p->moverate);
+ if( p->can_temposync() )
+ hs->setTempoSync(p->temposync);
+ hs->setValue(p->get_value_f01());
+ hs->setLabel(p->get_name());
+ hs->setModPresent(synth->isModDestUsed(p->id));
+ hs->setDefaultValue(p->get_default_value_f01());
+
+ if (synth->isValidModulation(p->id, modsource))
+ {
+ hs->setModMode(mod_editor ? 1 : 0);
+ hs->setModValue(synth->getModulation(p->id, modsource));
+ hs->setModCurrent(synth->isActiveModulation(p->id, modsource), synth->isBipolarModulation(modsource));
+ }
+ else
+ {
+ // Even if current modsource isn't modulating me, something else may be
+ }
+ frame->addView(hs);
+ param[i] = hs;
+
+ }
+ else if( parentClassName == "CLFOGui" )
+ {
+ if( p->ctrltype != ct_lfoshape )
+ {
+ // FIXME - warning?
+ }
+ CRect rect(0, 0, c->w, c->h);
+ rect.offset(c->x, c->y);
+ int lfo_id = p->ctrlgroup_entry - ms_lfo1;
+ if ((lfo_id >= 0) && (lfo_id < n_lfos))
+ {
+ CLFOGui* slfo = new CLFOGui(
+ rect, lfo_id == 0, this, p->id + start_paramtags,
+ &synth->storage.getPatch().scene[current_scene].lfo[lfo_id], &synth->storage,
+ &synth->storage.getPatch().stepsequences[current_scene][lfo_id],
+ bitmapStore);
+ slfo->setSkin( currentSkin );
+ lfodisplay = slfo;
+ frame->addView(slfo);
+ nonmod_param[i] = slfo;
+ }
+ }
+ else if( parentClassName == "CSwitchControl" )
+ {
+ CRect rect(0, 0, c->w, c->h);
+ rect.offset(c->x, c->y);
+
+ // Make this a function on skin
+ auto bmp = currentSkin->backgroundBitmapForControl( c, bitmapStore );
+ if( bmp )
+ {
+ CSwitchControl* hsw = new CSwitchControl(rect, this, p->id + start_paramtags, bmp );
+ hsw->setValue(p->get_value_f01());
+ frame->addView(hsw);
+ nonmod_param[i] = hsw;
+
+ // Carry over this filter type special case from the default control path
+ if( p->ctrltype == ct_filtertype )
+ {
+ ((CSwitchControl*)hsw)->is_itype = true;
+ ((CSwitchControl*)hsw)->imax = 3;
+ ((CSwitchControl*)hsw)->ivalue = p->val.i + 1;
+ if (fut_subcount[synth->storage.getPatch()
+ .scene[current_scene]
+ .filterunit[p->ctrlgroup_entry]
+ .type.val.i] == 0)
+ ((CSwitchControl*)hsw)->ivalue = 0;
+
+ if (p->ctrlgroup_entry == 1)
+ {
+ f2subtypetag = p->id + start_paramtags;
+ filtersubtype[1] = hsw;
+ }
+ else
+ {
+ f1subtypetag = p->id + start_paramtags;
+ filtersubtype[0] = hsw;
+ }
+ }
+
+ }
+ else
+ {
+ std::cout << "Couldn't make CSwitch Control for ID '" << uiid << "'" << std::endl;
+ }
+
+ }
+ else if( parentClassName == "CHSwitch2" )
+ {
+ CRect rect(0, 0, c->w, c->h);
+ rect.offset(c->x, c->y);
+
+ // Make this a function on skin
+ auto bmp = currentSkin->backgroundBitmapForControl( c, bitmapStore );
+ if( bmp )
+ {
+ auto subpixmaps = currentSkin->propertyValue( c, "subpixmaps", "1" );
+ auto rows = currentSkin->propertyValue( c, "rows", "1" );
+ auto cols = currentSkin->propertyValue( c, "columns", "1" );
+ CControl* hsw = new CHSwitch2(rect, this, p->id + start_paramtags,
+ std::atoi(subpixmaps.c_str()), c->h,
+ std::atoi(rows.c_str()), std::atoi(cols.c_str()),
+ bmp, nopoint,
+ true); // FIXME - this needs parameterization
+ hsw->setValue(p->get_value_f01());
+ frame->addView(hsw);
+ nonmod_param[i] = hsw;
+ }
+ }
+ else
+ {
+ handledBySkins = false; /* FIXME: currentSkin->fallbackToDefaultSkin() */
+ std::cout << "Was able to get a control for the uiid '" << c->ui_id << "' class is '" << c->classname << "' upc='" << parentClassName << "'" << std::endl;
+ }
+
+
+ /*
+ switch( parentClass )
+ {
+ case Surge::UI::Skin::Control::CSurgeSlider:
+ case Surge::UI::t lSkin::Control::CHSwitch2:
+ default:
+ std::cout << "UNKNOWN PARENT CLASS " << parentClass << std::endl;
+ break;
+ }
+ */
}
- if ((p->posx != 0) && ((p->scene == (current_scene + 1)) || (p->scene == 0)) &&
- isControlVisible(p->ctrlgroup, p->ctrlgroup_entry) && (p->ctrltype != ct_none))
+ if (! handledBySkins && p->posx != 0 && paramIsVisible)
{
+ /*
+ ** This is the legacy/1.6.6 codepath
+ */
long style = p->ctrlstyle;
/*if(p->ctrlstyle == cs_hori) style = kHorizontal;
else if(p->ctrlstyle == cs_vert) style = kVertical | kBottom;*/
@@ -1336,6 +1508,7 @@ void SurgeGUIEditor::openOrRecreateEditor()
int lfo_id = p->ctrlgroup_entry - ms_lfo1;
if ((lfo_id >= 0) && (lfo_id < n_lfos))
{
+ std::cout << "Old School LFOGUI Build" << std::endl;
CLFOGui* slfo = new CLFOGui(
rect, lfo_id == 0, this, p->id + start_paramtags,
&synth->storage.getPatch().scene[current_scene].lfo[lfo_id], &synth->storage,
@@ -1478,20 +1651,6 @@ void SurgeGUIEditor::openOrRecreateEditor()
hs->setTempoSync(p->temposync);
frame->addView(hs);
param[i] = hs;
-
- /* if(p->can_temposync() && (style &
- kHorizontal))
- {
- CRect rect(0,0,14,18);
- rect.offset(p->posx+134,p->posy+5 + p->posy_offset*yofs);
- CControl *hsw = new
- gui_switch(rect,this,p->id+start_paramtags+tag_temposyncoffset,bmp_temposync);
- rect(1,1,11,14);
- rect.offset(p->posx+134,p->posy+5 + p->posy_offset*yofs);
- hsw->setMouseableArea(rect);
- hsw->setValue(p->temposync?1.f:0.f);
- frame->addView(hsw);
- } */
}
}
break;
@@ -3835,21 +3994,55 @@ VSTGUI::COptionMenu *SurgeGUIEditor::makeSkinMenu(VSTGUI::CRect &menuRect)
auto defaultNoOp = []() { Surge::UserInteractions::promptError( "Not Implemented Yet", "Sorry" ); };
auto &db = Surge::UI::SkinDB::get(&(synth->storage));
+ bool hasTests = false;
for( auto &entry : db.getAvailableSkins() )
{
- addCallbackMenu(skinSubMenu, entry.name,
- [this, entry, &db]() {
- auto s = db.getSkin(entry);
- this->currentSkin = s;
- this->bitmapStore.reset(new SurgeBitmaps());
- this->bitmapStore->setupBitmapsForFrame(frame);
- this->currentSkin->reloadSkin(this->bitmapStore);
- reloadFromSkin();
- this->synth->refresh_editor = true;
- Surge::Storage::updateUserDefaultValue(&(this->synth->storage), "defaultSkin", entry.name );
- });
- tid++;
+ if( entry.name.rfind( "test", 0 ) == 0 )
+ {
+ hasTests = true;
+ }
+ else
+ {
+ addCallbackMenu(skinSubMenu, entry.name,
+ [this, entry, &db]() {
+ auto s = db.getSkin(entry);
+ this->currentSkin = s;
+ this->bitmapStore.reset(new SurgeBitmaps());
+ this->bitmapStore->setupBitmapsForFrame(frame);
+ this->currentSkin->reloadSkin(this->bitmapStore);
+ reloadFromSkin();
+ this->synth->refresh_editor = true;
+ Surge::Storage::updateUserDefaultValue(&(this->synth->storage), "defaultSkin", entry.name );
+ });
+ tid++;
+ }
+ }
+
+
+ if( hasTests )
+ {
+ COptionMenu *testSM = new COptionMenu(menuRect, 0, 0, 0, 0,
+ VSTGUI::COptionMenu::kNoDrawStyle |
+ VSTGUI::COptionMenu::kMultipleCheckStyle);
+ for( auto &entry : db.getAvailableSkins() )
+ {
+ if( entry.name.rfind( "test", 0 ) == 0 )
+ addCallbackMenu(testSM, entry.name,
+ [this, entry, &db]() {
+ auto s = db.getSkin(entry);
+ this->currentSkin = s;
+ this->bitmapStore.reset(new SurgeBitmaps());
+ this->bitmapStore->setupBitmapsForFrame(frame);
+ this->currentSkin->reloadSkin(this->bitmapStore);
+ reloadFromSkin();
+ this->synth->refresh_editor = true;
+ Surge::Storage::updateUserDefaultValue(&(this->synth->storage), "defaultSkin", entry.name );
+ });
+
+ }
+ skinSubMenu->addEntry( testSM, "Test Skins" );
}
+
skinSubMenu->addSeparator();
tid++;
@@ -3947,10 +4140,12 @@ VSTGUI::COptionMenu *SurgeGUIEditor::makeDevMenu(VSTGUI::CRect &menuRect)
oss << " x=\"" << vs.left << "\" y=\"" << vs.top
<< "\" w=\"" << vs.getWidth() << "\" h=\"" << vs.getHeight() << "\"";
+ /*
if( p )
oss << " posx=\"" << p->posx << "\" "
<< " posy=\"" << p->posy << "\" "
<< " posy_offset=\"" << p->posy_offset << "\" ";
+ */
auto dumpBG = [&oss](CControl *a) {
auto bg = a->getBackground();
@@ -3958,7 +4153,8 @@ VSTGUI::COptionMenu *SurgeGUIEditor::makeDevMenu(VSTGUI::CRect &menuRect)
if( rd.type == CResourceDescription::kIntegerType )
{
ios::fmtflags f(oss.flags());
- oss << " bg_resource=\"svg/bmp" << std::setw(5) << std::setfill('0') << rd.u.id << ".svg\" ";
+ oss << " bg_resource=\"SVG/bmp" << std::setw(5) << std::setfill('0') << rd.u.id << ".svg\" ";
+ oss << " bg_id=\"" << rd.u.id << "\" ";
oss.flags(f);
}
};
@@ -3967,7 +4163,9 @@ VSTGUI::COptionMenu *SurgeGUIEditor::makeDevMenu(VSTGUI::CRect &menuRect)
{
oss << " class=\"CHSwitch2\" ";
dumpBG(a);
- // Want to extract subPixmaps, heightOfOneImage, rows, cols, offset and the bitmap store id of background
+ oss << " subpixmaps=\"" << a->getNumSubPixmaps()
+ << "\" rows=\"" << a->rows
+ << "\" columns=\"" << a->columns << "\"";
}
else if( auto a = dynamic_cast(c) )
{