adjust dockpanes when a dockpane is floating/docking
This commit is contained in:
parent
c4af5dafce
commit
ebd8da13f0
@ -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
|
||||
|
@ -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<div_dockpane*>(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_dockpane*>(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<int>(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<true> widget;
|
||||
//panel<true> widget; //deprecated
|
||||
rectangle r;
|
||||
std::unique_ptr<panel<true>> dock_area;
|
||||
std::unique_ptr<form> 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<div_dockpane*>(child.get());
|
||||
|
||||
const auto is_vert = _m_is_vert(child->dir);
|
||||
|
||||
/*
|
||||
if (is_vert)
|
||||
{
|
||||
if (is_vert)
|
||||
vert_weight += static_cast<unsigned>(child->weight.get_value(area.height));
|
||||
else
|
||||
horz_weight += static_cast<unsigned>(child->weight.get_value(area.width));
|
||||
if (child_dv->height_percent >= 0)
|
||||
vert_weight += static_cast<unsigned>(child_dv->height_percent * area.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (child_dv->width_percent >= 0)
|
||||
horz_weight += static_cast<unsigned>(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<div_dockpane*>(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<std::unique_ptr<division>> 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);
|
||||
|
@ -198,7 +198,7 @@ namespace nana
|
||||
});
|
||||
|
||||
if (panels_.size() > 1)
|
||||
tabbar_.reset(new tabbar<int>(*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<form> container_;
|
||||
dockarea_caption caption_;
|
||||
std::deque<panel> panels_;
|
||||
std::unique_ptr<tabbar<int>> tabbar_;
|
||||
std::unique_ptr<tabbar_lite> tabbar_;
|
||||
|
||||
struct moves
|
||||
{
|
||||
|
@ -1275,8 +1275,6 @@ namespace nana
|
||||
#include <forward_list>
|
||||
namespace nana
|
||||
{
|
||||
namespace ng
|
||||
{
|
||||
namespace drawerbase
|
||||
{
|
||||
namespace tabbar_lite
|
||||
@ -1286,6 +1284,7 @@ namespace nana
|
||||
::std::string text;
|
||||
::nana::any value;
|
||||
::std::pair<int, int> 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user