code refine
This commit is contained in:
@@ -15,7 +15,6 @@
|
|||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <deque>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <nana/push_ignore_diagnostic>
|
#include <nana/push_ignore_diagnostic>
|
||||||
#include <nana/deploy.hpp>
|
#include <nana/deploy.hpp>
|
||||||
@@ -57,7 +56,7 @@ namespace nana
|
|||||||
enum class token
|
enum class token
|
||||||
{
|
{
|
||||||
div_start, div_end, splitter,
|
div_start, div_end, splitter,
|
||||||
identifier, dock, fit, vert, grid, number, array, reparray,
|
identifier, dock, fit, fit_s, vert, grid, number, array, reparray,
|
||||||
weight, gap, margin, arrange, variable, repeated, min_px, max_px, left, right, top, bottom, undisplayed, invisible,
|
weight, gap, margin, arrange, variable, repeated, min_px, max_px, left, right, top, bottom, undisplayed, invisible,
|
||||||
collapse, parameters,
|
collapse, parameters,
|
||||||
equal,
|
equal,
|
||||||
@@ -73,7 +72,7 @@ namespace nana
|
|||||||
return idstr_;
|
return idstr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
number_t number() const
|
const number_t& number() const
|
||||||
{
|
{
|
||||||
return number_;
|
return number_;
|
||||||
}
|
}
|
||||||
@@ -98,11 +97,6 @@ namespace nana
|
|||||||
return (sp_ - divstr_);
|
return (sp_ - divstr_);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string pos_str() const
|
|
||||||
{
|
|
||||||
return std::to_string(pos());
|
|
||||||
}
|
|
||||||
|
|
||||||
token read()
|
token read()
|
||||||
{
|
{
|
||||||
sp_ = _m_eat_whitespace(sp_);
|
sp_ = _m_eat_whitespace(sp_);
|
||||||
@@ -255,6 +249,8 @@ namespace nana
|
|||||||
return token::dock;
|
return token::dock;
|
||||||
else if ("fit" == idstr_)
|
else if ("fit" == idstr_)
|
||||||
return token::fit;
|
return token::fit;
|
||||||
|
else if ("fit_s" == idstr_)
|
||||||
|
return token::fit_s;
|
||||||
else if ("vertical" == idstr_ || "vert" == idstr_)
|
else if ("vertical" == idstr_ || "vert" == idstr_)
|
||||||
return token::vert;
|
return token::vert;
|
||||||
else if ("variable" == idstr_ || "repeated" == idstr_)
|
else if ("variable" == idstr_ || "repeated" == idstr_)
|
||||||
@@ -434,6 +430,16 @@ namespace nana
|
|||||||
}; //end class tokenizer
|
}; //end class tokenizer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_vert_dir(::nana::direction dir)
|
||||||
|
{
|
||||||
|
return (dir == ::nana::direction::north || dir == ::nana::direction::south);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int horz_point(bool vert, const point& pos)
|
||||||
|
{
|
||||||
|
return (vert ? pos.y : pos.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool is_idchar(int ch) noexcept
|
static bool is_idchar(int ch) noexcept
|
||||||
{
|
{
|
||||||
@@ -640,18 +646,31 @@ namespace nana
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
//Listen to destroy of a window
|
void _m_insert_widget(window wd, bool to_fasten)
|
||||||
//It will delete the element and recollocate when the window destroyed.
|
|
||||||
event_handle _m_make_destroy(window wd)
|
|
||||||
{
|
{
|
||||||
return API::events(wd).destroy.connect([this, wd](const arg_destroy&)
|
if (API::empty_window(wd))
|
||||||
|
throw std::invalid_argument("Place: An invalid window handle.");
|
||||||
|
|
||||||
|
if (API::get_parent_window(wd) != place_ptr_->window_handle())
|
||||||
|
throw std::invalid_argument("Place: the window is not a child of place bind window");
|
||||||
|
|
||||||
|
//Listen to destroy of a window
|
||||||
|
//It will delete the element and recollocate when the window destroyed.
|
||||||
|
auto evt = API::events(wd).destroy.connect([this, to_fasten](const arg_destroy& arg)
|
||||||
{
|
{
|
||||||
if (erase_element(elements, wd))
|
if (!to_fasten)
|
||||||
{
|
{
|
||||||
if (!API::is_destroying(API::get_parent_window(wd)))
|
if (erase_element(elements, arg.window_handle))
|
||||||
place_ptr_->collocate();
|
{
|
||||||
|
if (!API::is_destroying(API::get_parent_window(arg.window_handle)))
|
||||||
|
place_ptr_->collocate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
erase_element(fastened, arg.window_handle);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
(to_fasten ? &fastened : &elements)->emplace_back(wd, evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
field_interface& operator<<(const char* label_text) override
|
field_interface& operator<<(const char* label_text) override
|
||||||
@@ -666,33 +685,13 @@ namespace nana
|
|||||||
|
|
||||||
field_interface& operator<<(window wd) override
|
field_interface& operator<<(window wd) override
|
||||||
{
|
{
|
||||||
if (API::empty_window(wd))
|
_m_insert_widget(wd, false);
|
||||||
throw std::invalid_argument("Place: An invalid window handle.");
|
|
||||||
|
|
||||||
if (API::get_parent_window(wd) != place_ptr_->window_handle())
|
|
||||||
throw std::invalid_argument("Place: the window is not a child of place bind window");
|
|
||||||
|
|
||||||
auto evt = _m_make_destroy(wd);
|
|
||||||
elements.emplace_back(wd, evt);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
field_interface& fasten(window wd) override
|
field_interface& fasten(window wd) override
|
||||||
{
|
{
|
||||||
if (API::empty_window(wd))
|
_m_insert_widget(wd, true);
|
||||||
throw std::invalid_argument("Place: An invalid window handle.");
|
|
||||||
|
|
||||||
if (API::get_parent_window(wd) != place_ptr_->window_handle())
|
|
||||||
throw std::invalid_argument("Place: the window is not a child of place bind window");
|
|
||||||
|
|
||||||
//Listen to destroy of a window. The deleting a fastened window
|
|
||||||
//does not change the layout.
|
|
||||||
auto evt = API::events(wd).destroy.connect([this](const arg_destroy& arg)
|
|
||||||
{
|
|
||||||
erase_element(fastened, arg.window_handle);
|
|
||||||
});
|
|
||||||
|
|
||||||
fastened.emplace_back(wd, evt);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,6 +718,12 @@ namespace nana
|
|||||||
};//end class field_dock
|
};//end class field_dock
|
||||||
|
|
||||||
|
|
||||||
|
enum class fit_policy
|
||||||
|
{
|
||||||
|
none, //Doesn't fit the content
|
||||||
|
both, //Fits both width and height of content
|
||||||
|
single //Fits only width or height of content
|
||||||
|
};
|
||||||
|
|
||||||
class place::implement::division
|
class place::implement::division
|
||||||
{
|
{
|
||||||
@@ -773,7 +778,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
auto child_floor = child->calc_weight_floor();
|
auto child_floor = child->calc_weight_floor();
|
||||||
|
|
||||||
if(child->weight.kind_of() == number_t::kind::percent)
|
if(child->is_percent())
|
||||||
{
|
{
|
||||||
ratio += child->weight.real();
|
ratio += child->weight.real();
|
||||||
}
|
}
|
||||||
@@ -785,24 +790,23 @@ namespace nana
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto const vert = (this->div_owner && (this->div_owner->kind_of_division == kind::vertical_arrange));
|
auto const vert = (this->div_owner && (this->div_owner->kind_of_division == kind::vertical_arrange));
|
||||||
|
|
||||||
double& fv = (vert ? floor.second : floor.first);
|
double& fv = (vert ? floor.second : floor.first);
|
||||||
|
|
||||||
if(ratio > 0.001)
|
if((ratio > 0.001) && (fv > 0))
|
||||||
{
|
fv /= ratio;
|
||||||
if(fv > 0)
|
|
||||||
fv = fv / ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->weight.empty())
|
if (!this->weight.empty())
|
||||||
{
|
{
|
||||||
if (this->weight.kind_of() != number_t::kind::percent)
|
if(!this->is_percent())
|
||||||
fv = this->weight.real();
|
fv = this->weight.real();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (this->fit_content)
|
if (fit_policy::none != this->fit)
|
||||||
{
|
{
|
||||||
|
unsigned limited_px = 0;
|
||||||
|
bool limit_width = false;
|
||||||
|
|
||||||
std::size_t fit_count = 0;
|
std::size_t fit_count = 0;
|
||||||
unsigned max_value = 0;
|
unsigned max_value = 0;
|
||||||
for (auto & elm : this->field->elements)
|
for (auto & elm : this->field->elements)
|
||||||
@@ -812,17 +816,11 @@ namespace nana
|
|||||||
{
|
{
|
||||||
++fit_count;
|
++fit_count;
|
||||||
if (vert)
|
if (vert)
|
||||||
{
|
|
||||||
floor.second += extent->second.height;
|
floor.second += extent->second.height;
|
||||||
if (extent->second.width > max_value)
|
|
||||||
max_value = extent->second.width;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
floor.first += extent->second.width;
|
floor.first += extent->second.width;
|
||||||
if (extent->second.height > max_value)
|
|
||||||
max_value = extent->second.height;
|
max_value = (std::max)(max_value, (vert ? extent->second.width : extent->second.height));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1006,7 +1004,7 @@ namespace nana
|
|||||||
kind kind_of_division;
|
kind kind_of_division;
|
||||||
bool display{ true };
|
bool display{ true };
|
||||||
bool visible{ true };
|
bool visible{ true };
|
||||||
bool fit_content{ false };
|
fit_policy fit{ fit_policy::none };
|
||||||
::nana::direction dir{::nana::direction::west};
|
::nana::direction dir{::nana::direction::west};
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<std::unique_ptr<division>> children;
|
std::vector<std::unique_ptr<division>> children;
|
||||||
@@ -1109,27 +1107,21 @@ namespace nana
|
|||||||
|
|
||||||
bool moved = false;
|
bool moved = false;
|
||||||
unsigned px = 0;
|
unsigned px = 0;
|
||||||
if (this->fit_content)
|
|
||||||
|
auto move_r = element_r.result();
|
||||||
|
if (fit_policy::both == this->fit)
|
||||||
{
|
{
|
||||||
auto extent = API::content_extent(el.handle, 0, false);
|
auto extent = API::content_extent(el.handle, 0, false);
|
||||||
if (extent)
|
if (extent)
|
||||||
{
|
{
|
||||||
auto r = element_r.result();
|
move_r.dimension(extent->second);
|
||||||
r.dimension(extent->second);
|
|
||||||
|
|
||||||
if (vert)
|
if (vert)
|
||||||
{
|
move_r.x += place_parts::differ(area_margined.width, move_r.width) / 2;
|
||||||
if (area_margined.width > r.width)
|
|
||||||
r.x += (area_margined.width - r.width) / 2;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
move_r.y += place_parts::differ(area_margined.height, move_r.height) / 2;
|
||||||
if (area_margined.height > r.height)
|
|
||||||
r.y += (area_margined.height - r.height) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
API::move_window(el.handle, r);
|
px = (vert ? move_r.height : move_r.width);
|
||||||
px = (vert ? r.height : r.width);
|
|
||||||
moved = true;
|
moved = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1138,9 +1130,11 @@ namespace nana
|
|||||||
{
|
{
|
||||||
px = calc_number(arrange_.at(index), area_px, adjustable_px, precise_px);
|
px = calc_number(arrange_.at(index), area_px, adjustable_px, precise_px);
|
||||||
element_r.w_ref() = px;
|
element_r.w_ref() = px;
|
||||||
API::move_window(el.handle, element_r.result());
|
move_r = element_r.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
API::move_window(el.handle, move_r);
|
||||||
|
|
||||||
if (index + 1 < field->elements.size())
|
if (index + 1 < field->elements.size())
|
||||||
position += (px + calc_number(gap.at(index), area_px, 0, precise_px));
|
position += (px + calc_number(gap.at(index), area_px, 0, precise_px));
|
||||||
|
|
||||||
@@ -1260,7 +1254,7 @@ namespace nana
|
|||||||
return reached_mins;
|
return reached_mins;
|
||||||
}
|
}
|
||||||
|
|
||||||
double _m_revise_adjustable(std::pair<unsigned, std::size_t>& fa, unsigned area_px) noexcept
|
double _m_revise_adjustable(std::pair<unsigned, std::size_t>& fa, unsigned area_px)
|
||||||
{
|
{
|
||||||
if (fa.first >= area_px || 0 == fa.second)
|
if (fa.first >= area_px || 0 == fa.second)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1402,126 +1396,120 @@ namespace nana
|
|||||||
if (!field || !(visible && display))
|
if (!field || !(visible && display))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto area = margin_area();
|
auto const area = margin_area();
|
||||||
|
auto const gap_size = static_cast<unsigned>(gap.at(0).get_value(area.width)); //gap_size is 0 if gap isn't specified
|
||||||
unsigned gap_size = 0;
|
|
||||||
auto gap_number = gap.at(0);
|
|
||||||
if (!gap_number.empty())
|
|
||||||
gap_size = static_cast<unsigned>(gap_number.get_value(area.width));
|
|
||||||
|
|
||||||
//When the amount pixels of gaps is out of the area bound.
|
|
||||||
if ((gap_size * dimension.first >= area.width) || (gap_size * dimension.second >= area.height))
|
|
||||||
{
|
|
||||||
for (auto & el : field->elements)
|
|
||||||
API::window_size(el.handle, size{ 0, 0 });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto i = field->elements.cbegin();
|
auto i = field->elements.cbegin();
|
||||||
auto const end = field->elements.cend();
|
auto const end = field->elements.cend();
|
||||||
if (dimension.first <= 1 && dimension.second <= 1)
|
|
||||||
|
//The total gaps must not beyond the bound of the area.
|
||||||
|
if ((gap_size * dimension.first < area.width) && (gap_size * dimension.second < area.height))
|
||||||
{
|
{
|
||||||
auto n_of_wd = field->elements.size();
|
if (dimension.first <= 1 && dimension.second <= 1)
|
||||||
std::size_t edge;
|
|
||||||
switch (n_of_wd)
|
|
||||||
{
|
{
|
||||||
case 0:
|
auto n_of_wd = field->elements.size();
|
||||||
case 1:
|
std::size_t edge;
|
||||||
edge = 1; break;
|
switch (n_of_wd)
|
||||||
case 2: case 3: case 4:
|
|
||||||
edge = 2; break;
|
|
||||||
default:
|
|
||||||
edge = static_cast<std::size_t>(std::sqrt(n_of_wd));
|
|
||||||
if ((edge * edge) < n_of_wd) ++edge;
|
|
||||||
}
|
|
||||||
|
|
||||||
double y = area.y;
|
|
||||||
double block_w = area.width / double(edge);
|
|
||||||
double block_h = area.height / double((n_of_wd / edge) + (n_of_wd % edge ? 1 : 0));
|
|
||||||
unsigned uns_block_w = static_cast<unsigned>(block_w);
|
|
||||||
unsigned uns_block_h = static_cast<unsigned>(block_h);
|
|
||||||
unsigned height = (uns_block_h > gap_size ? uns_block_h - gap_size : uns_block_h);
|
|
||||||
|
|
||||||
std::size_t arr_pos = 0;
|
|
||||||
for (std::size_t u = 0; (u < edge && i != end); ++u)
|
|
||||||
{
|
|
||||||
double x = area.x;
|
|
||||||
for (std::size_t v = 0; (v < edge && i != end); ++v, ++i)
|
|
||||||
{
|
{
|
||||||
unsigned value = 0;
|
case 0:
|
||||||
auto arr = arrange_.at(arr_pos++);
|
case 1:
|
||||||
|
edge = 1; break;
|
||||||
if (arr.empty())
|
case 2: case 3: case 4:
|
||||||
value = static_cast<decltype(value)>(block_w);
|
edge = 2; break;
|
||||||
else
|
default:
|
||||||
value = static_cast<decltype(value)>(arr.get_value(static_cast<int>(area.width)));
|
edge = static_cast<std::size_t>(std::sqrt(n_of_wd));
|
||||||
|
if ((edge * edge) < n_of_wd) ++edge;
|
||||||
unsigned width = (value > uns_block_w ? uns_block_w : value);
|
|
||||||
if (width > gap_size) width -= gap_size;
|
|
||||||
API::move_window(i->handle, rectangle{ static_cast<int>(x), static_cast<int>(y), width, height });
|
|
||||||
x += block_w;
|
|
||||||
}
|
|
||||||
y += block_h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
double block_w = int(area.width - gap_size * (dimension.first - 1)) / double(dimension.first);
|
|
||||||
double block_h = int(area.height - gap_size * (dimension.second - 1)) / double(dimension.second);
|
|
||||||
|
|
||||||
std::unique_ptr<char[]> table_ptr{ new char[dimension.first * dimension.second] };
|
|
||||||
char *table = table_ptr.get();
|
|
||||||
std::memset(table, 0, dimension.first * dimension.second);
|
|
||||||
|
|
||||||
std::size_t lbp = 0;
|
|
||||||
|
|
||||||
double precise_h = 0;
|
|
||||||
for (std::size_t u = 0; (u < dimension.second && i != end); ++u)
|
|
||||||
{
|
|
||||||
auto const block_height_px = static_cast<unsigned>(block_h + precise_h);
|
|
||||||
precise_h = (block_h + precise_h) - block_height_px;
|
|
||||||
|
|
||||||
double precise_w = 0;
|
|
||||||
for (std::size_t v = 0; (v < dimension.first && i != end); ++v)
|
|
||||||
{
|
|
||||||
if (table[v + lbp])
|
|
||||||
{
|
|
||||||
precise_w += block_w;
|
|
||||||
precise_w -= static_cast<int>(precise_w);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<unsigned, unsigned> room{ 1, 1 };
|
|
||||||
_m_find_collapse(static_cast<int>(v), static_cast<int>(u), room);
|
|
||||||
|
|
||||||
int pos_x = area.x + static_cast<int>(v * (block_w + gap_size));
|
|
||||||
int pos_y = area.y + static_cast<int>(u * (block_h + gap_size));
|
|
||||||
|
|
||||||
unsigned result_h;
|
|
||||||
if (room.first <= 1 && room.second <= 1)
|
|
||||||
{
|
|
||||||
precise_w += block_w;
|
|
||||||
result_h = block_height_px;
|
|
||||||
table[v + lbp] = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
precise_w += block_w * room.first + (room.first - 1) * gap_size;
|
|
||||||
result_h = static_cast<unsigned>(block_h * room.second + precise_h + (room.second - 1) * gap_size);
|
|
||||||
|
|
||||||
for (unsigned y = 0; y < room.second; ++y)
|
|
||||||
for (unsigned x = 0; x < room.first; ++x)
|
|
||||||
table[v + x + lbp + y * dimension.first] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned result_w = static_cast<unsigned>(precise_w);
|
|
||||||
precise_w -= result_w;
|
|
||||||
|
|
||||||
API::move_window(i->handle, rectangle{ pos_x, pos_y, result_w, result_h });
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lbp += dimension.first;
|
double y = area.y;
|
||||||
|
const double block_w = area.width / double(edge);
|
||||||
|
const double block_h = area.height / double((n_of_wd / edge) + (n_of_wd % edge ? 1 : 0));
|
||||||
|
const unsigned uns_block_w = static_cast<unsigned>(block_w);
|
||||||
|
const unsigned uns_block_h = static_cast<unsigned>(block_h);
|
||||||
|
const unsigned height = (uns_block_h > gap_size ? uns_block_h - gap_size : uns_block_h);
|
||||||
|
|
||||||
|
std::size_t arr_pos = 0;
|
||||||
|
for (std::size_t u = 0; (u < edge && i != end); ++u)
|
||||||
|
{
|
||||||
|
double x = area.x;
|
||||||
|
for (std::size_t v = 0; (v < edge && i != end); ++v, ++i)
|
||||||
|
{
|
||||||
|
unsigned value = 0;
|
||||||
|
auto arr = arrange_.at(arr_pos++);
|
||||||
|
|
||||||
|
if (arr.empty())
|
||||||
|
value = static_cast<decltype(value)>(block_w);
|
||||||
|
else
|
||||||
|
value = static_cast<decltype(value)>(arr.get_value(static_cast<int>(area.width)));
|
||||||
|
|
||||||
|
unsigned width = (value > uns_block_w ? uns_block_w : value);
|
||||||
|
if (width > gap_size) width -= gap_size;
|
||||||
|
API::move_window(i->handle, rectangle{ static_cast<int>(x), static_cast<int>(y), width, height });
|
||||||
|
x += block_w;
|
||||||
|
}
|
||||||
|
y += block_h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const double block_w = int(area.width - gap_size * (dimension.first - 1)) / double(dimension.first);
|
||||||
|
const double block_h = int(area.height - gap_size * (dimension.second - 1)) / double(dimension.second);
|
||||||
|
|
||||||
|
std::unique_ptr<char[]> table_ptr{ new char[dimension.first * dimension.second] };
|
||||||
|
char *table = table_ptr.get();
|
||||||
|
std::memset(table, 0, dimension.first * dimension.second);
|
||||||
|
|
||||||
|
std::size_t lbp = 0;
|
||||||
|
|
||||||
|
double precise_h = 0;
|
||||||
|
for (std::size_t u = 0; (u < dimension.second && i != end); ++u)
|
||||||
|
{
|
||||||
|
auto const block_height_px = static_cast<unsigned>(block_h + precise_h);
|
||||||
|
precise_h = (block_h + precise_h) - block_height_px;
|
||||||
|
|
||||||
|
double precise_w = 0;
|
||||||
|
for (std::size_t v = 0; (v < dimension.first && i != end); ++v)
|
||||||
|
{
|
||||||
|
auto const epos = v + lbp;
|
||||||
|
if (table[epos])
|
||||||
|
{
|
||||||
|
precise_w += block_w;
|
||||||
|
precise_w -= static_cast<int>(precise_w);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<unsigned, unsigned> room{ 1, 1 };
|
||||||
|
_m_find_collapse(static_cast<int>(v), static_cast<int>(u), room);
|
||||||
|
|
||||||
|
const int pos_x = area.x + static_cast<int>(v * (block_w + gap_size));
|
||||||
|
const int pos_y = area.y + static_cast<int>(u * (block_h + gap_size));
|
||||||
|
|
||||||
|
unsigned result_h;
|
||||||
|
if (room.first <= 1 && room.second <= 1)
|
||||||
|
{
|
||||||
|
precise_w += block_w;
|
||||||
|
result_h = block_height_px;
|
||||||
|
table[epos] = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
precise_w += block_w * room.first + (room.first - 1) * gap_size;
|
||||||
|
result_h = static_cast<unsigned>(block_h * room.second + precise_h + (room.second - 1) * gap_size);
|
||||||
|
|
||||||
|
for (unsigned y = 0; y < room.second; ++y)
|
||||||
|
for (unsigned x = 0; x < room.first; ++x)
|
||||||
|
table[epos + x + y * dimension.first] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned result_w = static_cast<unsigned>(precise_w);
|
||||||
|
precise_w -= result_w;
|
||||||
|
|
||||||
|
API::move_window(i->handle, rectangle{ pos_x, pos_y, result_w, result_h });
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
lbp += dimension.first;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1598,6 +1586,9 @@ namespace nana
|
|||||||
if ((false == arg.left_button) && (mouse::left_button != arg.button))
|
if ((false == arg.left_button) && (mouse::left_button != arg.button))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
auto const leaf_left = _m_leaf(true);
|
||||||
|
auto const leaf_right = _m_leaf(false);
|
||||||
|
|
||||||
if (event_code::mouse_down == arg.evt_code)
|
if (event_code::mouse_down == arg.evt_code)
|
||||||
{
|
{
|
||||||
begin_point_ = splitter_.pos();
|
begin_point_ = splitter_.pos();
|
||||||
@@ -1605,8 +1596,8 @@ namespace nana
|
|||||||
auto px_ptr = &nana::rectangle::width;
|
auto px_ptr = &nana::rectangle::width;
|
||||||
|
|
||||||
//Use field_area of leaf, not margin_area. Otherwise splitter would be at wrong position
|
//Use field_area of leaf, not margin_area. Otherwise splitter would be at wrong position
|
||||||
auto area_left = _m_leaf_left()->field_area;
|
auto const area_left = leaf_left->field_area;
|
||||||
auto area_right = _m_leaf_right()->field_area;
|
auto const area_right = leaf_right->field_area;
|
||||||
|
|
||||||
if (nana::cursor::size_we != splitter_cursor_)
|
if (nana::cursor::size_we != splitter_cursor_)
|
||||||
{
|
{
|
||||||
@@ -1635,29 +1626,29 @@ namespace nana
|
|||||||
if(!grabbed_)
|
if(!grabbed_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const bool vert = (::nana::cursor::size_we != splitter_cursor_);
|
auto const vert = (::nana::cursor::size_we != splitter_cursor_);
|
||||||
auto area_px = rectangle_rotator(vert, div_owner->margin_area()).w();
|
auto const delta = horz_point(vert, splitter_.pos() - begin_point_);
|
||||||
int delta = (vert ? splitter_.pos().y - begin_point_.y : splitter_.pos().x - begin_point_.x);
|
|
||||||
|
|
||||||
const auto total_pixels = static_cast<int>(left_pixels_ + right_pixels_);
|
const auto total_pixels = static_cast<int>(left_pixels_ + right_pixels_);
|
||||||
|
|
||||||
auto left_px = std::clamp(static_cast<int>(left_pixels_) + delta, 0, total_pixels);
|
auto left_px = std::clamp(static_cast<int>(left_pixels_) + delta, 0, total_pixels);
|
||||||
|
|
||||||
|
auto area_px = rectangle_rotator(vert, div_owner->margin_area()).w();
|
||||||
double imd_rate = 100.0 / area_px;
|
double imd_rate = 100.0 / area_px;
|
||||||
left_px = static_cast<int>(limit_px(_m_leaf_left(), left_px, area_px));
|
left_px = static_cast<int>(limit_px(leaf_left, left_px, area_px));
|
||||||
_m_leaf_left()->weight.assign_percent(imd_rate * left_px);
|
leaf_left->weight.assign_percent(imd_rate * left_px);
|
||||||
|
|
||||||
auto right_px = std::clamp(static_cast<int>(right_pixels_) - delta, 0, total_pixels);
|
auto right_px = std::clamp(static_cast<int>(right_pixels_) - delta, 0, total_pixels);
|
||||||
|
|
||||||
right_px = static_cast<int>(limit_px(_m_leaf_right(), right_px, area_px));
|
right_px = static_cast<int>(limit_px(leaf_right, right_px, area_px));
|
||||||
_m_leaf_right()->weight.assign_percent(imd_rate * right_px);
|
leaf_right->weight.assign_percent(imd_rate * right_px);
|
||||||
|
|
||||||
pause_move_collocate_ = true;
|
pause_move_collocate_ = true;
|
||||||
div_owner->collocate(splitter_.parent());
|
div_owner->collocate(splitter_.parent());
|
||||||
|
|
||||||
//After the collocating, the splitter keeps the calculated weight of left division,
|
//After the collocating, the splitter keeps the calculated weight of left division,
|
||||||
//and clear the weight of right division.
|
//and clear the weight of right division.
|
||||||
_m_leaf_right()->weight.reset();
|
leaf_right->weight.reset();
|
||||||
|
|
||||||
pause_move_collocate_ = false;
|
pause_move_collocate_ = false;
|
||||||
}
|
}
|
||||||
@@ -1675,8 +1666,8 @@ namespace nana
|
|||||||
{
|
{
|
||||||
const bool vert = (::nana::cursor::size_we != splitter_cursor_);
|
const bool vert = (::nana::cursor::size_we != splitter_cursor_);
|
||||||
|
|
||||||
auto leaf_left = _m_leaf_left();
|
auto leaf_left = _m_leaf(true);
|
||||||
auto leaf_right = _m_leaf_right();
|
auto leaf_right = _m_leaf(false);
|
||||||
rectangle_rotator left(vert, leaf_left->field_area);
|
rectangle_rotator left(vert, leaf_left->field_area);
|
||||||
rectangle_rotator right(vert, leaf_right->field_area);
|
rectangle_rotator right(vert, leaf_right->field_area);
|
||||||
auto area_px = right.right() - left.x();
|
auto area_px = right.right() - left.x();
|
||||||
@@ -1806,16 +1797,19 @@ namespace nana
|
|||||||
|
|
||||||
void _m_update_div(std::string& div)
|
void _m_update_div(std::string& div)
|
||||||
{
|
{
|
||||||
|
auto const leaf_left = _m_leaf(true);
|
||||||
|
auto const leaf_right = _m_leaf(false);
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
bool left = true;
|
bool left = true;
|
||||||
|
|
||||||
//Search a name recursively from a specified leaf field.
|
//Search a name recursively from a specified leaf field.
|
||||||
//It returns the depth from the leaf div to the div which has a name.
|
//It returns the depth from the leaf div to the div which has a name.
|
||||||
auto depth = _m_search_name(_m_leaf_left(), name);
|
auto depth = _m_search_name(leaf_left, name);
|
||||||
if (-1 == depth)
|
if (-1 == depth)
|
||||||
{
|
{
|
||||||
left = false;
|
left = false;
|
||||||
depth = _m_search_name(_m_leaf_right(), name);
|
depth = _m_search_name(leaf_right, name);
|
||||||
if (-1 == depth)
|
if (-1 == depth)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1839,8 +1833,8 @@ namespace nana
|
|||||||
|
|
||||||
const bool vert = (::nana::cursor::size_we != splitter_cursor_);
|
const bool vert = (::nana::cursor::size_we != splitter_cursor_);
|
||||||
|
|
||||||
rectangle_rotator r_left(vert, _m_leaf_left()->field_area);
|
rectangle_rotator r_left(vert, leaf_left->field_area);
|
||||||
rectangle_rotator r_right(vert, _m_leaf_right()->field_area);
|
rectangle_rotator r_right(vert, leaf_right->field_area);
|
||||||
rectangle_rotator r_owner(vert, this->div_owner->field_area);
|
rectangle_rotator r_owner(vert, this->div_owner->field_area);
|
||||||
|
|
||||||
double percent = double((left ? r_left : r_right).w()) / double(r_owner.w());
|
double percent = double((left ? r_left : r_right).w()) / double(r_owner.w());
|
||||||
@@ -1866,14 +1860,9 @@ namespace nana
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
division * _m_leaf_left() const
|
division * _m_leaf(bool left) const noexcept
|
||||||
{
|
{
|
||||||
return previous();
|
return (left ? previous() : div_next);
|
||||||
}
|
|
||||||
|
|
||||||
division * _m_leaf_right() const
|
|
||||||
{
|
|
||||||
return div_next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rectangle_rotator _m_update_splitter_range()
|
rectangle_rotator _m_update_splitter_range()
|
||||||
@@ -1882,8 +1871,8 @@ namespace nana
|
|||||||
|
|
||||||
rectangle_rotator area(vert, div_owner->margin_area());
|
rectangle_rotator area(vert, div_owner->margin_area());
|
||||||
|
|
||||||
auto leaf_left = _m_leaf_left();
|
auto leaf_left = _m_leaf(true);
|
||||||
auto leaf_right = _m_leaf_right();
|
auto leaf_right = _m_leaf(false);
|
||||||
|
|
||||||
rectangle_rotator left(vert, leaf_left->field_area);
|
rectangle_rotator left(vert, leaf_left->field_area);
|
||||||
rectangle_rotator right(vert, leaf_right->field_area);
|
rectangle_rotator right(vert, leaf_right->field_area);
|
||||||
@@ -1982,7 +1971,7 @@ namespace nana
|
|||||||
|
|
||||||
void notify_move() override
|
void notify_move() override
|
||||||
{
|
{
|
||||||
if (!_m_indicator())
|
if (!_m_hit_test(false)) //hit test on indicator
|
||||||
{
|
{
|
||||||
indicator_.docker.reset();
|
indicator_.docker.reset();
|
||||||
return;
|
return;
|
||||||
@@ -2019,7 +2008,7 @@ namespace nana
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_m_dockable())
|
if (_m_hit_test(true)) //hit test on docker
|
||||||
{
|
{
|
||||||
if (!indicator_.dock_area)
|
if (!indicator_.dock_area)
|
||||||
{
|
{
|
||||||
@@ -2078,7 +2067,8 @@ namespace nana
|
|||||||
|
|
||||||
void notify_move_stopped() override
|
void notify_move_stopped() override
|
||||||
{
|
{
|
||||||
if (_m_dockable() && dockable_field && dockable_field->dockarea)
|
//hit test on docker
|
||||||
|
if (_m_hit_test(true) && dockable_field && dockable_field->dockarea)
|
||||||
dockable_field->dockarea->dock();
|
dockable_field->dockarea->dock();
|
||||||
|
|
||||||
indicator_.docker.reset();
|
indicator_.docker.reset();
|
||||||
@@ -2101,25 +2091,22 @@ namespace nana
|
|||||||
API::close_window(window_handle);
|
API::close_window(window_handle);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
bool _m_indicator() const
|
bool _m_hit_test(bool try_docker) const
|
||||||
{
|
{
|
||||||
::nana::point pos;
|
window handle = nullptr;
|
||||||
API::calc_screen_point(impl_ptr_->window_handle, pos);
|
if (try_docker)
|
||||||
|
{
|
||||||
|
if (!indicator_.docker)
|
||||||
|
return false;
|
||||||
|
|
||||||
rectangle r{ pos, API::window_size(impl_ptr_->window_handle) };
|
handle = indicator_.docker->handle(); //hit test for docker
|
||||||
return r.is_hit(API::cursor_position());
|
}
|
||||||
}
|
else
|
||||||
|
handle = impl_ptr_->window_handle; //hit test for indicator
|
||||||
|
|
||||||
bool _m_dockable() const
|
point pos;
|
||||||
{
|
API::calc_screen_point(handle, pos);
|
||||||
if (!indicator_.docker)
|
return rectangle{ pos, API::window_size(handle) }.is_hit(API::cursor_position());
|
||||||
return false;
|
|
||||||
|
|
||||||
::nana::point pos;
|
|
||||||
API::calc_screen_point(indicator_.docker->handle(), pos);
|
|
||||||
|
|
||||||
rectangle r{ pos, API::window_size(indicator_.docker->handle()) };
|
|
||||||
return r.is_hit(API::cursor_position());
|
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
field_dock * dockable_field{ nullptr };
|
field_dock * dockable_field{ nullptr };
|
||||||
@@ -2149,25 +2136,21 @@ namespace nana
|
|||||||
: panel<true>(wd, true), dir_(dir), dock_dv_(dock_dv), pane_dv_(pane_dv)
|
: panel<true>(wd, true), dir_(dir), dock_dv_(dock_dv), pane_dv_(pane_dv)
|
||||||
{
|
{
|
||||||
this->bgcolor(colors::alice_blue);
|
this->bgcolor(colors::alice_blue);
|
||||||
this->cursor(_m_is_vert(dir_) ? ::nana::cursor::size_ns : ::nana::cursor::size_we);
|
this->cursor(is_vert_dir(dir_) ? ::nana::cursor::size_ns : ::nana::cursor::size_we);
|
||||||
|
|
||||||
|
|
||||||
auto grab_fn = [this, wd](const arg_mouse& arg)
|
auto grab_fn = [this, wd](const arg_mouse& arg)
|
||||||
{
|
{
|
||||||
|
auto const is_vert = is_vert_dir(dir_);
|
||||||
|
|
||||||
if (event_code::mouse_down == arg.evt_code) //press mouse button
|
if (event_code::mouse_down == arg.evt_code) //press mouse button
|
||||||
{
|
{
|
||||||
if (arg.button != ::nana::mouse::left_button)
|
if (arg.button != ::nana::mouse::left_button)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool is_vert = _m_is_vert(dir_);
|
|
||||||
|
|
||||||
this->set_capture(true);
|
this->set_capture(true);
|
||||||
|
|
||||||
auto basepos = API::cursor_position();
|
base_pos_.x = horz_point(is_vert, API::cursor_position());
|
||||||
base_pos_.x = (is_vert ? basepos.y : basepos.x);
|
base_pos_.y = horz_point(is_vert, this->pos());
|
||||||
|
|
||||||
basepos = this->pos();
|
|
||||||
base_pos_.y = (is_vert ? basepos.y : basepos.x);
|
|
||||||
|
|
||||||
base_px_ = (is_vert ? pane_dv_->field_area.height : pane_dv_->field_area.width);
|
base_px_ = (is_vert ? pane_dv_->field_area.height : pane_dv_->field_area.width);
|
||||||
}
|
}
|
||||||
@@ -2176,8 +2159,7 @@ namespace nana
|
|||||||
if (!arg.is_left_button())
|
if (!arg.is_left_button())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto now_pos = API::cursor_position();
|
auto delta = horz_point(is_vert, API::cursor_position()) - base_pos_.x;
|
||||||
int delta = (_m_is_vert(dir_) ? now_pos.y : now_pos.x) - base_pos_.x;
|
|
||||||
int new_pos = base_pos_.y + delta;
|
int new_pos = base_pos_.y + delta;
|
||||||
if (new_pos < range_.x)
|
if (new_pos < range_.x)
|
||||||
{
|
{
|
||||||
@@ -2190,8 +2172,8 @@ namespace nana
|
|||||||
delta = new_pos - base_pos_.y;
|
delta = new_pos - base_pos_.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
now_pos = this->pos();
|
auto now_pos = this->pos();
|
||||||
if (_m_is_vert(dir_))
|
if (is_vert)
|
||||||
now_pos.y = new_pos;
|
now_pos.y = new_pos;
|
||||||
else
|
else
|
||||||
now_pos.x = new_pos;
|
now_pos.x = new_pos;
|
||||||
@@ -2218,7 +2200,7 @@ namespace nana
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dock_px = (_m_is_vert(dir_) ? dock_dv_->field_area.height : dock_dv_->field_area.width);
|
auto dock_px = (is_vert ? dock_dv_->field_area.height : dock_dv_->field_area.width);
|
||||||
|
|
||||||
pane_dv_->weight.assign_percent(double(px) / double(dock_px) * 100);
|
pane_dv_->weight.assign_percent(double(px) / double(dock_px) * 100);
|
||||||
|
|
||||||
@@ -2278,7 +2260,7 @@ namespace nana
|
|||||||
if (!child->display)
|
if (!child->display)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto is_vert = _m_is_vert(child->dir);
|
const auto is_vert = is_vert_dir(child->dir);
|
||||||
if (is_first)
|
if (is_first)
|
||||||
{
|
{
|
||||||
is_first = false;
|
is_first = false;
|
||||||
@@ -2318,7 +2300,7 @@ namespace nana
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto child_dv = dynamic_cast<div_dockpane*>(child.get());
|
auto child_dv = dynamic_cast<div_dockpane*>(child.get());
|
||||||
const bool is_vert = _m_is_vert(child->dir);
|
const bool is_vert = is_vert_dir(child->dir);
|
||||||
|
|
||||||
auto room_px = (is_vert ? room.height : room.width);
|
auto room_px = (is_vert ? room.height : room.width);
|
||||||
|
|
||||||
@@ -2429,11 +2411,6 @@ namespace nana
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
static bool _m_is_vert(::nana::direction dir)
|
|
||||||
{
|
|
||||||
return (dir == ::nana::direction::north || dir == ::nana::direction::south);
|
|
||||||
}
|
|
||||||
|
|
||||||
static div_dockpane* _m_right(division* dv)
|
static div_dockpane* _m_right(division* dv)
|
||||||
{
|
{
|
||||||
dv = dv->div_next;
|
dv = dv->div_next;
|
||||||
@@ -2521,7 +2498,6 @@ namespace nana
|
|||||||
static int get_parameter(place_parts::tokenizer& tknizer, std::size_t pos)
|
static int get_parameter(place_parts::tokenizer& tknizer, std::size_t pos)
|
||||||
{
|
{
|
||||||
auto & arg = tknizer.parameters()[pos];
|
auto & arg = tknizer.parameters()[pos];
|
||||||
//auto & arg = params[pos];
|
|
||||||
|
|
||||||
if (arg.kind_of() == number_t::kind::integer)
|
if (arg.kind_of() == number_t::kind::integer)
|
||||||
return arg.integer();
|
return arg.integer();
|
||||||
@@ -2538,7 +2514,7 @@ namespace nana
|
|||||||
|
|
||||||
std::unique_ptr<division> div;
|
std::unique_ptr<division> div;
|
||||||
token div_type = token::eof;
|
token div_type = token::eof;
|
||||||
bool fit_content = false;
|
auto fit = fit_policy::none;
|
||||||
|
|
||||||
//These variables stand for the new division's attributes
|
//These variables stand for the new division's attributes
|
||||||
std::string name;
|
std::string name;
|
||||||
@@ -2559,12 +2535,15 @@ namespace nana
|
|||||||
{
|
{
|
||||||
case token::dock:
|
case token::dock:
|
||||||
if (token::eof != div_type && token::dock != div_type)
|
if (token::eof != div_type && token::dock != div_type)
|
||||||
throw std::invalid_argument("nana.place: conflict of div type at " + tknizer.pos_str());
|
throw std::invalid_argument("nana.place: conflict of div type at " + std::to_string(tknizer.pos()));
|
||||||
|
|
||||||
div_type = token::dock;
|
div_type = token::dock;
|
||||||
break;
|
break;
|
||||||
case token::fit:
|
case token::fit:
|
||||||
fit_content = true;
|
fit = fit_policy::both;
|
||||||
|
break;
|
||||||
|
case token::fit_s:
|
||||||
|
fit = fit_policy::single;
|
||||||
break;
|
break;
|
||||||
case token::splitter:
|
case token::splitter:
|
||||||
//Ignore the splitter when there is not a division.
|
//Ignore the splitter when there is not a division.
|
||||||
@@ -2666,7 +2645,7 @@ namespace nana
|
|||||||
switch (tknizer.read())
|
switch (tknizer.read())
|
||||||
{
|
{
|
||||||
case token::number:
|
case token::number:
|
||||||
margin.set_value(tknizer.number());
|
margin.push(tknizer.number(), true);
|
||||||
break;
|
break;
|
||||||
case token::array:
|
case token::array:
|
||||||
margin.set_array(tknizer.array());
|
margin.set_array(tknizer.array());
|
||||||
@@ -2829,7 +2808,7 @@ namespace nana
|
|||||||
|
|
||||||
div->display = !undisplayed;
|
div->display = !undisplayed;
|
||||||
div->visible = !(undisplayed || invisible);
|
div->visible = !(undisplayed || invisible);
|
||||||
div->fit_content = fit_content;
|
div->fit = fit;
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2891,20 +2870,20 @@ namespace nana
|
|||||||
if (i != docks.end())
|
if (i != docks.end())
|
||||||
{
|
{
|
||||||
docks_to_be_closed.erase(div->name);
|
docks_to_be_closed.erase(div->name);
|
||||||
auto pane = dynamic_cast<div_dockpane*>(div);
|
|
||||||
pane->dockable_field = i->second;
|
|
||||||
|
|
||||||
auto old_pane = pane->dockable_field->attached;
|
auto const pane = dynamic_cast<div_dockpane*>(div);
|
||||||
if (old_pane)
|
auto fd_dock = pane->dockable_field;
|
||||||
|
fd_dock = i->second;
|
||||||
|
|
||||||
|
if (fd_dock->attached)
|
||||||
{
|
{
|
||||||
//old div_dockpane will be deleted
|
fd_dock->attached->dockable_field = nullptr;
|
||||||
old_pane->dockable_field = nullptr;
|
div->display = fd_dock->attached->display;
|
||||||
div->display = old_pane->display;
|
|
||||||
}
|
}
|
||||||
pane->dockable_field->attached = pane;
|
|
||||||
|
|
||||||
if (pane->dockable_field->dockarea)
|
fd_dock->attached = pane;
|
||||||
pane->dockable_field->dockarea->set_notifier(pane);
|
if (fd_dock->dockarea)
|
||||||
|
fd_dock->dockarea->set_notifier(pane);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -3035,7 +3014,6 @@ namespace nana
|
|||||||
throw std::invalid_argument(what);
|
throw std::invalid_argument(what);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<implement::division>* replaced = nullptr;
|
std::unique_ptr<implement::division>* replaced = nullptr;
|
||||||
|
|
||||||
implement::division * div_owner = div_ptr->div_owner;
|
implement::division * div_owner = div_ptr->div_owner;
|
||||||
|
|||||||
@@ -29,21 +29,16 @@ namespace nana
|
|||||||
virtual ~splitter_interface(){}
|
virtual ~splitter_interface(){}
|
||||||
};
|
};
|
||||||
|
|
||||||
class splitter_dtrigger
|
|
||||||
: public drawer_trigger
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template<bool IsLite>
|
template<bool IsLite>
|
||||||
class splitter
|
class splitter
|
||||||
: public widget_object <typename std::conditional<IsLite, category::lite_widget_tag, category::widget_tag>::type, splitter_dtrigger>,
|
: public widget_object <typename std::conditional<IsLite, category::lite_widget_tag, category::widget_tag>::type, drawer_trigger>,
|
||||||
public splitter_interface
|
public splitter_interface
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
void _m_complete_creation() override
|
void _m_complete_creation() override
|
||||||
{
|
{
|
||||||
this->caption("place-splitter");
|
this->caption("place-splitter");
|
||||||
widget_object <typename std::conditional<IsLite, category::lite_widget_tag, category::widget_tag>::type, splitter_dtrigger>::_m_complete_creation();
|
widget_object <typename std::conditional<IsLite, category::lite_widget_tag, category::widget_tag>::type, drawer_trigger>::_m_complete_creation();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -92,7 +87,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
color xclr = colors::red;
|
color xclr = colors::red;
|
||||||
|
|
||||||
if(x_state_ == ::nana::mouse_action::pressed)
|
if(x_state_ == ::nana::mouse_action::pressed)
|
||||||
xclr = xclr.blend(colors::white, 0.8);
|
xclr = xclr.blend(colors::white, 0.8);
|
||||||
|
|
||||||
graph.rectangle(r, true, xclr);
|
graph.rectangle(r, true, xclr);
|
||||||
@@ -144,11 +139,8 @@ namespace nana
|
|||||||
private:
|
private:
|
||||||
::nana::rectangle _m_button_area() const
|
::nana::rectangle _m_button_area() const
|
||||||
{
|
{
|
||||||
::nana::rectangle r{API::window_size(window_handle_)};
|
auto sz = API::window_size(window_handle_);
|
||||||
|
return{static_cast<int>(sz.width) - 20, 0, 20, sz.height};
|
||||||
r.x = r.right() - 20;
|
|
||||||
r.width = 20;
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
window window_handle_;
|
window window_handle_;
|
||||||
@@ -161,12 +153,17 @@ namespace nana
|
|||||||
};
|
};
|
||||||
|
|
||||||
class dockarea_caption
|
class dockarea_caption
|
||||||
: public widget_object < category::widget_tag, dockcaption_dtrigger >
|
: public widget_object<category::widget_tag, dockcaption_dtrigger>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using widget_object<category::widget_tag, dockcaption_dtrigger>::get_drawer_trigger;
|
using widget_object<category::widget_tag, dockcaption_dtrigger>::get_drawer_trigger;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static unsigned differ(unsigned x, unsigned y) noexcept
|
||||||
|
{
|
||||||
|
return (x > y ? x - y : 0);
|
||||||
|
}
|
||||||
|
|
||||||
class dockarea
|
class dockarea
|
||||||
: public widget_object <category::lite_widget_tag, drawer_trigger>
|
: public widget_object <category::lite_widget_tag, drawer_trigger>
|
||||||
{
|
{
|
||||||
@@ -183,6 +180,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
notifier_ = notifier;
|
notifier_ = notifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
void create(window parent)
|
void create(window parent)
|
||||||
{
|
{
|
||||||
host_window_ = parent;
|
host_window_ = parent;
|
||||||
@@ -191,17 +189,14 @@ namespace nana
|
|||||||
caption_.create(*this, true);
|
caption_.create(*this, true);
|
||||||
caption_.get_drawer_trigger().on_close([this]
|
caption_.get_drawer_trigger().on_close([this]
|
||||||
{
|
{
|
||||||
bool destroy_dockarea = true;
|
|
||||||
|
|
||||||
if (tabbar_)
|
if (tabbar_)
|
||||||
{
|
{
|
||||||
tabbar_->erase(tabbar_->selected());
|
tabbar_->erase(tabbar_->selected());
|
||||||
|
if (tabbar_->length())
|
||||||
destroy_dockarea = (0 == tabbar_->length());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (destroy_dockarea)
|
notifier_->request_close();
|
||||||
notifier_->request_close();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this->events().resized.connect([this](const arg_resized& arg)
|
this->events().resized.connect([this](const arg_resized& arg)
|
||||||
@@ -331,14 +326,11 @@ namespace nana
|
|||||||
private:
|
private:
|
||||||
widget* _m_add_pane(factory & fn)
|
widget* _m_add_pane(factory & fn)
|
||||||
{
|
{
|
||||||
rectangle r{ point(), this->size() };
|
rectangle r{ this->size() };
|
||||||
|
|
||||||
//get a rectangle excluding caption
|
//get a rectangle excluding caption
|
||||||
r.y = 20;
|
r.y = 20;
|
||||||
if (r.height > 20)
|
r.height = differ(r.height, 20);
|
||||||
r.height -= 20;
|
|
||||||
else
|
|
||||||
r.height = 0;
|
|
||||||
|
|
||||||
if (!tabbar_)
|
if (!tabbar_)
|
||||||
{
|
{
|
||||||
@@ -434,17 +426,8 @@ namespace nana
|
|||||||
|
|
||||||
bool is_negative() const
|
bool is_negative() const
|
||||||
{
|
{
|
||||||
switch (kind_)
|
return (((kind::integer == kind_) && (value_.integer < 0)) ||
|
||||||
{
|
((kind::real == kind_ || kind::percent == kind_) && (value_.real < 0)));
|
||||||
case kind::integer:
|
|
||||||
return (value_.integer < 0);
|
|
||||||
case kind::real:
|
|
||||||
case kind::percent:
|
|
||||||
return (value_.real < 0);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const noexcept
|
bool empty() const noexcept
|
||||||
@@ -533,14 +516,11 @@ namespace nana
|
|||||||
margins_.clear();
|
margins_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(const number_t& v)
|
void push(const number_t& v, bool reset = false)
|
||||||
{
|
{
|
||||||
margins_.emplace_back(v);
|
if (reset)
|
||||||
}
|
clear();
|
||||||
|
|
||||||
void set_value(const number_t& v)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
margins_.emplace_back(v);
|
margins_.emplace_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,12 +539,11 @@ namespace nana
|
|||||||
if (all_edges_)
|
if (all_edges_)
|
||||||
{
|
{
|
||||||
auto px = static_cast<int>(margins_.back().get_value(static_cast<int>(r.width)));
|
auto px = static_cast<int>(margins_.back().get_value(static_cast<int>(r.width)));
|
||||||
const auto dbl_px = static_cast<unsigned>(px << 1);
|
|
||||||
r.x += px;
|
r.x += px;
|
||||||
r.width = (r.width < dbl_px ? 0 : r.width - dbl_px);
|
r.width = differ(r.width, (static_cast<unsigned>(px) << 1));
|
||||||
|
|
||||||
r.y += px;
|
r.y += px;
|
||||||
r.height = (r.height < dbl_px ? 0 : r.height - dbl_px);
|
r.height = differ(r.height, (static_cast<unsigned>(px) << 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -587,49 +566,44 @@ namespace nana
|
|||||||
ib = 2;
|
ib = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef decltype(r.height) px_type;
|
using px_type = decltype(r.height);
|
||||||
auto calc = [](px_type a, px_type b)
|
|
||||||
{
|
|
||||||
return (a > b ? a - b : 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (0 == it) //top
|
if (0 == it) //top
|
||||||
{
|
{
|
||||||
auto px = static_cast<int>(margins_[it].get_value(static_cast<int>(field_area.height)));
|
auto px = static_cast<int>(margins_[it].get_value(static_cast<int>(field_area.height)));
|
||||||
r.y += px;
|
r.y += px;
|
||||||
r.height = calc(r.height, static_cast<px_type>(px));
|
r.height = differ(r.height, static_cast<px_type>(px));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-1 != ib) //bottom
|
if (-1 != ib) //bottom
|
||||||
{
|
{
|
||||||
auto px = static_cast<int>(margins_[ib].get_value(static_cast<int>(field_area.height)));
|
auto px = static_cast<int>(margins_[ib].get_value(static_cast<int>(field_area.height)));
|
||||||
r.height = calc(r.height, static_cast<px_type>(px));
|
r.height = differ(r.height, static_cast<px_type>(px));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-1 != il) //left
|
if (-1 != il) //left
|
||||||
{
|
{
|
||||||
auto px = static_cast<px_type>(margins_[il].get_value(static_cast<int>(field_area.width)));
|
auto px = static_cast<px_type>(margins_[il].get_value(static_cast<int>(field_area.width)));
|
||||||
r.x += px;
|
r.x += px;
|
||||||
r.width = calc(r.width, static_cast<px_type>(px));
|
r.width = differ(r.width, static_cast<px_type>(px));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-1 != ir) //right
|
if (-1 != ir) //right
|
||||||
{
|
{
|
||||||
auto px = static_cast<int>(margins_[ir].get_value(static_cast<int>(field_area.width)));
|
auto px = static_cast<int>(margins_[ir].get_value(static_cast<int>(field_area.width)));
|
||||||
r.width = calc(r.width, static_cast<px_type>(px));
|
r.width = differ(r.width, static_cast<px_type>(px));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
bool all_edges_ = true;
|
bool all_edges_{ true };
|
||||||
std::vector<number_t> margins_;
|
std::vector<number_t> margins_;
|
||||||
};//end class margin
|
};//end class margin
|
||||||
|
|
||||||
class repeated_array
|
class repeated_array
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//A workaround for VC2013, becuase it does not generated an implicit declared move-constructor as defaulted.
|
//A workaround for VC2013, becuase it does not generated an implicit declared move-constructor as defaulted.
|
||||||
repeated_array() = default;
|
repeated_array() = default;
|
||||||
|
|
||||||
@@ -678,15 +652,10 @@ namespace nana
|
|||||||
|
|
||||||
number_t at(std::size_t pos) const
|
number_t at(std::size_t pos) const
|
||||||
{
|
{
|
||||||
if (values_.empty())
|
if (values_.size() && (repeated_ || pos < values_.size()))
|
||||||
return{};
|
return values_[pos % values_.size()];
|
||||||
|
|
||||||
if (repeated_)
|
return{};
|
||||||
pos %= values_.size();
|
|
||||||
else if (pos >= values_.size())
|
|
||||||
return{};
|
|
||||||
|
|
||||||
return values_[pos];
|
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
bool repeated_ = false;
|
bool repeated_ = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user