improve dockpane factory
This commit is contained in:
parent
44a067fd51
commit
5d2127e613
@ -127,15 +127,16 @@ namespace nana
|
|||||||
|
|
||||||
/// Add a panel factory
|
/// Add a panel factory
|
||||||
template<typename Panel, typename ...Args>
|
template<typename Panel, typename ...Args>
|
||||||
void dock(const std::string& dockname, Args&& ... args)
|
place& dock(const std::string& dockname, const std::string& factory_name, Args&& ... args)
|
||||||
{
|
{
|
||||||
dock(dockname, std::bind([](window parent, Args & ... args)
|
return dock(dockname, factory_name, std::bind([](window parent, Args & ... args)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<widget>(new Panel(parent, std::forward<Args>(args)...));
|
return std::unique_ptr<widget>(new Panel(parent, std::forward<Args>(args)...));
|
||||||
}, std::placeholders::_1, args...));
|
}, std::placeholders::_1, args...));
|
||||||
}
|
}
|
||||||
|
|
||||||
void dock(const std::string& dockname, std::function<std::unique_ptr<widget>(window)> factory);
|
place& dock(const std::string& dockname, std::string factory_name, std::function<std::unique_ptr<widget>(window)> factory);
|
||||||
|
place& dock_create(const std::string& factory);
|
||||||
private:
|
private:
|
||||||
implement * impl_;
|
implement * impl_;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -450,6 +450,7 @@ namespace nana
|
|||||||
std::unique_ptr<division> root_division;
|
std::unique_ptr<division> root_division;
|
||||||
std::map<std::string, field_gather*> fields;
|
std::map<std::string, field_gather*> fields;
|
||||||
std::map<std::string, field_dock*> docks;
|
std::map<std::string, field_dock*> docks;
|
||||||
|
std::map<std::string, field_dock*> dock_factoris;
|
||||||
|
|
||||||
//A temporary pointer used to refer to a specified div object which
|
//A temporary pointer used to refer to a specified div object which
|
||||||
//will be deleted in modification process.
|
//will be deleted in modification process.
|
||||||
@ -597,8 +598,9 @@ namespace nana
|
|||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
div_dockpane * attached{ nullptr }; //attached div object
|
div_dockpane * attached{ nullptr }; //attached div object
|
||||||
place_parts::dockarea dockarea; //the dockable widget
|
std::unique_ptr<place_parts::dockarea> dockarea; //the dockable widget
|
||||||
|
std::map<std::string, std::function<std::unique_ptr<widget>(window)>> factories; //factories for dockpane
|
||||||
};//end class field_dock
|
};//end class field_dock
|
||||||
|
|
||||||
|
|
||||||
@ -1559,13 +1561,14 @@ namespace nana
|
|||||||
impl_ptr_{impl}
|
impl_ptr_{impl}
|
||||||
{
|
{
|
||||||
dir = pane_dir;
|
dir = pane_dir;
|
||||||
|
this->display = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
~div_dockpane()
|
~div_dockpane()
|
||||||
{
|
{
|
||||||
if (dockable_field)
|
if (dockable_field)
|
||||||
{
|
{
|
||||||
dockable_field->dockarea.close();
|
dockable_field->dockarea.reset();
|
||||||
dockable_field->attached = nullptr;
|
dockable_field->attached = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1586,6 +1589,8 @@ namespace nana
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto & dockarea = dockable_field->dockarea;
|
auto & dockarea = dockable_field->dockarea;
|
||||||
|
|
||||||
|
/*
|
||||||
if (!created_)
|
if (!created_)
|
||||||
{
|
{
|
||||||
created_ = true;
|
created_ = true;
|
||||||
@ -1594,6 +1599,10 @@ namespace nana
|
|||||||
|
|
||||||
if (!dockarea.empty() && !dockarea.floating())
|
if (!dockarea.empty() && !dockarea.floating())
|
||||||
dockarea.move(this->field_area);
|
dockarea.move(this->field_area);
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (dockarea && !dockarea->floating())
|
||||||
|
dockarea->move(this->field_area);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
//Implement dock_notifier_interface
|
//Implement dock_notifier_interface
|
||||||
@ -1710,8 +1719,8 @@ namespace nana
|
|||||||
|
|
||||||
void notify_move_stopped()
|
void notify_move_stopped()
|
||||||
{
|
{
|
||||||
if (_m_dockable() && dockable_field)
|
if (_m_dockable() && dockable_field && dockable_field->dockarea)
|
||||||
dockable_field->dockarea.dock();
|
dockable_field->dockarea->dock();
|
||||||
|
|
||||||
indicator_.docker.reset();
|
indicator_.docker.reset();
|
||||||
}
|
}
|
||||||
@ -2514,7 +2523,7 @@ namespace nana
|
|||||||
|
|
||||||
for (auto& e : docks_to_be_closed)
|
for (auto& e : docks_to_be_closed)
|
||||||
{
|
{
|
||||||
e.second->dockarea.close();
|
e.second->dockarea.reset();
|
||||||
e.second->attached->dockable_field = nullptr;
|
e.second->attached->dockable_field = nullptr;
|
||||||
e.second->attached = nullptr;
|
e.second->attached = nullptr;
|
||||||
}
|
}
|
||||||
@ -2747,7 +2756,7 @@ namespace nana
|
|||||||
return field(name);
|
return field(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void place::dock(const std::string& name, std::function<std::unique_ptr<widget>(window)> factory)
|
place& place::dock(const std::string& name, std::string factory_name, std::function<std::unique_ptr<widget>(window)> factory)
|
||||||
{
|
{
|
||||||
//check the name, it throws std::invalid_argument
|
//check the name, it throws std::invalid_argument
|
||||||
//if name violate the naming convention.
|
//if name violate the naming convention.
|
||||||
@ -2757,7 +2766,16 @@ namespace nana
|
|||||||
if (!dock_ptr)
|
if (!dock_ptr)
|
||||||
dock_ptr = new implement::field_dock;
|
dock_ptr = new implement::field_dock;
|
||||||
|
|
||||||
dock_ptr->dockarea.add_factory(std::move(factory));
|
//Register the factory if it has a name
|
||||||
|
if (!factory_name.empty())
|
||||||
|
{
|
||||||
|
auto i = impl_->dock_factoris.find(factory_name);
|
||||||
|
if (i != impl_->dock_factoris.end())
|
||||||
|
throw std::invalid_argument("nana::place - the specified factory name(" + factory_name + ") already exists");
|
||||||
|
|
||||||
|
impl_->dock_factoris[factory_name] = dock_ptr;
|
||||||
|
dock_ptr->factories[factory_name].swap(factory);
|
||||||
|
}
|
||||||
|
|
||||||
auto div = dynamic_cast<implement::div_dockpane*>(impl_->search_div_name(impl_->root_division.get(), name));
|
auto div = dynamic_cast<implement::div_dockpane*>(impl_->search_div_name(impl_->root_division.get(), name));
|
||||||
if (div)
|
if (div)
|
||||||
@ -2765,6 +2783,45 @@ namespace nana
|
|||||||
dock_ptr->attached = div;
|
dock_ptr->attached = div;
|
||||||
div->dockable_field = dock_ptr;
|
div->dockable_field = dock_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Create the pane if it has not a name
|
||||||
|
if (factory_name.empty())
|
||||||
|
{
|
||||||
|
dock_ptr->attached->set_display(true);
|
||||||
|
impl_->collocate();
|
||||||
|
|
||||||
|
if (!dock_ptr->dockarea)
|
||||||
|
{
|
||||||
|
dock_ptr->dockarea.reset(new ::nana::place_parts::dockarea);
|
||||||
|
dock_ptr->dockarea->create(impl_->window_handle, dock_ptr->attached);
|
||||||
|
dock_ptr->dockarea->move(dock_ptr->attached->field_area);
|
||||||
|
}
|
||||||
|
dock_ptr->dockarea->add_pane(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
place& place::dock_create(const std::string& factory)
|
||||||
|
{
|
||||||
|
auto i = impl_->dock_factoris.find(factory);
|
||||||
|
if (i == impl_->dock_factoris.end())
|
||||||
|
throw std::invalid_argument("nana::place - invalid factory name(" + factory + ")");
|
||||||
|
|
||||||
|
auto dock_ptr = i->second;
|
||||||
|
dock_ptr->attached->set_display(true);
|
||||||
|
impl_->collocate();
|
||||||
|
|
||||||
|
if (!dock_ptr->dockarea)
|
||||||
|
{
|
||||||
|
dock_ptr->dockarea.reset(new ::nana::place_parts::dockarea);
|
||||||
|
dock_ptr->dockarea->create(impl_->window_handle, dock_ptr->attached);
|
||||||
|
dock_ptr->dockarea->move(dock_ptr->attached->field_area);
|
||||||
|
}
|
||||||
|
|
||||||
|
dock_ptr->dockarea->add_pane(i->second->factories[factory]);
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
//end class place
|
//end class place
|
||||||
}//end namespace nana
|
}//end namespace nana
|
||||||
|
|||||||
@ -148,12 +148,7 @@ namespace nana
|
|||||||
|
|
||||||
struct panel
|
struct panel
|
||||||
{
|
{
|
||||||
factory factory_fn;
|
|
||||||
std::unique_ptr<widget> widget_ptr;
|
std::unique_ptr<widget> widget_ptr;
|
||||||
|
|
||||||
panel(factory && fn)
|
|
||||||
: factory_fn(std::move(fn))
|
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
void create(window parent, place_parts::dock_notifier_interface* notifier)
|
void create(window parent, place_parts::dock_notifier_interface* notifier)
|
||||||
@ -229,29 +224,49 @@ namespace nana
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (panels_.size() > 1)
|
|
||||||
tabbar_.reset(new tabbar_lite(*this));
|
|
||||||
|
|
||||||
std::size_t pos = 0;
|
|
||||||
for (auto & pn : panels_)
|
|
||||||
{
|
|
||||||
if (!pn.widget_ptr)
|
|
||||||
{
|
|
||||||
pn.widget_ptr = pn.factory_fn(*this);
|
|
||||||
if (tabbar_)
|
|
||||||
{
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_factory(factory && fn)
|
void add_pane(factory & fn)
|
||||||
{
|
{
|
||||||
panels_.emplace_back(std::move(fn));
|
rectangle r{ point(), this->size()};
|
||||||
|
|
||||||
|
//get a rectangle excluding caption
|
||||||
|
r.y = 20;
|
||||||
|
if (r.height > 20)
|
||||||
|
r.height -= 20;
|
||||||
|
else
|
||||||
|
r.height = 0;
|
||||||
|
|
||||||
|
if (!tabbar_ && panels_.size() > 0)
|
||||||
|
{
|
||||||
|
tabbar_.reset(new tabbar_lite(*this));
|
||||||
|
tabbar_->move({ 0, r.bottom() - 20, r.width, 20 });
|
||||||
|
r.height -= 20;
|
||||||
|
|
||||||
|
std::size_t pos = 0;
|
||||||
|
for (auto & pn : panels_)
|
||||||
|
{
|
||||||
|
tabbar_->push_back(::nana::charset(pn.widget_ptr->caption()));
|
||||||
|
tabbar_->attach(pos++, *pn.widget_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto wdg = fn(*this);
|
||||||
|
|
||||||
|
if (tabbar_)
|
||||||
|
{
|
||||||
|
tabbar_->push_back(::nana::charset(wdg->caption()));
|
||||||
|
tabbar_->attach(panels_.size(), *wdg);
|
||||||
|
}
|
||||||
|
|
||||||
|
panels_.emplace_back();
|
||||||
|
panels_.back().widget_ptr.swap(wdg);
|
||||||
|
|
||||||
|
for (auto & pn : panels_)
|
||||||
|
{
|
||||||
|
if (pn.widget_ptr)
|
||||||
|
pn.widget_ptr->move(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void float_away(const ::nana::point& move_pos)
|
void float_away(const ::nana::point& move_pos)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user