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) ) {