new switchable field

This commit is contained in:
Jinhao 2018-03-13 11:15:29 +08:00
parent 6616b695e9
commit dbf898cc50

View File

@ -1,7 +1,7 @@
/*
* An Implementation of Place for Layout
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -58,7 +58,7 @@ namespace nana
{
div_start, div_end, splitter,
identifier, dock, fit, hfit, vfit, vert, grid, number, array, reparray,
weight, width, height, gap, margin, arrange, variable, repeated, min_px, max_px, left, right, top, bottom, undisplayed, invisible,
weight, width, height, gap, margin, arrange, variable, repeated, min_px, max_px, left, right, top, bottom, undisplayed, invisible, switchable,
collapse, parameters,
equal,
eof, error
@ -252,14 +252,6 @@ namespace nana
case 'd': return token::width;
}
}
else if ("dock" == idstr_)
return token::dock;
else if ("fit" == idstr_)
return token::fit;
else if ("vertical" == idstr_ || "vert" == idstr_)
return token::vert;
else if ("variable" == idstr_ || "repeated" == idstr_)
return ('v' == idstr_[0] ? token::variable : token::repeated);
else if ("arrange" == idstr_ || "hfit" == idstr_ || "vfit" == idstr_ || "gap" == idstr_)
{
auto ch = idstr_[0];
@ -287,16 +279,54 @@ namespace nana
_m_throw_error("a parameter list is required after 'collapse'");
return token::collapse;
}
else if ("left" == idstr_ || "right" == idstr_ || "top" == idstr_ || "bottom" == idstr_ || "undisplayed" == idstr_ || "invisible" == idstr_)
else if (!idstr_.empty())
{
switch (idstr_.front())
{
case 'l': return token::left;
case 'r': return token::right;
case 't': return token::top;
case 'b': return token::bottom;
case 'u': return token::undisplayed;
case 'i': return token::invisible;
case 'b':
if ("bottom" == idstr_)
return token::bottom;
break;
case 'd':
if ("dock" == idstr_)
return token::dock;
break;
case 'f':
if ("fit" == idstr_)
return token::fit;
break;
case 'i':
if ("invisible" == idstr_)
return token::invisible;
break;
case 'l':
if ("left" == idstr_)
return token::left;
break;
case 'r':
if ("repeated" == idstr_)
return token::repeated;
else if ("right" == idstr_)
return token::right;
break;
case 's':
if ("switchable" == idstr_)
return token::switchable;
break;
case 't':
if ("top" == idstr_)
return token::top;
break;
case 'u':
if ("undisplayed" == idstr_)
return token::undisplayed;
break;
case 'v':
if ("vertical" == idstr_ || "vert" == idstr_)
return token::vert;
else if ("variable" == idstr_)
return token::variable;
break;
}
}
@ -579,6 +609,7 @@ namespace nana
class div_splitter;
class div_dock;
class div_dockpane;
class div_switchable;
window window_handle{nullptr};
event_handle event_size_handle{nullptr};
@ -747,7 +778,7 @@ namespace nana
class place::implement::division
{
public:
enum class kind{ arrange, vertical_arrange, grid, splitter, dock, dockpane};
enum class kind{ arrange, vertical_arrange, grid, splitter, dock, dockpane, switchable};
using token = place_parts::tokenizer::token;
division(kind k, std::string&& n) noexcept
@ -981,6 +1012,19 @@ namespace nana
div_next->set_display(true);
}
}
if (display)
{
//If the field is a child of switchable field, hides other child fields.
if (this->div_owner && (kind::switchable == this->div_owner->kind_of_division))
{
for (auto & child : this->div_owner->children)
{
if (child.get() != this)
child->set_display(false);
}
}
}
}
bool is_back(const division* div) const noexcept
@ -2539,6 +2583,43 @@ namespace nana
implement * const impl_;
};
class place::implement::div_switchable
: public division
{
public:
div_switchable(std::string && name, implement* impl) noexcept
: division(kind::switchable, std::move(name)), impl_(impl)
{}
private:
void collocate(window wd) override
{
division * div = nullptr;
for (auto & child : children)
{
if (child->display)
{
div = child.get();
div->field_area = this->margin_area();
div->collocate(wd);
break;
}
}
//Hide other child fields.
rectangle empty_r{ this->margin_area().position() , size{ 0, 0 } };
for (auto & child : children)
{
if (child.get() != div)
{
child->field_area = empty_r;
child->collocate(wd);
}
}
}
private:
implement * const impl_;
};
place::implement::~implement()
{
API::umake_event(event_size_handle);
@ -2680,6 +2761,9 @@ namespace nana
children.emplace_back(std::move(div));
}
break;
case token::switchable:
div_type = token::switchable;
break;
case token::vert:
div_type = tk;
break;
@ -2850,6 +2934,9 @@ namespace nana
case token::dock:
div.reset(new div_dock(std::move(name), this));
break;
case token::switchable:
div.reset(new div_switchable(std::move(name), this));
break;
default:
throw std::invalid_argument("nana.place: invalid division type.");
}