improve dockpane factory
This commit is contained in:
parent
44a067fd51
commit
5d2127e613
@ -127,15 +127,16 @@ namespace nana
|
||||
|
||||
/// Add a panel factory
|
||||
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)...));
|
||||
}, 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:
|
||||
implement * impl_;
|
||||
};
|
||||
|
||||
@ -450,6 +450,7 @@ namespace nana
|
||||
std::unique_ptr<division> root_division;
|
||||
std::map<std::string, field_gather*> fields;
|
||||
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
|
||||
//will be deleted in modification process.
|
||||
@ -597,8 +598,9 @@ namespace nana
|
||||
{
|
||||
|
||||
public:
|
||||
div_dockpane * attached{ nullptr }; //attached div object
|
||||
place_parts::dockarea dockarea; //the dockable widget
|
||||
div_dockpane * attached{ nullptr }; //attached div object
|
||||
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
|
||||
|
||||
|
||||
@ -1559,13 +1561,14 @@ namespace nana
|
||||
impl_ptr_{impl}
|
||||
{
|
||||
dir = pane_dir;
|
||||
this->display = false;
|
||||
}
|
||||
|
||||
~div_dockpane()
|
||||
{
|
||||
if (dockable_field)
|
||||
{
|
||||
dockable_field->dockarea.close();
|
||||
dockable_field->dockarea.reset();
|
||||
dockable_field->attached = nullptr;
|
||||
}
|
||||
}
|
||||
@ -1586,6 +1589,8 @@ namespace nana
|
||||
}
|
||||
|
||||
auto & dockarea = dockable_field->dockarea;
|
||||
|
||||
/*
|
||||
if (!created_)
|
||||
{
|
||||
created_ = true;
|
||||
@ -1594,6 +1599,10 @@ namespace nana
|
||||
|
||||
if (!dockarea.empty() && !dockarea.floating())
|
||||
dockarea.move(this->field_area);
|
||||
*/
|
||||
|
||||
if (dockarea && !dockarea->floating())
|
||||
dockarea->move(this->field_area);
|
||||
}
|
||||
private:
|
||||
//Implement dock_notifier_interface
|
||||
@ -1710,8 +1719,8 @@ namespace nana
|
||||
|
||||
void notify_move_stopped()
|
||||
{
|
||||
if (_m_dockable() && dockable_field)
|
||||
dockable_field->dockarea.dock();
|
||||
if (_m_dockable() && dockable_field && dockable_field->dockarea)
|
||||
dockable_field->dockarea->dock();
|
||||
|
||||
indicator_.docker.reset();
|
||||
}
|
||||
@ -2514,7 +2523,7 @@ namespace nana
|
||||
|
||||
for (auto& e : docks_to_be_closed)
|
||||
{
|
||||
e.second->dockarea.close();
|
||||
e.second->dockarea.reset();
|
||||
e.second->attached->dockable_field = nullptr;
|
||||
e.second->attached = nullptr;
|
||||
}
|
||||
@ -2747,7 +2756,7 @@ namespace nana
|
||||
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
|
||||
//if name violate the naming convention.
|
||||
@ -2757,7 +2766,16 @@ namespace nana
|
||||
if (!dock_ptr)
|
||||
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));
|
||||
if (div)
|
||||
@ -2765,6 +2783,45 @@ namespace nana
|
||||
dock_ptr->attached = div;
|
||||
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 namespace nana
|
||||
|
||||
@ -148,12 +148,7 @@ namespace nana
|
||||
|
||||
struct panel
|
||||
{
|
||||
factory factory_fn;
|
||||
std::unique_ptr<widget> widget_ptr;
|
||||
|
||||
panel(factory && fn)
|
||||
: factory_fn(std::move(fn))
|
||||
{}
|
||||
};
|
||||
public:
|
||||
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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user