Skip to content

Commit

Permalink
Merge pull request #156 from NREL/JSON_UIforms
Browse files Browse the repository at this point in the history
JSON UI forms for develop per GitHub issue SAM 504
  • Loading branch information
brtietz authored Feb 6, 2023
2 parents ae21e40 + 4cb1f47 commit c9aae91
Show file tree
Hide file tree
Showing 6 changed files with 336 additions and 11 deletions.
44 changes: 42 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
run: cmake --version
- name: Install OS dependencies
run: |
sudo apt-get update
sudo apt-get update --fix-missing
sudo apt-get install -y \
build-essential \
freeglut3-dev \
Expand Down Expand Up @@ -68,6 +68,26 @@ jobs:
run: |
echo "LKDIR=$GITHUB_WORKSPACE/lk" >>$GITHUB_ENV
echo "LKD_LIB=$GITHUB_WORKSPACE/lk/build_linux" >>$GITHUB_ENV # iff CMAKE_BUILD_TYPE=Debug
- name: Set RAPIDJSONDIR
run: |
echo "RAPIDJSONDIR=$GITHUB_WORKSPACE/ssc" >>$GITHUB_ENV
- name: Get git ref of sibling dependency SSC
run: |
ref=$(git ls-remote --exit-code git://github.com/NREL/ssc.git refs/heads/develop | awk '{print $1}')
echo "ref_of_ssc=$ref" | tee --append $GITHUB_ENV
- name: Get cached build data of sibling dependency SSC
uses: actions/cache@v2
id: cachedssc
with:
path: ${{ env.GH_WORKSPACE }}/ssc
key: ${{ env.RUNS_ON }}-${{ env.ref_of_ssc }}-SSC
- name: Clone sibling dependency SSC
if: steps.cachedssc.outputs.cache-hit != 'true'
uses: actions/checkout@v2
with:
ref: ${{ env.ref_of_ssc }}
path: ssc
repository: NREL/ssc

- name: Checkout
uses: actions/checkout@v2
Expand Down Expand Up @@ -101,7 +121,7 @@ jobs:
run: cmake --version
- name: Install OS dependencies
run: |
sudo apt-get update
sudo apt-get update --fix-missing
sudo apt-get install -y \
build-essential \
freeglut3-dev \
Expand Down Expand Up @@ -150,6 +170,26 @@ jobs:
run: |
echo "LKDIR=$GITHUB_WORKSPACE/lk" >>$GITHUB_ENV
echo "LKD_LIB=$GITHUB_WORKSPACE/lk/build_linux" >>$GITHUB_ENV # iff CMAKE_BUILD_TYPE=Debug
- name: Set RAPIDJSONDIR
run: |
echo "RAPIDJSONDIR=$GITHUB_WORKSPACE/ssc" >>$GITHUB_ENV
- name: Get git ref of sibling dependency SSC
run: |
ref=$(git ls-remote --exit-code git://github.com/NREL/ssc.git refs/heads/develop | awk '{print $1}')
echo "ref_of_ssc=$ref" | tee --append $GITHUB_ENV
- name: Get cached build data of sibling dependency SSC
uses: actions/cache@v2
id: cachedssc
with:
path: ${{ env.GH_WORKSPACE }}/ssc
key: ${{ env.RUNS_ON }}-${{ env.ref_of_ssc }}-SSC
- name: Clone sibling dependency SSC
if: steps.cachedssc.outputs.cache-hit != 'true'
uses: actions/checkout@v2
with:
ref: ${{ env.ref_of_ssc }}
path: ssc
repository: NREL/ssc

- name: Checkout
uses: actions/checkout@v2
Expand Down
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ endif ()
#
#####################################################################################################################

# for rapidjson folder
include_directories($ENV{RAPIDJSONDIR})

add_subdirectory(src)
if (NOT SAM_SKIP_TOOLS)
add_subdirectory(tools)
Expand Down
15 changes: 13 additions & 2 deletions include/wex/uiform.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <wx/wx.h>
#include <wx/clrpicker.h>
#include <rapidjson/document.h>

class wxUIProperty;

Expand Down Expand Up @@ -120,6 +121,10 @@ class wxUIProperty {
void Write_text(wxOutputStream &, wxString &);

bool Read_text(wxInputStream &, wxString &);

void Write_JSON(rapidjson::Document&, wxString &);

bool Read_JSON(const rapidjson::Value&, wxString&);

void AddUpdateInterface(const wxString &name, wxUIPropertyUpdateInterface *pui);

Expand Down Expand Up @@ -220,6 +225,11 @@ class wxUIObject : public wxUIPropertyUpdateInterface {
virtual void Write_text(wxOutputStream &, wxString &);

virtual bool Read_text(wxInputStream &, wxString &);

virtual void Write_JSON(rapidjson::Document&, wxString &);

virtual bool Read_JSON(const rapidjson::Value&, wxString&);


protected:
void AddProperty(const wxString &name, wxUIProperty *prop);
Expand Down Expand Up @@ -314,13 +324,14 @@ class wxUIFormData {

// load/save form definition
virtual void Write(wxOutputStream &);

virtual bool Read(wxInputStream &);

virtual void Write_text(wxOutputStream &, wxString &);

virtual bool Read_text(wxInputStream &, wxString &);

virtual void Write_JSON(rapidjson::Document&, wxString &);
virtual bool Read_JSON(const rapidjson::Document&, wxString&);

// methods to create/edit UI objects
wxUIObject *Create(const wxString &type, const wxRect &geom, const wxString &name = wxEmptyString);

Expand Down
14 changes: 14 additions & 0 deletions include/wex/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <wx/string.h>
#include <wx/arrstr.h>
#include <wx/dc.h>
#include <rapidjson/document.h>

std::vector<int> wxCommaDashListToIndices(const wxString &value);

void Write_JSON_value(rapidjson::Document& doc, wxString name, double value);

void Write_JSON_value(rapidjson::Document& doc, wxString name, wxString value);

void Write_JSON_multiline_value(rapidjson::Document& doc, wxString name, wxString value);

wxString Read_JSON_multiline_value(const rapidjson::Value& doc, wxString name);


void Write_JSON_value(rapidjson::Document& doc, wxString name, wxArrayString value);

wxString Read_JSON_value(const rapidjson::Value& doc, wxString name);

wxString wxLimitTextColumns(const wxString &str, size_t numcols);

wxString wxConvertToBase26(unsigned int val);
Expand Down
201 changes: 200 additions & 1 deletion src/uiform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1293,7 +1293,6 @@ bool wxUIProperty::Read(wxInputStream &_i) {
return (code == in.Read8());
}


void wxUIProperty::Write_text(wxOutputStream &_o, wxString &ui_path) {
wxExtTextOutputStream out(_o, wxEOL_UNIX);
wxString s = wxEmptyString;
Expand Down Expand Up @@ -1364,6 +1363,122 @@ void wxUIProperty::Write_text(wxOutputStream &_o, wxString &ui_path) {
}
}


void wxUIProperty::Write_JSON(rapidjson::Document& doc, wxString &ui_path)
{
wxString s = wxEmptyString;
wxString name;
rapidjson::Document json_table(&doc.GetAllocator()); // for table inside of json document.
json_table.SetObject();
int type = GetType();
Write_JSON_value(doc, "Type", type);
switch (type) {
case DOUBLE: {
Write_JSON_value(doc, "Double", GetDouble());
}
break;
case BOOLEAN: {
if (GetBoolean())
Write_JSON_value(doc, "Boolean", 1.0);
else
Write_JSON_value(doc, "Boolean", 0.0);
}
break;
case INTEGER: {
Write_JSON_value(doc, "Integer", GetInteger());
}
break;
case STRING: {
Write_JSON_value(doc, "String", GetString());

}
break;
case COLOUR: {
wxColour c = GetColour();
Write_JSON_value(json_table, "Red", c.Red());
Write_JSON_value(json_table, "Green", c.Green());
Write_JSON_value(json_table, "Blue", c.Blue());
Write_JSON_value(json_table, "Alpha", c.Alpha());
name = "Color";
doc.AddMember(rapidjson::Value(name.c_str(), (unsigned int)name.size(), doc.GetAllocator()).Move(), json_table.Move(), doc.GetAllocator());
}
break;
case STRINGLIST: {
Write_JSON_value(doc, "StringList", GetStringList());
}
break;
case IMAGE: {
wxImage img = GetImage();
img.SaveFile(ui_path + ".png", wxBITMAP_TYPE_PNG);
wxString fn = wxFileName(ui_path + ".png").GetName();
Write_JSON_value(doc, "Image", fn + ".png");
}
break;
}

}

bool wxUIProperty::Read_JSON(const rapidjson::Value& doc, wxString& ui_path)
{
wxUint8 r, g, b, a;
bool ok = true;
int type = (int)doc["Type"].GetDouble();
if (m_pReference)
m_pReference->m_type = type;
else
m_type = type;

switch (type) {
case DOUBLE:
Set(doc["Double"].GetDouble());
break;
case BOOLEAN: {
if ((int)doc["Boolean"].GetDouble() == 1)
Set(true);
else
Set(false);
}
break;
case INTEGER:
Set((int)doc["Integer"].GetDouble());
break;
case STRING:
Set(Read_JSON_value(doc, "String"));
break;
case COLOUR:
for (rapidjson::Value::ConstMemberIterator itr = doc["Color"].GetObject().MemberBegin(); itr != doc["Color"].GetObject().MemberEnd(); ++itr) {
wxString name = wxString(itr->name.GetString());
if (name == "Red")
r = (int)itr->value.GetDouble();
else if (name == "Green")
g = (int)itr->value.GetDouble();
else if (name == "Blue")
b = (int)itr->value.GetDouble();
else if (name == "Alpha")
a = (int)itr->value.GetDouble();
}
Set(wxColour(r, g, b, a));
break;
case STRINGLIST: {
wxArrayString list = wxSplit(Read_JSON_value(doc, "StringList"), '|');
Set(list);
}
break;
case IMAGE: {
wxImage img;
wxString img_filename = doc["Image"].GetString();
img_filename = ui_path + img_filename;
img.LoadFile(img_filename, wxBITMAP_TYPE_PNG);
Set(img);
}
break;
}

return ok;
}



bool wxUIProperty::Read_text(wxInputStream &_i, wxString &ui_path) {
wxExtTextInputStream in(_i, "\n", wxConvAuto(wxFONTENCODING_UTF8));
wxUint16 type = in.Read16();
Expand Down Expand Up @@ -1680,6 +1795,44 @@ void wxUIObject::Write_text(wxOutputStream &_o, wxString &ui_path) {

}


void wxUIObject::Write_JSON(rapidjson::Document &doc, wxString &ui_path)
{
if (m_visible)
Write_JSON_value(doc, "Visible", 1);
else
Write_JSON_value(doc, "Visible", 0);
rapidjson::Document json_objectproperties(&doc.GetAllocator()); // for table inside of json document.
json_objectproperties.SetObject();
for (size_t i = 0; i < m_properties.size(); i++) {
rapidjson::Document json_uiproperty(&json_objectproperties.GetAllocator()); // for table inside of json document.
json_uiproperty.SetObject();
m_properties[i].prop->Write_JSON(json_uiproperty, ui_path);
json_objectproperties.AddMember(rapidjson::Value(m_properties[i].name.c_str(), (unsigned int)m_properties[i].name.size(), json_objectproperties.GetAllocator()).Move(), json_uiproperty.Move(), json_objectproperties.GetAllocator());
}
wxString name="ObjectProperties";
doc.AddMember(rapidjson::Value(name.c_str(), (unsigned int)name.size(), doc.GetAllocator()).Move(), json_objectproperties.Move(), doc.GetAllocator());
}


bool wxUIObject::Read_JSON(const rapidjson::Value &doc, wxString &ui_path)
{
bool ok = true;
if ((int)doc["Visible"].GetDouble() == 1)
m_visible = true;
else
m_visible = false;

auto json_objectproperties = doc["ObjectProperties"].GetObject();
for (rapidjson::Value::ConstMemberIterator itr = json_objectproperties.MemberBegin(); itr != json_objectproperties.MemberEnd() && ok; ++itr) {
wxString name = itr->name.GetString();
ok = ok && Property(name).Read_JSON(itr->value, ui_path);
}
return ok;

}


bool wxUIObject::Read_text(wxInputStream &_i, wxString &ui_path) {
wxExtTextInputStream in(_i, "\n");

Expand Down Expand Up @@ -2213,9 +2366,55 @@ void wxUIFormData::Write_text(wxOutputStream &_O, wxString &ui_path) {
o->Write_text(_O, ui_path);
}
}
}

void wxUIFormData::Write_JSON(rapidjson::Document& doc, wxString &ui_path)
{
Write_JSON_value(doc, "Name", m_name);
Write_JSON_value(doc, "Width", m_width);
Write_JSON_value(doc, "Height", m_height);
rapidjson::Document json_formobjects(&doc.GetAllocator()); // for table inside of json document.
json_formobjects.SetObject();
wxUIObject *o;
wxArrayString as = ListAll();
as.Sort();
for (size_t i = 0; i < as.Count(); i++) {
o = Find(as[i]);
if (o != NULL) {
rapidjson::Document json_uiobject(&json_formobjects.GetAllocator()); // for table inside of json document.
json_uiobject.SetObject();
o->Write_JSON(json_uiobject, ui_path);
json_formobjects.AddMember(rapidjson::Value(o->GetTypeName().c_str(), (unsigned int)o->GetTypeName().size(), json_formobjects.GetAllocator()).Move(), json_uiobject.Move(), json_formobjects.GetAllocator());
}
}
wxString name="FormObjects";
doc.AddMember(rapidjson::Value(name.c_str(), (unsigned int)name.size(), doc.GetAllocator()).Move(), json_formobjects.Move(), doc.GetAllocator());
}

bool wxUIFormData::Read_JSON(const rapidjson::Document& doc, wxString& ui_path)
{
bool ok = true;
DeleteAll();

m_name = doc["Name"].GetString();
m_width = (int)doc["Width"].GetDouble();
m_height = (int)doc["Height"].GetDouble();


auto json_formobjects = doc["FormObjects"].GetObject();

for (rapidjson::Value::ConstMemberIterator itr = json_formobjects.MemberBegin(); itr != json_formobjects.MemberEnd() && ok; ++itr) {
wxString type = itr->name.GetString();
if (wxUIObject *obj = Create(type))
ok = ok && obj->Read_JSON(itr->value, ui_path);
else
ok = false;
}
return ok;
}



bool wxUIFormData::Read_text(wxInputStream &_I, wxString &ui_path) {
DeleteAll();

Expand Down
Loading

0 comments on commit c9aae91

Please sign in to comment.