diff --git a/include/nana/gui/widgets/tabbar.hpp b/include/nana/gui/widgets/tabbar.hpp index 02722d96..a788dc29 100644 --- a/include/nana/gui/widgets/tabbar.hpp +++ b/include/nana/gui/widgets/tabbar.hpp @@ -337,8 +337,6 @@ namespace nana namespace nana { - namespace ng - { namespace drawerbase { namespace tabbar_lite @@ -352,7 +350,7 @@ namespace nana driver(); ~driver(); - model* get_model(); + model* get_model() const throw(); private: //Overrides drawer_trigger's method void attached(widget_reference, graph_reference) override; @@ -373,11 +371,15 @@ namespace nana tabbar_lite() = default; tabbar_lite(window, bool visible = true, const::nana::rectangle& = {}); + public: //capacity + std::size_t length() const; + + public: //modifiers + void attach(std::size_t pos, window); void push_back(std::string text, ::nana::any par = {}); void push_front(std::string text, ::nana::any par = {}); }; - } } #endif diff --git a/source/gui/place.cpp b/source/gui/place.cpp index aa1f02f8..92033b99 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -1602,16 +1602,83 @@ namespace nana } private: //Implement dock_notifier_interface + /* + static div_dockpane* _m_left(div_dockpane* dockpn) + { + for (auto & dv : dockpn->div_owner->children) + { + if (dv->div_next == dockpn) + return static_cast(dv.get()); + } + return nullptr; + } + + ::nana::size _m_calc_space_if_remove(div_dockpane* dockpn) + { + div_owner->field_area; + + auto left = _m_left(dockpn); + while (left && !left->display) + left = _m_left(left); + + auto right = dockpn->div_next; + while (right && !right->display) + right = right->div_next; + + } + */ void notify_float() override { set_display(false); + /* + this->width_percent = field_area.width / div_owner->field_area.width * 100.0; + this->height_percent = field_area.height / div_owner->field_area.height * 100.0; + + + //Re-layout the siblings + double other_px = this->div_owner->field_area.height - this->field_area.height; + for (auto& div : this->div_owner->children) + { + if (!div->display) + continue; + + //deprecated + //auto wgt_percent = div->field_area.height / other_px; + //div->weight.assign_percent(wgt_percent * 100.0); + + //???? other_px issue, have + auto dockpn = dynamic_cast(div.get()); + dockpn->width_percent = div->field_area.width / other_px * 100.0; + dockpn->height_percent = div->field_area.height / other_px * 100.0; + } + + this->weight.assign_percent((double(field_area.height) / this->div_owner->field_area.height) * 100.0); + */ impl_ptr_->collocate(); } void notify_dock() override { indicator_.docker.reset(); + + /* + //Re-layout the siblings + auto px = this->weight.get_value(div_owner->field_area.height); + + double other_px = this->div_owner->field_area.height - px; + + this->weight.assign_percent(px / div_owner->field_area.height * 100); + for (auto& div : this->div_owner->children) + { + if (!div->display) + continue; + + auto px = div->weight.get_value(static_cast(other_px)); + div->weight.assign_percent(px / div_owner->field_area.height * 100); + } + */ + set_display(true); impl_ptr_->collocate(); } @@ -1744,6 +1811,8 @@ namespace nana } public: field_dock * dockable_field{ nullptr }; + double width_percent{ -1 }; //[-1, 100] it's invalid if it is less than zero + double height_percent{ -1 }; //[-1, 100] private: implement * impl_ptr_; bool created_{ false }; @@ -1751,7 +1820,7 @@ namespace nana struct indicator_tag { paint::graphics graph; - //panel widget; + //panel widget; //deprecated rectangle r; std::unique_ptr> dock_area; std::unique_ptr
docker; @@ -1766,6 +1835,19 @@ namespace nana : division(kind::dock, std::move(name)) {} + division* front() const + { + auto i = children.cbegin(); + + for (auto i = children.cbegin(); i != children.cend(); ++i) + { + if (i->get()->display) + return i->get(); + } + + return nullptr; + } + void collocate(window wd) override { auto area = this->margin_area(); @@ -1773,20 +1855,30 @@ namespace nana unsigned vert_count = 0, horz_count = 0; unsigned vert_weight = 0, horz_weight = 0; - bool prev_attr = _m_is_vert(children.front()->dir); + bool prev_attr = _m_is_vert(front()->dir); (prev_attr ? horz_count : vert_count) = 1; for (auto & child : children) { - auto is_vert = _m_is_vert(child->dir); + if (!child->display) + continue; - if (child->weight.is_not_none()) + auto child_dv = dynamic_cast(child.get()); + + const auto is_vert = _m_is_vert(child->dir); + + /* + if (is_vert) { - if (is_vert) - vert_weight += static_cast(child->weight.get_value(area.height)); - else - horz_weight += static_cast(child->weight.get_value(area.width)); + if (child_dv->height_percent >= 0) + vert_weight += static_cast(child_dv->height_percent * area.height); } + else + { + if (child_dv->width_percent >= 0) + horz_weight += static_cast(child_dv->width_percent * area.width); + } + */ if (is_vert == prev_attr) { @@ -1819,12 +1911,36 @@ namespace nana for (auto & child : children) { + if (!child->display) + continue; + + auto child_dv = dynamic_cast(child.get()); double weight; + + /* //deprecated if (child->weight.is_not_none()) weight = child->weight.get_value(_m_is_vert(child->dir) ? area.height : area.height); else weight = (_m_is_vert(child->dir) ? auto_vert_w : auto_horz_w); + if (_m_is_vert(child->dir)) + { + if (child_dv->height_percent >= 0) + weight = child_dv->height_percent * area.height; + else + weight = auto_vert_w; + } + else + { + if (child_dv->width_percent >= 0) + weight = child_dv->width_percent * area.width; + else + weight = auto_horz_w; + } + */ + + weight = (_m_is_vert(child->dir) ? auto_vert_w : auto_horz_w); + ::nana::rectangle child_r; switch (child->dir) { @@ -2216,7 +2332,12 @@ namespace nana std::vector> adjusted_children; for (auto & child : children) { - adjusted_children.emplace_back(new div_dockpane(std::move(child->name), this, child->dir)); + //ignores weight if it is a dockpane + //internally, width_percent/height_percent are employed for weight + auto dockpn = new div_dockpane(std::move(child->name), this, child->dir); + dockpn->div_next = child->div_next; + dockpn->div_owner = child->div_owner; + adjusted_children.emplace_back(dockpn); } children.swap(adjusted_children); diff --git a/source/gui/place_parts.hpp b/source/gui/place_parts.hpp index 3a1b670e..b90732f5 100644 --- a/source/gui/place_parts.hpp +++ b/source/gui/place_parts.hpp @@ -198,7 +198,7 @@ namespace nana }); if (panels_.size() > 1) - tabbar_.reset(new tabbar(*this)); + tabbar_.reset(new tabbar_lite(*this)); std::size_t pos = 0; for (auto & pn : panels_) @@ -208,8 +208,10 @@ namespace nana pn.widget_ptr = pn.factory_fn(*this); if (tabbar_) { - tabbar_->push_back(pn.widget_ptr->caption()); - tabbar_->relate(pos++, pn.widget_ptr->handle()); + tabbar_->push_back(::nana::charset(pn.widget_ptr->caption())); + tabbar_->attach(pos++, pn.widget_ptr->handle()); + //tabbar_->push_back(pn.widget_ptr->caption()); + //tabbar_->relate(pos++, pn.widget_ptr->handle()); } } } @@ -262,7 +264,7 @@ namespace nana std::unique_ptr container_; dockarea_caption caption_; std::deque panels_; - std::unique_ptr> tabbar_; + std::unique_ptr tabbar_; struct moves { diff --git a/source/gui/widgets/tabbar.cpp b/source/gui/widgets/tabbar.cpp index 624b5db1..3796a1ac 100644 --- a/source/gui/widgets/tabbar.cpp +++ b/source/gui/widgets/tabbar.cpp @@ -1275,8 +1275,6 @@ namespace nana #include namespace nana { - namespace ng - { namespace drawerbase { namespace tabbar_lite @@ -1286,6 +1284,7 @@ namespace nana ::std::string text; ::nana::any value; ::std::pair pos_ends; + ::nana::window attached_window{ nullptr }; item(std::string t, ::nana::any v) : text(std::move(t)), value(std::move(v)) @@ -1361,6 +1360,23 @@ namespace nana return items_; } + void show_attached_window() + { + if (indexes_.active_pos != npos) + { + auto i = items_.cbegin(); + std::advance(i, indexes_.active_pos); + API::show_window(i->attached_window, true); + + std::size_t pos = 0; + for (auto & m : items_) + { + if (pos++ != indexes_.active_pos) + API::show_window(m.attached_window, false); + } + } + } + bool track_pointer(const point& pos) { std::size_t item_pos = 0; @@ -1476,7 +1492,7 @@ namespace nana delete model_; } - model* driver::get_model() + model* driver::get_model() const throw() { return model_; } @@ -1514,10 +1530,12 @@ namespace nana void driver::mouse_down(graph_reference graph, const arg_mouse&) { auto & indexes = model_->get_indexes(); - if (indexes.hovered_pos == model_->npos) + if ((indexes.hovered_pos == model_->npos) || (indexes.active_pos == indexes.hovered_pos)) return; indexes.active_pos = indexes.hovered_pos; + model_->show_attached_window(); + refresh(graph); API::lazy_refresh(); } @@ -1532,6 +1550,41 @@ namespace nana this->create(parent_wd, r, visible); } + //capacity + std::size_t tabbar_lite::length() const + { + auto& items = get_drawer_trigger().get_model()->items(); + internal_scope_guard lock; + + std::size_t off = 0; + auto i = items.cbegin(), end = items.cend(); + while (i != end) + { + ++i; + ++off; + } + return off; + } + + //modifiers + void tabbar_lite::attach(std::size_t pos_set, window wd) + { + auto model = get_drawer_trigger().get_model(); + internal_scope_guard lock; + + for (auto & m : model->items()) + { + if (0 == pos_set--) + { + m.attached_window = wd; + model->show_attached_window(); + return; + } + } + + throw std::out_of_range("invalid position of tabbar_lite"); + } + void tabbar_lite::push_back(std::string text, ::nana::any any) { auto & items = get_drawer_trigger().get_model()->items(); @@ -1561,5 +1614,4 @@ namespace nana API::refresh_window(handle()); } //end class tabbar - } }//end namespace nana