From df4340af2a82561f7de9112896a9a68585acaa1d Mon Sep 17 00:00:00 2001 From: besh81 Date: Mon, 7 Sep 2020 15:33:00 +0200 Subject: [PATCH] Developing 0.25.0 - linked nana 1.7.4 - added project name to form caption - added 'MOVE INTO' functionality to move a group of controls into a field, a grid or a panel - checkbox: added scheme - toolbar: improved code generation - fixed context menu behaviour on object panel - fixed bug on pg_color_inherited initialization - fixed monor bugs --- README.MD | 4 +- build/codeblocks_win/nana_creator.cbp | 2 + src/assetspanel.cpp | 2 +- src/config.h | 3 +- src/creator.cpp | 26 ++- src/creator.h | 8 +- src/ctrls/checkbox.cpp | 25 ++- src/ctrls/checkbox.h | 2 + src/ctrls/listbox.cpp | 5 +- src/ctrls/textbox.cpp | 3 +- src/ctrls/toolbar.cpp | 27 ++- src/guimanager.cpp | 309 +++++++++++++++++++------- src/guimanager.h | 16 ++ src/nana_extra/propertygrid.h | 2 +- src/objectspanel.cpp | 20 +- src/objectspanel.h | 1 + src/pgitems_creator.cpp | 3 +- src/propertiespanel.h | 2 +- src/scrollablecanvas.cpp | 2 +- wdir/icons/delete.png | Bin 675 -> 6413 bytes 20 files changed, 360 insertions(+), 102 deletions(-) diff --git a/README.MD b/README.MD index e099dbb..772b251 100644 --- a/README.MD +++ b/README.MD @@ -1,7 +1,7 @@ # Nana Creator Buy Me A Coffee -**Nana Creator** is a RAD tool for (and build with) [Nana C++ Library](https://github.com/cnjinhao/nana). +**Nana Creator** is a RAD tool for (and built with) [Nana C++ Library](https://github.com/cnjinhao/nana). -[![](https://img.shields.io/badge/dependencies-nana%20Lib%201.7.3-blue.svg?longCache=true&style=for-the-badge)](https://github.com/cnjinhao/nana) +[![](https://img.shields.io/badge/dependencies-nana%20Lib%201.7.4-blue.svg?longCache=true&style=for-the-badge)](https://github.com/cnjinhao/nana) Click here to download the win exe file: [![Download nana-creator](https://img.shields.io/sourceforge/dt/nana-creator.svg)](https://sourceforge.net/projects/nana-creator/files/latest/download) diff --git a/build/codeblocks_win/nana_creator.cbp b/build/codeblocks_win/nana_creator.cbp index f2fda01..cc29cfc 100644 --- a/build/codeblocks_win/nana_creator.cbp +++ b/build/codeblocks_win/nana_creator.cbp @@ -124,6 +124,8 @@ + + diff --git a/src/assetspanel.cpp b/src/assetspanel.cpp index 64cb455..97593ee 100644 --- a/src/assetspanel.cpp +++ b/src/assetspanel.cpp @@ -17,7 +17,7 @@ extern imagemanager g_img_mgr; //assetspanel assetspanel::assetspanel(nana::window wd, bool visible) - : nana::panel(wd, visible) + : nana::panel(wd, nana::rectangle(), visible) { bgcolor(CREATOR_WINDOW_BG); diff --git a/src/config.h b/src/config.h index 27821c0..f6c351b 100644 --- a/src/config.h +++ b/src/config.h @@ -10,7 +10,8 @@ #define CREATOR_NAME "Nana Creator" -#define CREATOR_VERSION "0.24.0" +#define CREATOR_VERSION "0.25.0" +#define CREATOR_TITLE (CREATOR_NAME " " CREATOR_VERSION) diff --git a/src/creator.cpp b/src/creator.cpp index 8706a58..26537c7 100644 --- a/src/creator.cpp +++ b/src/creator.cpp @@ -126,7 +126,7 @@ void creator::sb_set(const std::string& str) void creator::_init_ctrls() { - caption(CREATOR_NAME " " CREATOR_VERSION); + caption(CREATOR_TITLE); // toolbar _tb.events().selected([this](const nana::arg_toolbar & arg) @@ -146,6 +146,9 @@ void creator::_init_ctrls() save_xml(prj_name.string()); } + // update window caption + caption(CREATOR_TITLE); + p_gui_mgr->clear(); prj_name = ""; @@ -156,6 +159,15 @@ void creator::_init_ctrls() { prj_name = dlg.get_filename(); + // update window caption + std::string title = CREATOR_TITLE; + if(!prj_name.string().empty()) + { + title.append(" - "); + title.append(prj_name.filename().string()); + } + caption(title); + p_gui_mgr->new_project(dlg.get_ctrl_type(), dlg.get_projectname()); // crea file di progetto @@ -177,6 +189,9 @@ void creator::_init_ctrls() save_xml(prj_name.string()); } + // update window caption + caption(CREATOR_TITLE); + p_gui_mgr->clear(); prj_name = ""; @@ -202,6 +217,15 @@ void creator::_init_ctrls() if(!load_xml(prj_name.string())) prj_name = ""; + + // update window caption + std::string title = CREATOR_TITLE; + if(!prj_name.string().empty()) + { + title.append(" - "); + title.append(prj_name.filename().string()); + } + caption(title); } } else if(arg.button == TB_SAVE) // save project diff --git a/src/creator.h b/src/creator.h index e2f9ff1..35ee019 100644 --- a/src/creator.h +++ b/src/creator.h @@ -1,5 +1,5 @@ /***************************************************** - * C++ code generated with Nana Creator (0.22.0) + * C++ code generated with Nana Creator (0.25.0) * GitHub repo: https://github.com/besh81/nana-creator * * PLEASE EDIT ONLY INSIDE THE TAGS: @@ -60,8 +60,7 @@ class creator _tb.append("Save project", nana::paint::image("icons/save.png")); _tb.append("Save project as...", nana::paint::image("icons/save_as.png")); _tb.separate(); - _tb.append("Generate code", nana::paint::image("icons/output.png")); - _tb.textout(5, true); + _tb.append("Generate code", nana::paint::image("icons/output.png")).textout(true); _tb.separate(); _tb.append("Delete current selection", nana::paint::image("icons/delete.png")); _tb.separate(); @@ -72,8 +71,7 @@ class creator _tb.append("Copy current selection", nana::paint::image("icons/copy.png")); _tb.append("Paste into/after current selection", nana::paint::image("icons/paste.png")); _tb.go_right(); - _tb.append("Info...", nana::paint::image("icons/info.png")); - _tb.textout(15, true); + _tb.append("Info...", nana::paint::image("icons/info.png")).textout(true); // _adi_panel_margin _adi_panel_margin.create(*this); _adi_panel_margin_place.bind(_adi_panel_margin); diff --git a/src/ctrls/checkbox.cpp b/src/ctrls/checkbox.cpp index 2b3b98d..235401a 100644 --- a/src/ctrls/checkbox.cpp +++ b/src/ctrls/checkbox.cpp @@ -7,7 +7,7 @@ #include "config.h" #include "ctrls/checkbox.h" - +#include "nana_extra/color_helper.h" namespace ctrls @@ -20,6 +20,10 @@ namespace ctrls chk.create(*parent->nanawdg); ctrl::init(&chk, CTRL_CHECKBOX, name); + def_scheme = chk.scheme(); + + chk.react(false); // needs to avoid user can change the state clicking on control + // common properties.append("caption").label("Caption").category(CAT_COMMON).type(pg_type::string) = ""; properties.append("check").label("Checked").category(CAT_COMMON).type(pg_type::check) = chk.checked(); @@ -29,6 +33,10 @@ namespace ctrls properties.append("transparent").label("Transparent").category(CAT_APPEARANCE).type(pg_type::check) = chk.transparent(); // layout // ... + //scheme + // def values from checkbox.cpp - function: void drawer::refresh(graph_reference graph) + properties.append("square_bgcolor").label("Square bg").category(CAT_SCHEME).type(pg_type::color_inherited) = nana::to_string(def_scheme.square_bgcolor.get(chk.bgcolor()), true); + properties.append("square_border_color").label("Square border").category(CAT_SCHEME).type(pg_type::color) = nana::to_string(def_scheme.square_border_color.get(chk.fgcolor())); } @@ -41,7 +49,14 @@ namespace ctrls chk.radio(properties.property("radio").as_bool()); chk.transparent(properties.property("transparent").as_bool()); - chk.react(false); // needs to avoid user can change the state clicking on control + //scheme + if(nana::is_color_inherited(properties.property("square_bgcolor").as_string())) + chk.scheme().square_bgcolor = static_cast(0x0); // def values from checkbox.hpp - drawerbase::checkbox::scheme + else + chk.scheme().square_bgcolor = nana::to_color(properties.property("square_bgcolor").as_string()); + chk.scheme().square_border_color = nana::to_color(properties.property("square_border_color").as_string()); + + nana::API::refresh_window(chk); } @@ -84,6 +99,12 @@ namespace ctrls cd->init.push_back(name + ".radio(true);"); if(properties.property("transparent").as_bool()) cd->init.push_back(name + ".transparent(true);"); + + //scheme + if(properties.property("square_bgcolor").as_string() != nana::to_string(def_scheme.square_bgcolor)) + cd->init.push_back(name + ".scheme().square_bgcolor = nana::color(" + properties.property("square_bgcolor").as_string() + ");"); + if(properties.property("square_border_color").as_string() != nana::to_string(def_scheme.square_border_color)) + cd->init.push_back(name + ".scheme().square_border_color = nana::color(" + properties.property("square_border_color").as_string() + ");"); } }//end namespace ctrls diff --git a/src/ctrls/checkbox.h b/src/ctrls/checkbox.h index 491888e..7451e13 100644 --- a/src/ctrls/checkbox.h +++ b/src/ctrls/checkbox.h @@ -29,6 +29,8 @@ namespace ctrls protected: nana::checkbox chk; + + nana::drawerbase::checkbox::scheme def_scheme; }; }//end namespace ctrls diff --git a/src/ctrls/listbox.cpp b/src/ctrls/listbox.cpp index 426c652..7e2b112 100644 --- a/src/ctrls/listbox.cpp +++ b/src/ctrls/listbox.cpp @@ -89,7 +89,7 @@ namespace ctrls lst.scheme().item_selected = nana::to_color(properties.property("item_selected").as_string()); lst.scheme().item_highlighted = nana::to_color(properties.property("item_highlighted").as_string()); lst.scheme().selection_box = nana::to_color(properties.property("selection_box").as_string()); - // column_font + // column_font {???} lst.scheme().max_fit_content = properties.property("max_fit_content").as_uint(); lst.scheme().min_column_width = properties.property("min_column_width").as_uint(); lst.scheme().text_margin = properties.property("text_margin").as_uint(); @@ -98,7 +98,8 @@ namespace ctrls lst.scheme().header_splitter_area_after = properties.property("header_splitter_area_after").as_uint(); lst.scheme().header_padding_top = properties.property("header_padding_top").as_uint(); lst.scheme().header_padding_bottom = properties.property("header_padding_bottom").as_uint(); - // mouse_wheel + // mouse_wheel {???} + nana::API::refresh_window(lst); } diff --git a/src/ctrls/textbox.cpp b/src/ctrls/textbox.cpp index 28b198f..e806e48 100644 --- a/src/ctrls/textbox.cpp +++ b/src/ctrls/textbox.cpp @@ -64,7 +64,8 @@ namespace ctrls txt.scheme().selection = nana::to_color(properties.property("selection").as_string()); txt.scheme().selection_unfocused = nana::to_color(properties.property("selection_unfocused").as_string()); txt.scheme().selection_text = nana::to_color(properties.property("selection_text").as_string()); - // mouse_wheel + // mouse_wheel {???} + nana::API::refresh_window(txt); } diff --git a/src/ctrls/toolbar.cpp b/src/ctrls/toolbar.cpp index c1f384a..ecef32a 100644 --- a/src/ctrls/toolbar.cpp +++ b/src/ctrls/toolbar.cpp @@ -113,7 +113,7 @@ namespace ctrls cd->init.push_back(name + ".scale(" + properties.property("scale").as_string() + ");"); // buttons - START - std::size_t pos = 0; + std::size_t pos = 0; //TODO : nella nuova versione non dovrebbe pił servire for(auto& i : items) { if(i.property("goright").as_bool()) @@ -126,6 +126,7 @@ namespace ctrls cd->init.push_back(name + ".separate();"); else { + /* auto str = name + ".append(\"" + i.property("text").as_string() + "\""; if(i.property("image").as_string().empty()) str.append(");"); @@ -146,6 +147,30 @@ namespace ctrls if(i.property("toggle_pushed").as_bool()) cd->init.push_back(name + ".toggle(" + std::to_string(pos) + ", true);"); } + */ + auto str = name + ".append(\"" + i.property("text").as_string() + "\""; + if(i.property("image").as_string().empty()) + str.append(")"); + else + str.append(", nana::paint::image(\"" + g_file_mgr.to_relative(i.property("image").as_string()) + "\"))"); + + if(!i.property("enable").as_bool()) + str.append(".enable(false)"); + if(i.property("textout").as_bool()) + str.append(".textout(true)"); + + if(i.property("toggle_type").as_bool()) + { + // TODO: questo va direttamente dentro la funzione append + //cd->init.push_back(name + ".tooltype(" + std::to_string(pos) + ", nana::toolbar::tool_type::toggle);"); + if(!i.property("toggle_group").as_string().empty()) + str.append(".toggle_group(\"" + i.property("toggle_group").as_string() + "\")"); + if(i.property("toggle_pushed").as_bool()) + str.append(".toggle(true)"); + } + + str.append(";"); + cd->init.push_back(str); } ++pos; diff --git a/src/guimanager.cpp b/src/guimanager.cpp index 19a810e..7f2d5cf 100644 --- a/src/guimanager.cpp +++ b/src/guimanager.cpp @@ -42,52 +42,70 @@ guimanager::guimanager(nana::window wd) : _root_wd(wd) { // context menu - // 0. move up - _ctxmenu.append("Move Up", [this](const nana::menu::item_proxy& ip) + // move up + _ctxmenu.append("Move up", [this](const nana::menu::item_proxy& ip) { moveupselected(); }); nana::paint::image _img_up("icons/up.png"); _ctxmenu.image(0, _img_up); - // 1. move down - _ctxmenu.append("Move Down", [this](const nana::menu::item_proxy& ip) + // move down + _ctxmenu.append("Move down", [this](const nana::menu::item_proxy& ip) { movedownselected(); }); nana::paint::image _img_down("icons/down.png"); _ctxmenu.image(1, _img_down); - // 2. ----- + // move into + _ctxmenu.append("Move into"); + auto* sub_move_into = _ctxmenu.create_sub_menu(2); + sub_move_into->append("field", [this](const nana::menu::item_proxy& ip) + { + moveintofield(); + }); + sub_move_into->image(0, nana::paint::image("icons/horizontal_layout.png")); + sub_move_into->append("grid", [this](const nana::menu::item_proxy& ip) + { + moveintogrid(); + }); + sub_move_into->image(1, nana::paint::image("icons/grid_layout.png")); + sub_move_into->append("panel", [this](const nana::menu::item_proxy& ip) + { + moveintopanel(); + }); + sub_move_into->image(2, nana::paint::image("icons/panel.png")); + // ----- _ctxmenu.append_splitter(); - // 3. delete + // delete _ctxmenu.append("Delete", [this](const nana::menu::item_proxy& ip) - { - deleteselected(); - }); + { + deleteselected(); + }); nana::paint::image _img_del("icons/delete.png"); - _ctxmenu.image(3, _img_del); - // 4. ----- + _ctxmenu.image(4, _img_del); + // ----- _ctxmenu.append_splitter(); - // 5. cut + // cut _ctxmenu.append("Cut", [this](const nana::menu::item_proxy& ip) - { - copyselected(true); - }); + { + copyselected(true); + }); nana::paint::image _img_cut("icons/cut.png"); - _ctxmenu.image(5, _img_cut); - // 6. copy + _ctxmenu.image(6, _img_cut); + // copy _ctxmenu.append("Copy", [this](const nana::menu::item_proxy& ip) - { - copyselected(); - }); + { + copyselected(); + }); nana::paint::image _img_copy("icons/copy.png"); - _ctxmenu.image(6, _img_copy); - // 7. paste + _ctxmenu.image(7, _img_copy); + // paste _ctxmenu.append("Paste", [this](const nana::menu::item_proxy& ip) - { - pasteselected(); - }); + { + pasteselected(); + }); nana::paint::image _img_paste("icons/paste.png"); - _ctxmenu.image(7, _img_paste); + _ctxmenu.image(8, _img_paste); } @@ -187,6 +205,15 @@ void guimanager::new_project(const std::string& type, const std::string& name) } +void guimanager::_error_message(const std::string& txt) +{ + nana::msgbox m(_root_wd, CREATOR_NAME, nana::msgbox::ok); + m.icon(m.icon_error); + m << txt; + m(); +} + + bool guimanager::_check_relationship(control_obj parent, const std::string& child_type) { // check parent @@ -452,14 +479,14 @@ tree_node* guimanager::addcommonctrl(tree_node* node, control_obj_ptr page_wptr; _ctrls.for_each([page, &page_wptr](tree_node* node) -> bool - { - if(node->value.get() == page) { - page_wptr = node->value; - return false; - } - return true; - }); + if(node->value.get() == page) + { + page_wptr = node->value; + return false; + } + return true; + }); if(page_wptr.expired()) return; @@ -489,10 +516,10 @@ void guimanager::deleteselected() // delete ctrl name _ctrls.for_each(toremove, [this](tree_node* node) -> bool - { - _name_mgr.remove(node->value->properties.property("name").as_string()); - return true; - }); + { + _name_mgr.remove(node->value->properties.property("name").as_string()); + return true; + }); // delete ctrl @@ -566,6 +593,135 @@ void guimanager::movedownselected() } +bool guimanager::_moveinto_check_relationship(tree_node* ctrl, move_into into) +{ + if(!ctrl) + return false; + + auto type = ctrl->value->properties.property("type").as_string(); + if(type == CTRL_PAGE || type == CTRL_FORM || ctrl == _ctrls.get_root()->child) + { + _error_message("Impossible to move the selected control!"); + return false; + } + + auto parent = ctrl->owner; + auto parent_type = parent->value->properties.property("type").as_string(); + + if(into == move_into::field || into == move_into::grid) + { + if(parent_type == CTRL_GRID) + { + _error_message("Impossible to create field/grid inside a grid!"); + return false; + } + } + + if(into == move_into::grid) + { + if(type == CTRL_FIELD || type == CTRL_GRID) + { + _error_message("Impossible to create field/grid inside a grid!"); + return false; + } + } + + return true; +} + +void guimanager::_moveinto(tree_node* ctrl, move_into into) +{ + if(!_moveinto_check_relationship(ctrl, into)) + return; + + auto parent = ctrl->owner; + _select_ctrl(0); + + // disable GUI + enableGUI(false, false); + lock_guard des_lock(&_deserializing, true); + _op->emit_events(false); + _op->auto_draw(false); + + // serialize ctrls to move + pugi::xml_document to_move; + pugi::xml_node root = to_move.append_child(NODE_ROOT); + _serialize(parent->child, &root, false); + + // delete ctrls to move + int num_siblings = 0; + auto sibling = parent->child; + while(sibling) + { + num_siblings++; + + // delete ctrls name + _ctrls.for_each(sibling, [this](tree_node* node) -> bool + { + _name_mgr.remove(node->value->properties.property("name").as_string()); + return true; + }); + + auto next = sibling->next; + + _ctrls.recursive_backward(sibling, [this](tree_node* node) -> bool + { + if(node->owner) + { + control_obj parent_ = node->owner->value; + if(parent_) + parent_->remove(node->value.get()); + } + + _ctrls.remove(node); + + return true; + }); + + sibling = next; + } + + // add new field node + tree_node* new_node = nullptr; + if(into == move_into::field) + { + new_node = addcommonctrl(parent, CTRL_FIELD, insert_mode::into); + // adjust layout orientation + new_node->value->properties.property("layout").value(parent->value->properties.property("layout").as_int()); + } + else if(into == move_into::grid) + { + new_node = addcommonctrl(parent, CTRL_GRID, insert_mode::into); + // adjust grid size + int n = std::max(int(ceil(sqrt(num_siblings))), 2); + new_node->value->properties.property("columns").value(n); + new_node->value->properties.property("rows").value(n); + } + else if(into == move_into::panel) + { + new_node = addcommonctrl(parent, CTRL_PANEL, insert_mode::into); + new_node->value->properties.property("layout").value(parent->value->properties.property("layout").as_int()); + } + + // deserialize ctrls to move + if(!_deserialize(new_node, &root, true)) + { + _error_message("Unable to move the selected controls!"); + } + + // enable GUI + _op->auto_draw(true); + _op->emit_events(true); + _update_op(); + enableGUI(true, true); + + // select new_node + new_node->value->refresh(); + left_click_ctrl(new_node->value); +} + + + void guimanager::copyselected(bool cut) { if(!_selected) @@ -574,10 +730,7 @@ void guimanager::copyselected(bool cut) // main widget cannot be cut or copied if(_selected == _ctrls.get_root()->child) { - nana::msgbox m(_root_wd, CREATOR_NAME, nana::msgbox::ok); - m.icon(m.icon_error); - m << "Impossible to cut/copy the main widget!"; - m(); + _error_message("Impossible to cut/copy the main widget!"); return; } @@ -631,7 +784,7 @@ void guimanager::pasteselected() bool paste_ok = _deserialize(_selected, &root, true); if(!paste_ok) { - //TODO message box con errore + _error_message("Unable to move the selected controls!"); } _op->auto_draw(true); @@ -654,14 +807,14 @@ bool guimanager::click_ctrl(control_obj ctrl, const nana::arg_mouse& arg) tree_node* _ctrl_node{ 0 }; _ctrls.for_each([&ctrl, &_ctrl_node](tree_node* node) -> bool - { - if(node->value == ctrl) { - _ctrl_node = node; - return false; - } - return true; - }); + if(node->value == ctrl) + { + _ctrl_node = node; + return false; + } + return true; + }); if(!_ctrl_node) return false; // continue propagation @@ -740,7 +893,7 @@ bool guimanager::click_ctrl(control_obj ctrl, const nana::arg_mouse& arg) // add ctrl if(!addcommonctrl(_ctrl_node, cursor().type, mode)) { - //TODO message box con errore + _error_message("Unable to add control!"); } // reset mouse cursor @@ -791,22 +944,22 @@ void guimanager::left_click_ctrl(control_obj ctrl) void guimanager::click_objectspanel(const std::string& name) { _ctrls.for_each([this, name](tree_node* node) -> bool - { - if(node->value->properties.property("name").as_string() == name) { - _select_ctrl(node); + if(node->value->properties.property("name").as_string() == name) + { + _select_ctrl(node); - // set properties panel - _pp->set(&node->value->properties, &node->value->items); + // set properties panel + _pp->set(&node->value->properties, &node->value->items); - // set focus to new object - node->value->nanawdg->focus(); + // set focus to new object + node->value->nanawdg->focus(); - return false; - } + return false; + } - return true; - }); + return true; + }); } @@ -1049,13 +1202,13 @@ void guimanager::_updatechildrenctrls(tree_node* node) { auto* this_node = node; _ctrls.for_each(node, [this, this_node](tree_node* node) -> bool - { - if(this_node == node) - return true; + { + if(this_node == node) + return true; - _updatectrl(node, false, false); - return true; - }); + _updatectrl(node, false, false); + return true; + }); } @@ -1067,18 +1220,18 @@ void guimanager::_update_op() _op->clear(); _ctrls.for_each([this](tree_node* node) -> bool - { - auto ctrl = node->value; - - if(node->owner->value) { - auto parent = node->owner->value; - _op->append(parent->properties.property("name").as_string(), ctrl->properties.property("name").as_string(), ctrl->properties.property("type").as_string()); - } - else - _op->append("", ctrl->properties.property("name").as_string(), ctrl->properties.property("type").as_string()); - return true; - }); + auto ctrl = node->value; + + if(node->owner->value) + { + auto parent = node->owner->value; + _op->append(parent->properties.property("name").as_string(), ctrl->properties.property("name").as_string(), ctrl->properties.property("type").as_string()); + } + else + _op->append("", ctrl->properties.property("name").as_string(), ctrl->properties.property("type").as_string()); + return true; + }); _op->auto_draw(true); _op->emit_events(true); diff --git a/src/guimanager.h b/src/guimanager.h index 9655bfb..be2be1c 100644 --- a/src/guimanager.h +++ b/src/guimanager.h @@ -67,6 +67,10 @@ class guimanager void moveupselected(); void movedownselected(); + void moveintofield() { _moveinto(_selected, move_into::field); } + void moveintogrid() { _moveinto(_selected, move_into::grid); } + void moveintopanel() { _moveinto(_selected, move_into::panel); } + void cutselected() { copyselected(true); } void copyselected(bool cut = false); void pasteselected(); @@ -94,6 +98,15 @@ class guimanager private: + enum class move_into + { + field, + grid, + panel + }; + + void _error_message(const std::string& txt); + bool _check_relationship(control_obj parent, const std::string& child_type); control_obj _create_ctrl(control_obj parent, const std::string& type, const std::string& name); @@ -111,6 +124,9 @@ class guimanager void _select_ctrl(tree_node* to_select); + bool _moveinto_check_relationship(tree_node* ctrl, move_into into); + void _moveinto(tree_node* ctrl, move_into into); + nana::window _root_wd; nana::menu _ctxmenu; diff --git a/src/nana_extra/propertygrid.h b/src/nana_extra/propertygrid.h index 03d8a77..4504899 100644 --- a/src/nana_extra/propertygrid.h +++ b/src/nana_extra/propertygrid.h @@ -86,7 +86,7 @@ namespace nana pgitem() = default; pgitem(const std::string& label, const std::string& value = "") ///< Constructor - : label_(label), value_(value), def_(value) + : label_(label), value_(value), def_(value), ess_(nullptr) {} void init(window wd); ///< Initialize the inline controls (should not be used) diff --git a/src/objectspanel.cpp b/src/objectspanel.cpp index b265ede..3decd97 100644 --- a/src/objectspanel.cpp +++ b/src/objectspanel.cpp @@ -16,7 +16,7 @@ extern imagemanager g_img_mgr; //objectspanel objectspanel::objectspanel(nana::window wd, bool visible) - : nana::panel(wd, visible) + : nana::panel(wd, nana::rectangle(), visible) { bgcolor(CREATOR_WINDOW_BG); @@ -117,8 +117,7 @@ bool objectspanel::select(const std::string& name) void objectspanel::selected(std::function f) { - _objects.events().selected([this, f](const nana::arg_treebox& arg) - { + _objects.events().selected([this, f](const nana::arg_treebox& arg) { if(!_evt_emit) return; @@ -131,5 +130,18 @@ void objectspanel::selected(std::function f) void objectspanel::contex_menu(nana::menu* ctx) { _ctxmenu = ctx; - _objects.events().mouse_down(nana::menu_popuper(*_ctxmenu)); + + _objects.events().mouse_down([this](const nana::arg_mouse& arg) { + _right_button = arg.right_button; + }); + + _objects.events().mouse_up([this](const nana::arg_mouse& arg) { + if(!_evt_emit) + return; + + if(_right_button && !_objects.hovered(false).empty()) + { + _ctxmenu->popup(*this, arg.pos.x, arg.pos.y); + } + }); } diff --git a/src/objectspanel.h b/src/objectspanel.h index e7c9331..27c9354 100644 --- a/src/objectspanel.h +++ b/src/objectspanel.h @@ -55,6 +55,7 @@ class objectspanel std::vector _roots; bool _evt_emit{ true }; + bool _right_button{ false }; }; #endif //NANA_CREATOR_OBJECTSPANEL_H diff --git a/src/pgitems_creator.cpp b/src/pgitems_creator.cpp index 477f1d9..310aeee 100644 --- a/src/pgitems_creator.cpp +++ b/src/pgitems_creator.cpp @@ -553,6 +553,7 @@ void pg_color_inherited::inherited(bool value) void pg_color_inherited::create(nana::window wd) { + auto val = value_; pg_color::create(wd); // ibox context menu @@ -565,7 +566,7 @@ void pg_color_inherited::create(nana::window wd) }); menu_.check_style(2, nana::menu::checks::highlight); - pg_color_inherited::value(value_); + pg_color_inherited::value(value_ = val); } /// class pg_color_inherited end diff --git a/src/propertiespanel.h b/src/propertiespanel.h index 31250a0..70d4a4b 100644 --- a/src/propertiespanel.h +++ b/src/propertiespanel.h @@ -28,7 +28,7 @@ class propertiespanel { public: propertiespanel(nana::window wd, bool visible = true) - : nana::panel(wd, visible) + : nana::panel(wd, nana::rectangle(), visible) { init_(); diff --git a/src/scrollablecanvas.cpp b/src/scrollablecanvas.cpp index 13f2221..63fab60 100644 --- a/src/scrollablecanvas.cpp +++ b/src/scrollablecanvas.cpp @@ -11,7 +11,7 @@ scrollablecanvas::scrollablecanvas(nana::window parent, bool visible) - : nana::panel(parent, visible) + : nana::panel(parent, nana::rectangle(), visible) { bgcolor(CREATOR_MAIN_BG); diff --git a/wdir/icons/delete.png b/wdir/icons/delete.png index b456b2d55c99ed3fe04a94713c8c2d8effaba0cf..d188fb2e25f7e3c596fc5aec023c32aa02a9fc2d 100644 GIT binary patch delta 6390 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 Eg7x}N5C8xG delta 609 zcmV-n0-pViGNT2MBa^fiE`QQNZ=GGUEikzveWb0U4R5j2%bDo15}Lh!k)q0wpKD4s^X-wk&PpkU@ay`=oFT z$Qtar^*TzeHVu+V@_)PPx@!}bngf2k-|uTO45tpoFu1a98t|e4yKbvB4+{dCW7vnH z49R--G%`&T!^nA#{Ofz$ibp zybXcJDI7Z&7sw#E1(IQiGlqQvcJiynG5byvvD#|eQbzNPvEIprD%kw4!z<`%On@to=%P)3Pb=^wQVt;#+rWI6m z_DaUEF0cpe1y<0h_IgO)&+1cocX?R?dPS|?0_1@ZX>8l^o$;i