├── .gitignore ├── .gitmodules ├── LICENSE ├── NanaDesigner.sln ├── NanaDesigner ├── DesignerForm.cpp ├── DesignerForm.h ├── ExportViewer.cpp ├── ExportViewer.h ├── NanaDesigner.vcxproj ├── NanaDesigner.vcxproj.filters ├── PreviewPanel.cpp ├── PreviewPanel.h ├── ResolutionForm.cpp ├── ResolutionForm.h ├── SchemeEditor.cpp ├── SchemeEditor.h ├── Utils.h ├── color_picker.cpp ├── color_picker.h ├── color_picker_panel.cpp ├── color_picker_panel.h ├── main.cpp ├── nana_typeinfo.cpp ├── nana_typeinfo.h └── vector_utils.h ├── README.md ├── external └── json │ └── include │ └── nlohmann │ └── json.hpp ├── extra ├── NanaDesigner.props ├── PropertySheet.props └── nana_1.5.1.props ├── submodule instructions.txt └── tests ├── main.cpp ├── tests.vcxproj └── tests.vcxproj.filters /.gitignore: -------------------------------------------------------------------------------- 1 | # Lib temp files 2 | build 3 | external/temp/nana 4 | 5 | # Compiled Object files 6 | *.slo 7 | *.lo 8 | *.o 9 | *.obj 10 | 11 | # Precompiled Headers 12 | *.gch 13 | *.pch 14 | 15 | # Compiled Dynamic libraries 16 | *.so 17 | *.dylib 18 | *.dll 19 | 20 | # Fortran module files 21 | *.mod 22 | *.smod 23 | 24 | # Compiled Static libraries 25 | *.lai 26 | *.la 27 | *.a 28 | *.lib 29 | 30 | # Executables 31 | *.exe 32 | *.out 33 | *.app 34 | 35 | ## Ignore Visual Studio temporary files, build results, and 36 | ## files generated by popular Visual Studio add-ons. 37 | ## 38 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 39 | 40 | # User-specific files 41 | *.suo 42 | *.user 43 | *.userosscache 44 | *.sln.docstates 45 | 46 | # User-specific files (MonoDevelop/Xamarin Studio) 47 | *.userprefs 48 | 49 | # Build results 50 | [Dd]ebug/ 51 | [Dd]ebugPublic/ 52 | [Rr]elease/ 53 | [Rr]eleases/ 54 | x64/ 55 | x86/ 56 | bld/ 57 | [Bb]in/ 58 | [Oo]bj/ 59 | [Ll]og/ 60 | 61 | # Visual Studio 2015 cache/options directory 62 | .vs/ 63 | # Uncomment if you have tasks that create the project's static files in wwwroot 64 | #wwwroot/ 65 | 66 | # MSTest test Results 67 | [Tt]est[Rr]esult*/ 68 | [Bb]uild[Ll]og.* 69 | 70 | # NUNIT 71 | *.VisualState.xml 72 | TestResult.xml 73 | 74 | # Build Results of an ATL Project 75 | [Dd]ebugPS/ 76 | [Rr]eleasePS/ 77 | dlldata.c 78 | 79 | # .NET Core 80 | project.lock.json 81 | project.fragment.lock.json 82 | artifacts/ 83 | **/Properties/launchSettings.json 84 | 85 | *_i.c 86 | *_p.c 87 | *_i.h 88 | *.ilk 89 | *.meta 90 | *.obj 91 | *.pch 92 | *.pdb 93 | *.pgc 94 | *.pgd 95 | *.rsp 96 | *.sbr 97 | *.tlb 98 | *.tli 99 | *.tlh 100 | *.tmp 101 | *.tmp_proj 102 | *.log 103 | *.vspscc 104 | *.vssscc 105 | .builds 106 | *.pidb 107 | *.svclog 108 | *.scc 109 | 110 | # Chutzpah Test files 111 | _Chutzpah* 112 | 113 | # Visual C++ cache files 114 | ipch/ 115 | *.aps 116 | *.ncb 117 | *.opendb 118 | *.opensdf 119 | *.sdf 120 | *.cachefile 121 | *.VC.db 122 | *.VC.VC.opendb 123 | 124 | # Visual Studio profiler 125 | *.psess 126 | *.vsp 127 | *.vspx 128 | *.sap 129 | 130 | # TFS 2012 Local Workspace 131 | $tf/ 132 | 133 | # Guidance Automation Toolkit 134 | *.gpState 135 | 136 | # ReSharper is a .NET coding add-in 137 | _ReSharper*/ 138 | *.[Rr]e[Ss]harper 139 | *.DotSettings.user 140 | 141 | # JustCode is a .NET coding add-in 142 | .JustCode 143 | 144 | # TeamCity is a build add-in 145 | _TeamCity* 146 | 147 | # DotCover is a Code Coverage Tool 148 | *.dotCover 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # TODO: Comment the next line if you want to checkin your web deploy settings 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # The packages folder can be ignored because of Package Restore 198 | **/packages/* 199 | # except build/, which is used as an MSBuild target. 200 | !**/packages/build/ 201 | # Uncomment if necessary however generally it will be regenerated when needed 202 | #!**/packages/repositories.config 203 | # NuGet v3's project.json files produces more ignorable files 204 | *.nuget.props 205 | *.nuget.targets 206 | 207 | # Microsoft Azure Build Output 208 | csx/ 209 | *.build.csdef 210 | 211 | # Microsoft Azure Emulator 212 | ecf/ 213 | rcf/ 214 | 215 | # Windows Store app package directories and files 216 | AppPackages/ 217 | BundleArtifacts/ 218 | Package.StoreAssociation.xml 219 | _pkginfo.txt 220 | 221 | # Visual Studio cache files 222 | # files ending in .cache can be ignored 223 | *.[Cc]ache 224 | # but keep track of directories ending in .cache 225 | !*.[Cc]ache/ 226 | 227 | # Others 228 | ClientBin/ 229 | ~$* 230 | *~ 231 | *.dbmdl 232 | *.dbproj.schemaview 233 | *.jfm 234 | *.pfx 235 | *.publishsettings 236 | orleans.codegen.cs 237 | 238 | # Since there are multiple workflows, uncomment next line to ignore bower_components 239 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 240 | #bower_components/ 241 | 242 | # RIA/Silverlight projects 243 | Generated_Code/ 244 | 245 | # Backup & report files from converting an old project file 246 | # to a newer Visual Studio version. Backup files are not needed, 247 | # because we have git ;-) 248 | _UpgradeReport_Files/ 249 | Backup*/ 250 | UpgradeLog*.XML 251 | UpgradeLog*.htm 252 | 253 | # SQL Server files 254 | *.mdf 255 | *.ldf 256 | *.ndf 257 | 258 | # Business Intelligence projects 259 | *.rdl.data 260 | *.bim.layout 261 | *.bim_*.settings 262 | 263 | # Microsoft Fakes 264 | FakesAssemblies/ 265 | 266 | # GhostDoc plugin setting file 267 | *.GhostDoc.xml 268 | 269 | # Node.js Tools for Visual Studio 270 | .ntvs_analysis.dat 271 | node_modules/ 272 | 273 | # Typescript v1 declaration files 274 | typings/ 275 | 276 | # Visual Studio 6 build log 277 | *.plg 278 | 279 | # Visual Studio 6 workspace options file 280 | *.opt 281 | 282 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 283 | *.vbw 284 | 285 | # Visual Studio LightSwitch build output 286 | **/*.HTMLClient/GeneratedArtifacts 287 | **/*.DesktopClient/GeneratedArtifacts 288 | **/*.DesktopClient/ModelManifest.xml 289 | **/*.Server/GeneratedArtifacts 290 | **/*.Server/ModelManifest.xml 291 | _Pvt_Extensions 292 | 293 | # Paket dependency manager 294 | .paket/paket.exe 295 | paket-files/ 296 | 297 | # FAKE - F# Make 298 | .fake/ 299 | 300 | # JetBrains Rider 301 | .idea/ 302 | *.sln.iml 303 | 304 | # CodeRush 305 | .cr/ 306 | 307 | # Python Tools for Visual Studio (PTVS) 308 | __pycache__/ 309 | *.pyc 310 | 311 | # Cake - Uncomment if you are using it 312 | # tools/** 313 | # !tools/packages.config 314 | 315 | # Telerik's JustMock configuration file 316 | *.jmconfig 317 | 318 | # BizTalk build output 319 | *.btp.cs 320 | *.btm.cs 321 | *.odx.cs 322 | *.xsd.cs 323 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "external/nana"] 2 | path = external/nana 3 | url = https://github.com/cnjinhao/nana.git 4 | [submodule "external/inja"] 5 | path = external/inja 6 | url = https://github.com/pantor/inja.git 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Maiko Steeman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NanaDesigner.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.705 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NanaDesigner", "NanaDesigner\NanaDesigner.vcxproj", "{B5355F36-7A08-4E9F-B99C-F7D3DCD02539}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests\tests.vcxproj", "{2D288D54-3422-4D7B-BE3E-80F070C237FF}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dependencies", "Dependencies", "{AC873378-03F3-4394-8CCE-2C105DB6EA15}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nana", "external\nana\build\vc2017\nana.vcxproj", "{42D0520F-EFA5-4831-84FE-2B9085301C5D}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|x64 = Debug|x64 17 | Debug|x86 = Debug|x86 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {B5355F36-7A08-4E9F-B99C-F7D3DCD02539}.Debug|x64.ActiveCfg = Debug|x64 23 | {B5355F36-7A08-4E9F-B99C-F7D3DCD02539}.Debug|x64.Build.0 = Debug|x64 24 | {B5355F36-7A08-4E9F-B99C-F7D3DCD02539}.Debug|x86.ActiveCfg = Debug|Win32 25 | {B5355F36-7A08-4E9F-B99C-F7D3DCD02539}.Debug|x86.Build.0 = Debug|Win32 26 | {B5355F36-7A08-4E9F-B99C-F7D3DCD02539}.Release|x64.ActiveCfg = Release|x64 27 | {B5355F36-7A08-4E9F-B99C-F7D3DCD02539}.Release|x64.Build.0 = Release|x64 28 | {B5355F36-7A08-4E9F-B99C-F7D3DCD02539}.Release|x86.ActiveCfg = Release|Win32 29 | {B5355F36-7A08-4E9F-B99C-F7D3DCD02539}.Release|x86.Build.0 = Release|Win32 30 | {2D288D54-3422-4D7B-BE3E-80F070C237FF}.Debug|x64.ActiveCfg = Debug|x64 31 | {2D288D54-3422-4D7B-BE3E-80F070C237FF}.Debug|x64.Build.0 = Debug|x64 32 | {2D288D54-3422-4D7B-BE3E-80F070C237FF}.Debug|x86.ActiveCfg = Debug|Win32 33 | {2D288D54-3422-4D7B-BE3E-80F070C237FF}.Debug|x86.Build.0 = Debug|Win32 34 | {2D288D54-3422-4D7B-BE3E-80F070C237FF}.Release|x64.ActiveCfg = Release|x64 35 | {2D288D54-3422-4D7B-BE3E-80F070C237FF}.Release|x64.Build.0 = Release|x64 36 | {2D288D54-3422-4D7B-BE3E-80F070C237FF}.Release|x86.ActiveCfg = Release|Win32 37 | {2D288D54-3422-4D7B-BE3E-80F070C237FF}.Release|x86.Build.0 = Release|Win32 38 | {42D0520F-EFA5-4831-84FE-2B9085301C5D}.Debug|x64.ActiveCfg = Debug|x64 39 | {42D0520F-EFA5-4831-84FE-2B9085301C5D}.Debug|x64.Build.0 = Debug|x64 40 | {42D0520F-EFA5-4831-84FE-2B9085301C5D}.Debug|x86.ActiveCfg = Debug|Win32 41 | {42D0520F-EFA5-4831-84FE-2B9085301C5D}.Debug|x86.Build.0 = Debug|Win32 42 | {42D0520F-EFA5-4831-84FE-2B9085301C5D}.Release|x64.ActiveCfg = Release|x64 43 | {42D0520F-EFA5-4831-84FE-2B9085301C5D}.Release|x64.Build.0 = Release|x64 44 | {42D0520F-EFA5-4831-84FE-2B9085301C5D}.Release|x86.ActiveCfg = Release|Win32 45 | {42D0520F-EFA5-4831-84FE-2B9085301C5D}.Release|x86.Build.0 = Release|Win32 46 | EndGlobalSection 47 | GlobalSection(SolutionProperties) = preSolution 48 | HideSolutionNode = FALSE 49 | EndGlobalSection 50 | GlobalSection(NestedProjects) = preSolution 51 | {42D0520F-EFA5-4831-84FE-2B9085301C5D} = {AC873378-03F3-4394-8CCE-2C105DB6EA15} 52 | EndGlobalSection 53 | GlobalSection(ExtensibilityGlobals) = postSolution 54 | SolutionGuid = {E1A5BADA-E3E2-4E0F-8ACB-3C02FDAC554A} 55 | EndGlobalSection 56 | EndGlobal 57 | -------------------------------------------------------------------------------- /NanaDesigner/DesignerForm.cpp: -------------------------------------------------------------------------------- 1 | #include "DesignerForm.h" 2 | #include 3 | #include 4 | #include "Utils.h" 5 | #include "ExportViewer.h" 6 | #include "ResolutionForm.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "color_picker_panel.h" 12 | #include "SchemeEditor.h" 13 | 14 | namespace fs = std::filesystem; 15 | 16 | DesignerForm::DesignerForm() : form(API::make_center(800, 600)) 17 | { 18 | caption("Nana UI Editor"); 19 | 20 | const char* main_div_text = MULTILINE( 21 | vert < 22 | 24 | 25 | > 26 | > 27 | 29 | < 30 | 31 | 32 | > 33 | > 34 | > 35 | > 36 | ); 37 | div(main_div_text); 38 | 39 | get_place().dock("preview", "f"); 40 | widget* dock = get_place().dock_create("f"); 41 | preview = dynamic_cast(dock); 42 | 43 | file_menu.append("New", [this](nana::menu::item_proxy& ip) { 44 | this->get_place().dock_create("f"); 45 | }); 46 | 47 | file_menu.append("Save", [&](menu::item_proxy& ip) 48 | { 49 | filebox fb{*this, false}; 50 | fb.title("GUI Project save file"); 51 | fb.add_filter("JSON", "*.json;*.JSON"); 52 | fb.allow_multi_select(false); 53 | std::vector path_parts = fb.show(); 54 | if (!path_parts.empty()) { 55 | fs::path selected_path = path_parts[0]; 56 | string filename = (selected_path.filename().stem().string()); 57 | std::cout << filename << std::endl; 58 | if (ExportViewer::isCorrectName(filename)) { 59 | if (!project_info_) project_info_ = new project_info(); 60 | project_info_->name = filename; 61 | std::ofstream ofs(selected_path, std::ios::binary); 62 | json j = json::object(); 63 | j["name"] = project_info_->name; 64 | j["contents"] = ExportViewer::GenerateCodeContents(*preview); 65 | ofs << j; 66 | RefreshProjectInfo(); 67 | } 68 | else 69 | { 70 | msgbox mb{ *this, "Wrong filename", msgbox::button_t::ok }; 71 | mb.icon(msgbox::icon_error); 72 | mb << L"You can only enter the characters: [a-z] [A-Z] [0-9] and '_'"; 73 | mb.show(); 74 | } 75 | } 76 | }); 77 | file_menu.append("Open", [&](menu::item_proxy& ip) 78 | {//TODO: Check for unsaved changes 79 | filebox fb{ *this, true }; 80 | fb.title("GUI Project save file"); 81 | fb.add_filter("JSON", "*.json;*.JSON"); 82 | fb.allow_multi_select(false); 83 | std::vector selectedPaths = fb.show(); 84 | if (!selectedPaths.empty()) { 85 | fs::path selectedPath = selectedPaths[0]; 86 | std::ifstream ifs(selectedPath, std::ios::binary); 87 | json j; 88 | j << ifs; 89 | if (!project_info_) project_info_ = new project_info(); 90 | string proj_name = j["name"]; 91 | project_info_->name = proj_name; 92 | json& contents = j["contents"]; 93 | string div = contents["div"]; 94 | preview->applyDiv(div); 95 | for (int i = preview->widgetAmount() - 1; i >= 0; --i) 96 | preview->removeWidget(i); 97 | for (json object : contents["widgets"]) 98 | { 99 | nanatype* type = &nana::get_nanatype_by_internalname(object["type"]); 100 | string caption = object["caption"]; 101 | widget* widget = type->instantiate(*preview, caption); 102 | if(widget) 103 | { 104 | string tag = object["tag"]; 105 | 106 | PreviewPanel::widget_ptr widget_ptr{ widget }; 107 | PreviewPanel::widget_pair widget_pair{ tag, widget_ptr }; 108 | 109 | preview->addWidget(widget_pair); 110 | } 111 | else 112 | { 113 | std::cout << "could not create widget: " << object["type"] << std::endl; 114 | } 115 | } 116 | 117 | Refresh(); 118 | } 119 | }); 120 | file_menu.append_splitter(); 121 | file_menu.append("Export", [&](nana::menu::item_proxy& ip) 122 | { 123 | std::unique_ptr export_viewer(new ExportViewer(handle())); 124 | json j = export_viewer->GenerateCodeContents(*preview);//TODO: Handle no preview window available 125 | std::cout << j << std::endl; 126 | export_viewer->GenerateCode(*preview, project_info_); 127 | export_viewer->show(); 128 | children.push_back(std::move(export_viewer)); 129 | 130 | }); 131 | preview_menu.append("Resolution", [this](menu::item_proxy& ip) 132 | { 133 | if(preview) 134 | { 135 | std::unique_ptr resolution_form(new ResolutionForm(handle(), *preview)); 136 | resolution_form->show(); 137 | children.push_back(std::move(resolution_form)); 138 | } 139 | }); 140 | 141 | schema_menu.append("Scheme editor", [this](menu::item_proxy& ip) 142 | { 143 | auto indices = widgetlist.selected(); 144 | for (auto selected : indices) 145 | { 146 | auto item = widgetlist.at(selected); 147 | PreviewPanel::widget_pair& pair_ptr = item.value(); 148 | string tag = pair_ptr.first; 149 | PreviewPanel::widget_ptr widget_ptr = pair_ptr.second; 150 | 151 | nanatype& type = nana::get_nanatype(*widget_ptr); 152 | form* scheme_editor = type.get_scheme_editor(*this, widget_ptr.get()); 153 | 154 | //SchemeEditor