Merge remote-tracking branch 'cnjinhao/develop' into develop
This commit is contained in:
commit
b7fec184aa
@ -109,6 +109,24 @@ namespace nana
|
|||||||
virtual unsigned fixed_pixels() const;
|
virtual unsigned fixed_pixels() const;
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
|
class boolean
|
||||||
|
: public abstract_content
|
||||||
|
{
|
||||||
|
struct implement;
|
||||||
|
public:
|
||||||
|
boolean(::std::string label, bool initial_value);
|
||||||
|
~boolean();
|
||||||
|
|
||||||
|
bool value() const;
|
||||||
|
private:
|
||||||
|
//Implementation of abstract_content
|
||||||
|
const ::std::string& label() const override;
|
||||||
|
window create(window, unsigned label_px) override;
|
||||||
|
unsigned fixed_pixels() const override;
|
||||||
|
private:
|
||||||
|
std::unique_ptr<implement> impl_;
|
||||||
|
};
|
||||||
|
|
||||||
class integer
|
class integer
|
||||||
: public abstract_content
|
: public abstract_content
|
||||||
{
|
{
|
||||||
@ -122,6 +140,7 @@ namespace nana
|
|||||||
//Implementation of abstract_content
|
//Implementation of abstract_content
|
||||||
const ::std::string& label() const override;
|
const ::std::string& label() const override;
|
||||||
window create(window, unsigned label_px) override;
|
window create(window, unsigned label_px) override;
|
||||||
|
unsigned fixed_pixels() const override;
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<implement> impl_;
|
std::unique_ptr<implement> impl_;
|
||||||
};
|
};
|
||||||
@ -139,6 +158,7 @@ namespace nana
|
|||||||
//Implementation of abstract_content
|
//Implementation of abstract_content
|
||||||
const ::std::string& label() const override;
|
const ::std::string& label() const override;
|
||||||
window create(window, unsigned label_px) override;
|
window create(window, unsigned label_px) override;
|
||||||
|
unsigned fixed_pixels() const override;
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<implement> impl_;
|
std::unique_ptr<implement> impl_;
|
||||||
};
|
};
|
||||||
@ -166,6 +186,7 @@ namespace nana
|
|||||||
//Implementation of abstract_content
|
//Implementation of abstract_content
|
||||||
const ::std::string& label() const override;
|
const ::std::string& label() const override;
|
||||||
window create(window, unsigned label_px) override;
|
window create(window, unsigned label_px) override;
|
||||||
|
unsigned fixed_pixels() const override;
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<implement> impl_;
|
std::unique_ptr<implement> impl_;
|
||||||
};
|
};
|
||||||
|
@ -1056,6 +1056,19 @@ namespace nana
|
|||||||
cat_proxy & select(bool);
|
cat_proxy & select(bool);
|
||||||
bool selected() const;
|
bool selected() const;
|
||||||
|
|
||||||
|
/// Enables/disables the number of items in the category to be displayed behind the category title
|
||||||
|
cat_proxy& display_number(bool display);
|
||||||
|
|
||||||
|
/// Determines whether the category is expanded.
|
||||||
|
bool expanded() const;
|
||||||
|
|
||||||
|
/// Expands/collapses the category
|
||||||
|
/**
|
||||||
|
* @param expand Indicates whether to expand or collapse the category. If this parameter is true, it expands the category. If the parameter is false, it collapses the category.
|
||||||
|
* @return the reference of *this.
|
||||||
|
*/
|
||||||
|
cat_proxy& expanded(bool expand);
|
||||||
|
|
||||||
/// Behavior of a container
|
/// Behavior of a container
|
||||||
void push_back(std::string text_utf8);
|
void push_back(std::string text_utf8);
|
||||||
|
|
||||||
@ -1488,6 +1501,22 @@ the nana::detail::basic_window member pointer scheme
|
|||||||
void enable_single(bool for_selection, bool category_limited);
|
void enable_single(bool for_selection, bool category_limited);
|
||||||
void disable_single(bool for_selection);
|
void disable_single(bool for_selection);
|
||||||
export_options& def_export_options();
|
export_options& def_export_options();
|
||||||
|
|
||||||
|
|
||||||
|
/// Sets a renderer for category icon
|
||||||
|
/**
|
||||||
|
* @param icon_renderer The renderer of category icon
|
||||||
|
* @return the reference of *this.
|
||||||
|
*/
|
||||||
|
listbox& category_icon(std::function<void(paint::graphics& graph, const rectangle& rt_icon, bool expanded)> icon_renderer);
|
||||||
|
|
||||||
|
/// Sets category icons
|
||||||
|
/**
|
||||||
|
* @param img_expanded An icon displayed in front of category title when the category is expanded.
|
||||||
|
* @param img_collapsed An icon displayed in front of category title when the category is collapsed.
|
||||||
|
* @return the reference of *this.
|
||||||
|
*/
|
||||||
|
listbox& category_icon(const paint::image& img_expanded, const paint::image&& img_collapsed);
|
||||||
private:
|
private:
|
||||||
drawerbase::listbox::essence & _m_ess() const;
|
drawerbase::listbox::essence & _m_ess() const;
|
||||||
nana::any* _m_anyobj(size_type cat, size_type index, bool allocate_if_empty) const override;
|
nana::any* _m_anyobj(size_type cat, size_type index, bool allocate_if_empty) const override;
|
||||||
|
@ -86,6 +86,7 @@ namespace nana{ namespace widgets
|
|||||||
~text_editor();
|
~text_editor();
|
||||||
|
|
||||||
size caret_size() const;
|
size caret_size() const;
|
||||||
|
const point& content_origin() const;
|
||||||
|
|
||||||
void set_highlight(const ::std::string& name, const ::nana::color&, const ::nana::color&);
|
void set_highlight(const ::std::string& name, const ::nana::color&, const ::nana::color&);
|
||||||
void erase_highlight(const ::std::string& name);
|
void erase_highlight(const ::std::string& name);
|
||||||
|
@ -140,6 +140,8 @@ namespace nana
|
|||||||
|
|
||||||
colored_area_access_interface* colored_area_access();
|
colored_area_access_interface* colored_area_access();
|
||||||
|
|
||||||
|
point content_origin() const;
|
||||||
|
|
||||||
/// Enables/disables the textbox to indent a line. Idents a new line when it is created by pressing enter.
|
/// Enables/disables the textbox to indent a line. Idents a new line when it is created by pressing enter.
|
||||||
/// @param generator generates text for identing a line. If it is empty, textbox indents the line according to last line.
|
/// @param generator generates text for identing a line. If it is empty, textbox indents the line according to last line.
|
||||||
textbox& indention(bool, std::function<std::string()> generator = {});
|
textbox& indention(bool, std::function<std::string()> generator = {});
|
||||||
|
@ -94,6 +94,7 @@ namespace nana
|
|||||||
void enable(size_type index, bool enable_state);
|
void enable(size_type index, bool enable_state);
|
||||||
void scale(unsigned s); ///< Sets the scale of control button.
|
void scale(unsigned s); ///< Sets the scale of control button.
|
||||||
|
|
||||||
|
/// Enable to place buttons at right part. After calling it, every new button is right aligned.
|
||||||
void go_right();
|
void go_right();
|
||||||
|
|
||||||
bool detached() { return detached_; };
|
bool detached() { return detached_; };
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <nana/gui/widgets/label.hpp>
|
#include <nana/gui/widgets/label.hpp>
|
||||||
#include <nana/gui/widgets/button.hpp>
|
#include <nana/gui/widgets/button.hpp>
|
||||||
#include <nana/gui/widgets/spinbox.hpp>
|
#include <nana/gui/widgets/spinbox.hpp>
|
||||||
|
#include <nana/gui/widgets/checkbox.hpp>
|
||||||
#include <nana/gui/widgets/combox.hpp>
|
#include <nana/gui/widgets/combox.hpp>
|
||||||
#include <nana/gui/widgets/textbox.hpp>
|
#include <nana/gui/widgets/textbox.hpp>
|
||||||
#include <nana/gui/widgets/panel.hpp>
|
#include <nana/gui/widgets/panel.hpp>
|
||||||
@ -519,15 +520,15 @@ namespace nana
|
|||||||
if (each_height[i] > 27)
|
if (each_height[i] > 27)
|
||||||
px = each_height[i];
|
px = each_height[i];
|
||||||
|
|
||||||
ss_content << "<weight=" << px << " margin=[3] input_" << i << ">";
|
ss_content << "<weight=" << (px + 3) << " margin=[3] input_" << i << ">";
|
||||||
|
|
||||||
height += px + 1;
|
height += px + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ss_content << "><margin=[15] weight=38<><buttons arrange=80 gap=10 weight=170>>>";
|
ss_content << "><margin=[15] weight=38<><buttons arrange=80 gap=10 weight=170>>>";
|
||||||
|
|
||||||
if (desc_extent.width < 170)
|
if (desc_extent.width < 200)
|
||||||
desc_extent.width = 170;
|
desc_extent.width = 200;
|
||||||
|
|
||||||
//Make sure the complete display of input extent
|
//Make sure the complete display of input extent
|
||||||
if (desc_extent.width < fixed_pixels)
|
if (desc_extent.width < fixed_pixels)
|
||||||
@ -653,6 +654,70 @@ namespace nana
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//class boolean
|
||||||
|
struct inputbox::boolean::implement
|
||||||
|
{
|
||||||
|
bool value;
|
||||||
|
::std::string empty_label_text;
|
||||||
|
::std::string label_text;
|
||||||
|
::nana::panel<false> dock;
|
||||||
|
::nana::checkbox checkbox;
|
||||||
|
};
|
||||||
|
|
||||||
|
inputbox::boolean::boolean(::std::string label, bool initial_value)
|
||||||
|
: impl_(new implement)
|
||||||
|
{
|
||||||
|
impl_->value = initial_value;
|
||||||
|
impl_->label_text = std::move(label);
|
||||||
|
impl_->empty_label_text = " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
inputbox::boolean::~boolean()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool inputbox::boolean::value() const
|
||||||
|
{
|
||||||
|
return (impl_->checkbox.empty() ? impl_->value : impl_->checkbox.checked());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Implementation of abstract_content
|
||||||
|
const ::std::string& inputbox::boolean::label() const
|
||||||
|
{
|
||||||
|
return impl_->empty_label_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
window inputbox::boolean::create(window owner, unsigned label_px)
|
||||||
|
{
|
||||||
|
auto impl = impl_.get();
|
||||||
|
|
||||||
|
impl->dock.create(owner);
|
||||||
|
|
||||||
|
paint::graphics graph{ ::nana::size{ 10, 10 } };
|
||||||
|
auto value_px = graph.text_extent_size(impl->label_text).width + 20;
|
||||||
|
|
||||||
|
impl->checkbox.create(impl->dock, rectangle{ (std::max)(static_cast<int>(label_px) - 18, 0), 0, value_px, 0 });
|
||||||
|
impl->checkbox.check(impl->value);
|
||||||
|
impl->checkbox.caption(impl->label_text);
|
||||||
|
|
||||||
|
impl->dock.events().resized.connect_unignorable([impl, value_px](const ::nana::arg_resized&)
|
||||||
|
{
|
||||||
|
impl->checkbox.size({ value_px, 24 });
|
||||||
|
});
|
||||||
|
|
||||||
|
impl->checkbox.events().destroy.connect_unignorable([impl](const arg_destroy&)
|
||||||
|
{
|
||||||
|
impl->value = impl->checkbox.checked();
|
||||||
|
});
|
||||||
|
|
||||||
|
return impl->dock;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned inputbox::boolean::fixed_pixels() const
|
||||||
|
{
|
||||||
|
paint::graphics graph{ ::nana::size{ 10, 10 } };
|
||||||
|
return graph.text_extent_size(impl_->label_text).width;
|
||||||
|
}
|
||||||
|
|
||||||
//class integer
|
//class integer
|
||||||
struct inputbox::integer::implement
|
struct inputbox::integer::implement
|
||||||
{
|
{
|
||||||
@ -705,20 +770,17 @@ namespace nana
|
|||||||
impl->label.caption(impl->label_text);
|
impl->label.caption(impl->label_text);
|
||||||
impl->label.format(true);
|
impl->label.format(true);
|
||||||
|
|
||||||
//get the longest value
|
auto const value_px = fixed_pixels();
|
||||||
int longest = (std::abs(static_cast<int>(impl->begin < 0 ? impl->begin * 10 : impl->begin)) < std::abs(static_cast<int>(impl->last < 0 ? impl->last * 10 : impl->last)) ? impl->last : impl->begin);
|
|
||||||
paint::graphics graph{ ::nana::size{ 10, 10 } };
|
|
||||||
auto value_px = graph.text_extent_size(std::to_wstring(longest)).width + 34;
|
|
||||||
|
|
||||||
impl->spinbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
|
impl->spinbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
|
||||||
impl->spinbox.range(impl->begin, impl->last, impl->step);
|
impl->spinbox.range(impl->begin, impl->last, impl->step);
|
||||||
|
|
||||||
impl->spinbox.value(std::to_string(impl->value));
|
impl->spinbox.value(std::to_string(impl->value));
|
||||||
|
|
||||||
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized&)
|
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg)
|
||||||
{
|
{
|
||||||
impl->label.size({ label_px, 24 });
|
impl->label.size({ label_px, arg.height });
|
||||||
impl->spinbox.size({ value_px, 24 });
|
impl->spinbox.move({static_cast<int>(label_px + 10), (static_cast<int>(arg.height) - 25) / 2, value_px, 24 });
|
||||||
});
|
});
|
||||||
|
|
||||||
impl->spinbox.events().destroy.connect_unignorable([impl](const arg_destroy&)
|
impl->spinbox.events().destroy.connect_unignorable([impl](const arg_destroy&)
|
||||||
@ -728,6 +790,14 @@ namespace nana
|
|||||||
|
|
||||||
return impl->dock;
|
return impl->dock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned inputbox::integer::fixed_pixels() const
|
||||||
|
{
|
||||||
|
//get the longest value
|
||||||
|
int longest = (std::abs(static_cast<int>(impl_->begin < 0 ? impl_->begin * 10 : impl_->begin)) < std::abs(static_cast<int>(impl_->last < 0 ? impl_->last * 10 : impl_->last)) ? impl_->last : impl_->begin);
|
||||||
|
paint::graphics graph{ ::nana::size{ 10, 10 } };
|
||||||
|
return graph.text_extent_size(std::to_wstring(longest)).width + 34;
|
||||||
|
}
|
||||||
//end class integer
|
//end class integer
|
||||||
|
|
||||||
|
|
||||||
@ -783,20 +853,17 @@ namespace nana
|
|||||||
impl->label.caption(impl->label_text);
|
impl->label.caption(impl->label_text);
|
||||||
impl->label.format(true);
|
impl->label.format(true);
|
||||||
|
|
||||||
//get the longest value
|
auto value_px = fixed_pixels();
|
||||||
auto longest = (std::abs(static_cast<int>(impl->begin < 0 ? impl->begin * 10 : impl->begin)) < std::abs(static_cast<int>(impl->last < 0 ? impl->last * 10 : impl->last)) ? impl->last : impl->begin);
|
|
||||||
paint::graphics graph{ ::nana::size{ 10, 10 } };
|
|
||||||
auto value_px = graph.text_extent_size(std::to_wstring(longest)).width + 34;
|
|
||||||
|
|
||||||
impl->spinbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
|
impl->spinbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
|
||||||
impl->spinbox.range(impl->begin, impl->last, impl->step);
|
impl->spinbox.range(impl->begin, impl->last, impl->step);
|
||||||
|
|
||||||
impl->spinbox.value(std::to_string(impl->value));
|
impl->spinbox.value(std::to_string(impl->value));
|
||||||
|
|
||||||
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized&)
|
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg)
|
||||||
{
|
{
|
||||||
impl->label.size(::nana::size{ label_px, 24 });
|
impl->label.size({ label_px, arg.height });
|
||||||
impl->spinbox.size(::nana::size{ value_px, 24 });
|
impl->spinbox.move({ static_cast<int>(label_px + 10), (static_cast<int>(arg.height) - 25) / 2, value_px, 24 });
|
||||||
});
|
});
|
||||||
|
|
||||||
impl->spinbox.events().destroy.connect_unignorable([impl](const arg_destroy&)
|
impl->spinbox.events().destroy.connect_unignorable([impl](const arg_destroy&)
|
||||||
@ -806,6 +873,14 @@ namespace nana
|
|||||||
|
|
||||||
return impl->dock;
|
return impl->dock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned inputbox::real::fixed_pixels() const
|
||||||
|
{
|
||||||
|
//get the longest value
|
||||||
|
auto longest = (std::abs(static_cast<int>(impl_->begin < 0 ? impl_->begin * 10 : impl_->begin)) < std::abs(static_cast<int>(impl_->last < 0 ? impl_->last * 10 : impl_->last)) ? impl_->last : impl_->begin);
|
||||||
|
paint::graphics graph{ ::nana::size{ 10, 10 } };
|
||||||
|
return graph.text_extent_size(std::to_wstring(longest)).width + 34;
|
||||||
|
}
|
||||||
//end class real
|
//end class real
|
||||||
|
|
||||||
|
|
||||||
@ -887,7 +962,7 @@ namespace nana
|
|||||||
impl->label.caption(impl->label_text);
|
impl->label.caption(impl->label_text);
|
||||||
impl->label.format(true);
|
impl->label.format(true);
|
||||||
|
|
||||||
unsigned value_px = 0;
|
unsigned const value_px = fixed_pixels();
|
||||||
if (impl->options.empty())
|
if (impl->options.empty())
|
||||||
{
|
{
|
||||||
impl->textbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, 0, 0 });
|
impl->textbox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, 0, 0 });
|
||||||
@ -898,16 +973,6 @@ namespace nana
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//get the longest value
|
|
||||||
paint::graphics graph{ ::nana::size{ 10, 10 } };
|
|
||||||
for (auto & s : impl->options)
|
|
||||||
{
|
|
||||||
auto px = graph.text_extent_size(s).width;
|
|
||||||
if (px > value_px)
|
|
||||||
value_px = px;
|
|
||||||
}
|
|
||||||
value_px += 34;
|
|
||||||
|
|
||||||
impl->combox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
|
impl->combox.create(impl->dock, rectangle{ static_cast<int>(label_px + 10), 0, value_px, 0 });
|
||||||
|
|
||||||
for (auto & s : impl->options)
|
for (auto & s : impl->options)
|
||||||
@ -919,10 +984,10 @@ namespace nana
|
|||||||
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg)
|
impl->dock.events().resized.connect_unignorable([impl, label_px, value_px](const ::nana::arg_resized& arg)
|
||||||
{
|
{
|
||||||
impl->label.size({ label_px, arg.height });
|
impl->label.size({ label_px, arg.height });
|
||||||
if (value_px)
|
if (impl->textbox.empty())
|
||||||
impl->combox.size({ value_px, 24 });
|
impl->combox.move({static_cast<int>(label_px + 10), (static_cast<int>(arg.height) - 25) / 2, value_px, 24 });
|
||||||
else
|
else
|
||||||
impl->textbox.size({arg.width - label_px - 10, 24});
|
impl->textbox.move({ static_cast<int>(label_px + 10), (static_cast<int>(arg.height) - 25) / 2, arg.width - label_px - 10, 24 });
|
||||||
});
|
});
|
||||||
|
|
||||||
auto & wdg = (value_px ? static_cast<widget&>(impl->combox) : static_cast<widget&>(impl->textbox));
|
auto & wdg = (value_px ? static_cast<widget&>(impl->combox) : static_cast<widget&>(impl->textbox));
|
||||||
@ -932,6 +997,24 @@ namespace nana
|
|||||||
});
|
});
|
||||||
return impl->dock;
|
return impl->dock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned inputbox::text::fixed_pixels() const
|
||||||
|
{
|
||||||
|
if (impl_->options.empty())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
paint::graphics graph{ ::nana::size{ 10, 10 } };
|
||||||
|
unsigned long_px = 0;
|
||||||
|
//get the longest value
|
||||||
|
for (auto & s : impl_->options)
|
||||||
|
{
|
||||||
|
auto px = graph.text_extent_size(s).width;
|
||||||
|
if (px > long_px)
|
||||||
|
long_px = px;
|
||||||
|
}
|
||||||
|
|
||||||
|
return long_px + 34;
|
||||||
|
}
|
||||||
//end class text
|
//end class text
|
||||||
|
|
||||||
|
|
||||||
@ -1028,17 +1111,18 @@ namespace nana
|
|||||||
impl->dock.events().resized.connect_unignorable([impl, label_px](const ::nana::arg_resized& arg)
|
impl->dock.events().resized.connect_unignorable([impl, label_px](const ::nana::arg_resized& arg)
|
||||||
{
|
{
|
||||||
impl->label.size({ label_px, arg.height });
|
impl->label.size({ label_px, arg.height });
|
||||||
auto sz = impl->wdg_month.size();
|
|
||||||
sz.height = 24;
|
|
||||||
impl->wdg_month.size(sz);
|
|
||||||
|
|
||||||
sz = impl->wdg_day.size();
|
rectangle rt{static_cast<int>(label_px + 10), (static_cast<int>(arg.height) - 25) / 2, 94, 24};
|
||||||
sz.height = 24;
|
|
||||||
impl->wdg_day.size(sz);
|
|
||||||
|
|
||||||
sz = impl->wdg_year.size();
|
impl->wdg_month.move(rt);
|
||||||
sz.height = 24;
|
|
||||||
impl->wdg_year.size(sz);
|
rt.x += 104;
|
||||||
|
rt.width = 38;
|
||||||
|
impl->wdg_day.move(rt);
|
||||||
|
|
||||||
|
rt.x += 48;
|
||||||
|
rt.width = 50;
|
||||||
|
impl->wdg_year.move(rt);
|
||||||
});
|
});
|
||||||
|
|
||||||
auto destroy_fn = [impl](const arg_destroy& arg)
|
auto destroy_fn = [impl](const arg_destroy& arg)
|
||||||
@ -1152,8 +1236,13 @@ namespace nana
|
|||||||
impl->dock.events().resized.connect_unignorable([impl, label_px](const ::nana::arg_resized& arg)
|
impl->dock.events().resized.connect_unignorable([impl, label_px](const ::nana::arg_resized& arg)
|
||||||
{
|
{
|
||||||
impl->label.size({ label_px, arg.height });
|
impl->label.size({ label_px, arg.height });
|
||||||
impl->path_edit.size({arg.width - label_px - 75, arg.height});
|
|
||||||
impl->browse.move({static_cast<int>(arg.width - 60), 0, 60, arg.height});
|
rectangle rt{ static_cast<int>(label_px)+10, (static_cast<int>(arg.height) - 25), arg.width - label_px - 75, 24};
|
||||||
|
impl->path_edit.move(rt);
|
||||||
|
|
||||||
|
rt.x = static_cast<int>(arg.width - 60);
|
||||||
|
rt.width = 60;
|
||||||
|
impl->browse.move(rt);
|
||||||
});
|
});
|
||||||
|
|
||||||
impl->path_edit.events().destroy.connect_unignorable([impl](const arg_destroy&)
|
impl->path_edit.events().destroy.connect_unignorable([impl](const arg_destroy&)
|
||||||
@ -1199,6 +1288,8 @@ namespace nana
|
|||||||
std::vector<unsigned> each_pixels;
|
std::vector<unsigned> each_pixels;
|
||||||
unsigned label_px = 0, fixed_px = 0;
|
unsigned label_px = 0, fixed_px = 0;
|
||||||
paint::graphics graph({ 5, 5 });
|
paint::graphics graph({ 5, 5 });
|
||||||
|
|
||||||
|
bool has_0_fixed_px = false;
|
||||||
for (auto p : contents)
|
for (auto p : contents)
|
||||||
{
|
{
|
||||||
auto px = label::measure(graph, p->label(), 150, true, align::right, align_v::center);
|
auto px = label::measure(graph, p->label(), 150, true, align::right, align_v::center);
|
||||||
@ -1206,12 +1297,17 @@ namespace nana
|
|||||||
label_px = px.width;
|
label_px = px.width;
|
||||||
|
|
||||||
px.width = p->fixed_pixels();
|
px.width = p->fixed_pixels();
|
||||||
|
has_0_fixed_px |= (px.width == 0);
|
||||||
if (px.width > fixed_px)
|
if (px.width > fixed_px)
|
||||||
fixed_px = px.width;
|
fixed_px = px.width;
|
||||||
|
|
||||||
each_pixels.push_back(px.height);
|
each_pixels.push_back(px.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Adjust the fixed_px for good looking
|
||||||
|
if (has_0_fixed_px && (fixed_px < 100))
|
||||||
|
fixed_px = 100;
|
||||||
|
|
||||||
inputbox_window input_wd(owner_, images_, valid_areas_, description_, title_, contents.size(), label_px + 10 + fixed_px, each_pixels);
|
inputbox_window input_wd(owner_, images_, valid_areas_, description_, title_, contents.size(), label_px + 10 + fixed_px, each_pixels);
|
||||||
|
|
||||||
std::vector<window> inputs;
|
std::vector<window> inputs;
|
||||||
|
@ -659,7 +659,8 @@ namespace nana
|
|||||||
|
|
||||||
std::unique_ptr<model_interface> model_ptr;
|
std::unique_ptr<model_interface> model_ptr;
|
||||||
|
|
||||||
bool expand{true};
|
bool expand{ true };
|
||||||
|
bool display_number{ true };
|
||||||
|
|
||||||
//A cat may have a key object to identify the category
|
//A cat may have a key object to identify the category
|
||||||
std::shared_ptr<nana::detail::key_interface> key_ptr;
|
std::shared_ptr<nana::detail::key_interface> key_ptr;
|
||||||
@ -1938,6 +1939,8 @@ namespace nana
|
|||||||
|
|
||||||
std::unique_ptr<widgets::skeletons::content_view> content_view;
|
std::unique_ptr<widgets::skeletons::content_view> content_view;
|
||||||
|
|
||||||
|
std::function<void(paint::graphics&, const rectangle&, bool)> ctg_icon_renderer; ///< Renderer for the category icon
|
||||||
|
|
||||||
struct mouse_selection_part
|
struct mouse_selection_part
|
||||||
{
|
{
|
||||||
bool started{ false };
|
bool started{ false };
|
||||||
@ -3544,27 +3547,36 @@ namespace nana
|
|||||||
|
|
||||||
color txt_color{ static_cast<color_rgb>(0x3399) };
|
color txt_color{ static_cast<color_rgb>(0x3399) };
|
||||||
|
|
||||||
|
//Area of category icon
|
||||||
|
rectangle rt_ctg_icon{ x + 5, y + static_cast<int>(item_height - 16) / 2, 16, 16 };
|
||||||
|
|
||||||
|
if (essence_->ctg_icon_renderer)
|
||||||
|
{
|
||||||
|
essence_->ctg_icon_renderer(*graph, rt_ctg_icon, categ.expand);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
facade<element::arrow> arrow("double");
|
facade<element::arrow> arrow("double");
|
||||||
arrow.direction(categ.expand ? ::nana::direction::north : ::nana::direction::south);
|
arrow.direction(categ.expand ? ::nana::direction::south : ::nana::direction::east);
|
||||||
arrow.draw( *graph, {}, txt_color,
|
arrow.draw(*graph, {}, txt_color, rt_ctg_icon, element_state::normal);
|
||||||
{ x + 5, y + static_cast<int>(item_height - 16) / 2, 16, 16 },
|
}
|
||||||
element_state::normal);
|
|
||||||
|
|
||||||
graph->string({ x + 20, y + txtoff }, categ.text, txt_color);
|
graph->string({ x + 20, y + txtoff }, categ.text, txt_color);
|
||||||
|
|
||||||
native_string_type str = to_nstring('(' + std::to_string(categ.items.size()) + ')');
|
auto text_px = graph->text_extent_size(categ.text).width;
|
||||||
|
if (categ.display_number)
|
||||||
auto text_s = graph->text_extent_size(categ.text).width;
|
|
||||||
auto extend_text_w = text_s + graph->text_extent_size(str).width;
|
|
||||||
|
|
||||||
graph->string({ x + 25 + static_cast<int>(text_s), y + txtoff }, str);
|
|
||||||
|
|
||||||
if (35 + extend_text_w < width)
|
|
||||||
{
|
{
|
||||||
::nana::point pos{ x + 30 + static_cast<int>(extend_text_w), y + static_cast<int>(item_height) / 2 };
|
//Display the number of items in the category
|
||||||
|
native_string_type str = to_nstring('(' + std::to_string(categ.items.size()) + ')');
|
||||||
|
graph->string({ x + 25 + static_cast<int>(text_px), y + txtoff }, str);
|
||||||
|
text_px += graph->text_extent_size(str).width;
|
||||||
|
}
|
||||||
|
|
||||||
graph->line(pos, { x + static_cast<int>(width) - 5, pos.y },
|
if (35 + text_px < width)
|
||||||
txt_color);
|
{
|
||||||
|
::nana::point pos{ x + 30 + static_cast<int>(text_px), y + static_cast<int>(item_height) / 2 };
|
||||||
|
|
||||||
|
graph->line(pos, { x + static_cast<int>(width) - 5, pos.y }, txt_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Draw selecting inner rectangle
|
//Draw selecting inner rectangle
|
||||||
@ -4814,6 +4826,32 @@ namespace nana
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cat_proxy& cat_proxy::display_number(bool display)
|
||||||
|
{
|
||||||
|
if (cat_->display_number != display)
|
||||||
|
{
|
||||||
|
cat_->display_number = display;
|
||||||
|
ess_->update();
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cat_proxy::expanded() const
|
||||||
|
{
|
||||||
|
return cat_->expand;
|
||||||
|
}
|
||||||
|
|
||||||
|
cat_proxy& cat_proxy::expanded(bool expand)
|
||||||
|
{
|
||||||
|
//The first category isn't allowed to be collapsed
|
||||||
|
if ((expand != cat_->expand) && pos_)
|
||||||
|
{
|
||||||
|
cat_->expand = expand;
|
||||||
|
ess_->update();
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
auto cat_proxy::columns() const -> size_type
|
auto cat_proxy::columns() const -> size_type
|
||||||
{
|
{
|
||||||
return ess_->header.cont().size();
|
return ess_->header.cont().size();
|
||||||
@ -5585,6 +5623,32 @@ namespace nana
|
|||||||
return _m_ess().def_exp_options;
|
return _m_ess().def_exp_options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listbox& listbox::category_icon(std::function<void(paint::graphics& graph, const rectangle& rt_icon, bool expanded)> icon_renderer)
|
||||||
|
{
|
||||||
|
_m_ess().ctg_icon_renderer.swap(icon_renderer);
|
||||||
|
_m_ess().update();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
listbox& listbox::category_icon(const paint::image& img_expanded, const paint::image&& img_collapsed)
|
||||||
|
{
|
||||||
|
_m_ess().ctg_icon_renderer = [img_expanded, img_collapsed](paint::graphics& graph, const rectangle& rt_icon, bool expanded)
|
||||||
|
{
|
||||||
|
if (expanded)
|
||||||
|
{
|
||||||
|
img_expanded.stretch(rectangle{ img_expanded.size() }, graph, rt_icon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
img_collapsed.stretch(rectangle{ img_collapsed.size() }, graph, rt_icon);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_m_ess().update();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
drawerbase::listbox::essence & listbox::_m_ess() const
|
drawerbase::listbox::essence & listbox::_m_ess() const
|
||||||
{
|
{
|
||||||
return get_drawer_trigger().ess();
|
return get_drawer_trigger().ess();
|
||||||
|
@ -35,6 +35,7 @@ namespace nana {
|
|||||||
bool drag_started{ false };
|
bool drag_started{ false };
|
||||||
point origin;
|
point origin;
|
||||||
|
|
||||||
|
scrolls enabled_scrolls{scrolls::both};
|
||||||
nana::scroll<false> horz;
|
nana::scroll<false> horz;
|
||||||
nana::scroll<true> vert;
|
nana::scroll<true> vert;
|
||||||
|
|
||||||
@ -193,7 +194,10 @@ namespace nana {
|
|||||||
|
|
||||||
this->passive = passive;
|
this->passive = passive;
|
||||||
|
|
||||||
if (imd_area.width != disp_area.width)
|
bool const vert_allowed = (enabled_scrolls == scrolls::vert || enabled_scrolls == scrolls::both);
|
||||||
|
bool const horz_allowed = (enabled_scrolls == scrolls::horz || enabled_scrolls == scrolls::both);
|
||||||
|
|
||||||
|
if ((imd_area.width != disp_area.width) && vert_allowed)
|
||||||
{
|
{
|
||||||
if (vert.empty())
|
if (vert.empty())
|
||||||
{
|
{
|
||||||
@ -217,10 +221,14 @@ namespace nana {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
vert.close();
|
vert.close();
|
||||||
|
|
||||||
|
//If vert is allowed, it indicates the vertical origin is not moved
|
||||||
|
//Make sure the v origin is zero
|
||||||
|
if (vert_allowed)
|
||||||
origin.y = 0;
|
origin.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imd_area.height != disp_area.height)
|
if ((imd_area.height != disp_area.height) && horz_allowed)
|
||||||
{
|
{
|
||||||
if (horz.empty())
|
if (horz.empty())
|
||||||
{
|
{
|
||||||
@ -244,6 +252,9 @@ namespace nana {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
horz.close();
|
horz.close();
|
||||||
|
//If horz is allowed, it indicates the horzontal origin is not moved
|
||||||
|
//Make sure the x origin is zero
|
||||||
|
if (horz_allowed)
|
||||||
origin.x = 0;
|
origin.x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,6 +277,16 @@ namespace nana {
|
|||||||
return impl_->events;
|
return impl_->events;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool content_view::enable_scrolls(scrolls which)
|
||||||
|
{
|
||||||
|
if (impl_->enabled_scrolls == which)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
impl_->enabled_scrolls = which;
|
||||||
|
impl_->size_changed(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void content_view::step(unsigned step_value, bool horz)
|
void content_view::step(unsigned step_value, bool horz)
|
||||||
{
|
{
|
||||||
if (horz)
|
if (horz)
|
||||||
@ -383,7 +404,7 @@ namespace nana {
|
|||||||
void content_view::draw_corner(graph_reference graph)
|
void content_view::draw_corner(graph_reference graph)
|
||||||
{
|
{
|
||||||
auto r = corner();
|
auto r = corner();
|
||||||
if(!r.empty())
|
if ((!r.empty()) && (scrolls::both == impl_->enabled_scrolls))
|
||||||
graph.rectangle(r, true, colors::button_face);
|
graph.rectangle(r, true, colors::button_face);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,8 +415,11 @@ namespace nana {
|
|||||||
|
|
||||||
rectangle content_view::view_area(const size& alt_content_size) const
|
rectangle content_view::view_area(const size& alt_content_size) const
|
||||||
{
|
{
|
||||||
unsigned extra_horz = (impl_->disp_area.width < alt_content_size.width ? space() : 0);
|
bool const vert_allowed = (impl_->enabled_scrolls == scrolls::vert || impl_->enabled_scrolls == scrolls::both);
|
||||||
unsigned extra_vert = (impl_->disp_area.height < alt_content_size.height + extra_horz ? space() : 0);
|
bool const horz_allowed = (impl_->enabled_scrolls == scrolls::horz || impl_->enabled_scrolls == scrolls::both);
|
||||||
|
|
||||||
|
unsigned extra_horz = (horz_allowed && (impl_->disp_area.width < alt_content_size.width) ? space() : 0);
|
||||||
|
unsigned extra_vert = (vert_allowed && (impl_->disp_area.height < alt_content_size.height + extra_horz) ? space() : 0);
|
||||||
|
|
||||||
if ((0 == extra_horz) && extra_vert)
|
if ((0 == extra_horz) && extra_vert)
|
||||||
extra_horz = (impl_->disp_area.width < alt_content_size.width + extra_vert ? space() : 0);
|
extra_horz = (impl_->disp_area.width < alt_content_size.width + extra_vert ? space() : 0);
|
||||||
|
@ -40,6 +40,11 @@ namespace skeletons
|
|||||||
public:
|
public:
|
||||||
using graph_reference = paint::graphics&;
|
using graph_reference = paint::graphics&;
|
||||||
|
|
||||||
|
enum class scrolls
|
||||||
|
{
|
||||||
|
none, horz, vert, both
|
||||||
|
};
|
||||||
|
|
||||||
struct events_type
|
struct events_type
|
||||||
{
|
{
|
||||||
::std::function<void(const point&)> hover_outside;
|
::std::function<void(const point&)> hover_outside;
|
||||||
@ -51,6 +56,8 @@ namespace skeletons
|
|||||||
|
|
||||||
events_type& events();
|
events_type& events();
|
||||||
|
|
||||||
|
bool enable_scrolls(scrolls which);
|
||||||
|
|
||||||
void step(unsigned step_value, bool horz);
|
void step(unsigned step_value, bool horz);
|
||||||
bool scroll(bool forwards, bool horz);
|
bool scroll(bool forwards, bool horz);
|
||||||
bool turn_page(bool forwards, bool horz);
|
bool turn_page(bool forwards, bool horz);
|
||||||
|
@ -497,6 +497,7 @@ namespace nana{ namespace widgets
|
|||||||
undoable<command> undo; //undo command
|
undoable<command> undo; //undo command
|
||||||
renderers customized_renderers;
|
renderers customized_renderers;
|
||||||
std::vector<upoint> text_position; //positions of text since last rendering.
|
std::vector<upoint> text_position; //positions of text since last rendering.
|
||||||
|
int text_position_origin{ -1 }; //origin when last text_exposed
|
||||||
|
|
||||||
skeletons::textbase<wchar_t> textbase;
|
skeletons::textbase<wchar_t> textbase;
|
||||||
|
|
||||||
@ -1083,6 +1084,11 @@ namespace nana{ namespace widgets
|
|||||||
return { 1, line_height() };
|
return { 1, line_height() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const point& text_editor::content_origin() const
|
||||||
|
{
|
||||||
|
return impl_->cview->origin();
|
||||||
|
}
|
||||||
|
|
||||||
void text_editor::set_highlight(const std::string& name, const ::nana::color& fgcolor, const ::nana::color& bgcolor)
|
void text_editor::set_highlight(const std::string& name, const ::nana::color& fgcolor, const ::nana::color& bgcolor)
|
||||||
{
|
{
|
||||||
if (fgcolor.invisible() && bgcolor.invisible())
|
if (fgcolor.invisible() && bgcolor.invisible())
|
||||||
@ -1337,6 +1343,10 @@ namespace nana{ namespace widgets
|
|||||||
line_wrapped(false);
|
line_wrapped(false);
|
||||||
|
|
||||||
_m_reset_content_size();
|
_m_reset_content_size();
|
||||||
|
impl_->cview->enable_scrolls(ml ? content_view::scrolls::both : content_view::scrolls::none);
|
||||||
|
impl_->cview->move_origin(point{} -impl_->cview->origin());
|
||||||
|
|
||||||
|
impl_->try_refresh = sync_graph::refresh;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1978,8 +1988,9 @@ namespace nana{ namespace widgets
|
|||||||
if (text_pos.empty())
|
if (text_pos.empty())
|
||||||
text_pos.emplace_back(upoint{});
|
text_pos.emplace_back(upoint{});
|
||||||
|
|
||||||
if (text_pos != impl_->text_position)
|
if ((impl_->text_position_origin != impl_->cview->origin().y) || (text_pos != impl_->text_position))
|
||||||
{
|
{
|
||||||
|
impl_->text_position_origin = impl_->cview->origin().y;
|
||||||
impl_->text_position.swap(text_pos);
|
impl_->text_position.swap(text_pos);
|
||||||
if (event_handler_)
|
if (event_handler_)
|
||||||
event_handler_->text_exposed(impl_->text_position);
|
event_handler_->text_exposed(impl_->text_position);
|
||||||
@ -3350,32 +3361,37 @@ namespace nana{ namespace widgets
|
|||||||
line_px_( editor.line_height() )
|
line_px_( editor.line_height() )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
color selection_text_color(bool has_focused) const
|
color selection_color(bool fgcolor, bool focused) const
|
||||||
{
|
{
|
||||||
return (has_focused ? editor_.scheme_->selection_text : editor_.scheme_->foreground).get_color();
|
if (fgcolor)
|
||||||
|
return (focused ? editor_.scheme_->selection_text : editor_.scheme_->foreground).get_color();
|
||||||
|
|
||||||
|
return (focused ? editor_.scheme_->selection : editor_.scheme_->selection_unfocused).get_color();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_selection(const point& text_pos, unsigned text_px, const wchar_t* text, std::size_t len, bool has_focused)
|
void write_selection(const point& text_pos, unsigned text_px, const wchar_t* text, std::size_t len, bool has_focused)
|
||||||
{
|
{
|
||||||
graph_.palette(true, selection_text_color(has_focused));
|
graph_.palette(true, selection_color(true, has_focused));
|
||||||
|
|
||||||
graph_.rectangle(::nana::rectangle{ text_pos, { text_px, line_px_ } }, true,
|
graph_.rectangle(::nana::rectangle{ text_pos, { text_px, line_px_ } }, true,
|
||||||
has_focused ? editor_.scheme_->selection.get_color() : editor_.scheme_->selection_unfocused.get_color());
|
selection_color(false, has_focused));
|
||||||
|
|
||||||
graph_.string(text_pos, text, len);
|
graph_.string(text_pos, text, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtl_string(point strpos, const wchar_t* str, std::size_t len, std::size_t str_px, unsigned glyph_front, unsigned glyph_selected, bool has_focused)
|
void rtl_string(point strpos, const wchar_t* str, std::size_t len, std::size_t str_px, unsigned glyph_front, unsigned glyph_selected, bool has_focused)
|
||||||
{
|
{
|
||||||
editor_._m_draw_parse_string(parser_, true, strpos, selection_text_color(has_focused), str, len);
|
editor_._m_draw_parse_string(parser_, true, strpos, selection_color(true, has_focused), str, len);
|
||||||
|
|
||||||
//Draw selected part
|
//Draw selected part
|
||||||
paint::graphics graph({ glyph_selected, line_px_ });
|
paint::graphics graph({ glyph_selected, line_px_ });
|
||||||
graph.typeface(this->graph_.typeface());
|
graph.typeface(this->graph_.typeface());
|
||||||
graph.rectangle(true, (has_focused ? editor_.scheme_->selection.get_color() : editor_.scheme_->selection_unfocused.get_color()));
|
graph.rectangle(true, selection_color(false, has_focused));
|
||||||
|
|
||||||
int sel_xpos = static_cast<int>(str_px - (glyph_front + glyph_selected));
|
int sel_xpos = static_cast<int>(str_px - (glyph_front + glyph_selected));
|
||||||
|
|
||||||
graph.palette(true, selection_text_color(has_focused));
|
graph.palette(true, selection_color(true, has_focused));
|
||||||
|
|
||||||
graph.string({ -sel_xpos, 0 }, str, len);
|
graph.string({ -sel_xpos, 0 }, str, len);
|
||||||
graph_.bitblt(nana::rectangle(strpos.x + sel_xpos, strpos.y, glyph_selected, line_px_), graph);
|
graph_.bitblt(nana::rectangle(strpos.x + sel_xpos, strpos.y, glyph_selected, line_px_), graph);
|
||||||
};
|
};
|
||||||
|
@ -269,6 +269,15 @@ namespace drawerbase {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
point textbox::content_origin() const
|
||||||
|
{
|
||||||
|
auto editor = get_drawer_trigger().editor();
|
||||||
|
if (editor)
|
||||||
|
return editor->content_origin();
|
||||||
|
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
|
||||||
/// Enables/disables the textbox to indent a line. Idents a new line when it is created by pressing enter.
|
/// Enables/disables the textbox to indent a line. Idents a new line when it is created by pressing enter.
|
||||||
/// @param generator generates text for identing a line. If it is empty, textbox indents the line according to last line.
|
/// @param generator generates text for identing a line. If it is empty, textbox indents the line according to last line.
|
||||||
textbox& textbox::indention(bool enb, std::function<std::string()> generator)
|
textbox& textbox::indention(bool enb, std::function<std::string()> generator)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user