Merge branch 'develop' of https://github.com/beru/nana into beru-develop

Conflicts:
	source/gui/widgets/skeletons/text_editor.cpp
	source/gui/widgets/textbox.cpp
	source/paint/detail/image_bmp.hpp
	source/paint/detail/image_ico.hpp
This commit is contained in:
Jinhao
2015-08-01 22:08:06 +08:00
22 changed files with 322 additions and 46 deletions

View File

@@ -537,6 +537,30 @@ namespace nana{
return false;
}
bool native_interface::window_icon(native_window_type wd, const paint::image& big_icon, const paint::image& small_icon)
{
#if defined(NANA_WINDOWS)
HICON h_big_icon = paint::image_accessor::icon(big_icon);
HICON h_small_icon = paint::image_accessor::icon(small_icon);
if (h_big_icon || h_small_icon)
{
nana::detail::platform_spec::instance().keep_window_icon(wd, (!big_icon.empty() ? big_icon : small_icon));
if (h_big_icon) {
::SendMessage(reinterpret_cast<HWND>(wd), WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(h_big_icon));
}
if (h_small_icon) {
::SendMessage(reinterpret_cast<HWND>(wd), WM_SETICON, ICON_SMALL, reinterpret_cast<WPARAM>(h_small_icon));
}
return true;
}
#elif defined(NANA_X11)
return window_icon(wd, big_icon);
#endif
return false;
}
void native_interface::activate_owner(native_window_type wd)
{
#if defined(NANA_WINDOWS)

View File

@@ -1413,6 +1413,7 @@ namespace detail
auto tstop_wd = brock.wd_manager.tabstop(msgwnd, is_forward);
if (tstop_wd)
{
root_runtime->condition.tabstop_focus_changed = true;
brock.wd_manager.set_focus(tstop_wd, false);
brock.wd_manager.do_lazy_refresh(msgwnd, false);
brock.wd_manager.do_lazy_refresh(tstop_wd, true);

View File

@@ -42,7 +42,8 @@ namespace detail
{
root_register misc_register;
handle_manager<core_window_t*, window_manager, window_handle_deleter> wd_register;
paint::image default_icon;
paint::image default_icon_big;
paint::image default_icon_small;
};
//end struct wdm_private_impl
@@ -182,11 +183,6 @@ namespace detail
}
}
void window_manager::default_icon(const paint::image& img)
{
impl_->default_icon = img;
}
bool window_manager::available(core_window_t* wd)
{
return impl_->wd_register.available(wd);
@@ -218,7 +214,7 @@ namespace detail
if (impl_->wd_register.available(owner))
{
native = (owner->other.category == category::frame_tag::value ?
owner->other.attribute.frame->container : owner->root_widget->root);
owner->other.attribute.frame->container : owner->root_widget->root);
r.x += owner->pos_root.x;
r.y += owner->pos_root.y;
}
@@ -247,7 +243,7 @@ namespace detail
insert_frame(owner, wd);
bedrock::inc_window(wd->thread_id);
this->icon(wd, impl_->default_icon);
this->icon(wd, impl_->default_icon_big, impl_->default_icon_small);
return wd;
}
return nullptr;
@@ -394,6 +390,18 @@ namespace detail
}
}
void window_manager::default_icon(const paint::image& img)
{
impl_->default_icon_big = img;
impl_->default_icon_small = img;
}
void window_manager::default_icon(const nana::paint::image& big, const nana::paint::image& small)
{
impl_->default_icon_big = big;
impl_->default_icon_small = small;
}
void window_manager::icon(core_window_t* wd, const paint::image& img)
{
if(false == img.empty())
@@ -407,6 +415,19 @@ namespace detail
}
}
void window_manager::icon(core_window_t* wd, const paint::image& big_icon, const paint::image& small_icon)
{
if(!big_icon.empty() || !small_icon.empty())
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
if (impl_->wd_register.available(wd))
{
if(wd->other.category == category::root_tag::value)
native_interface::window_icon(wd->root, big_icon, small_icon);
}
}
}
//show
//@brief: show or hide a window
bool window_manager::show(core_window_t* wd, bool visible)

View File

@@ -1021,6 +1021,7 @@ namespace nana
if (!impl_->open_or_save)
ofn.Flags = OFN_OVERWRITEPROMPT; //Overwrite prompt if it is save mode
ofn.Flags |= OFN_NOCHANGEDIR;
if(FALSE == (impl_->open_or_save ? ::GetOpenFileName(&ofn) : ::GetSaveFileName(&ofn)))
return false;

View File

@@ -359,11 +359,21 @@ namespace API
restrict::window_manager.default_icon(img);
}
void window_icon_default(const paint::image& big_icon, const paint::image& small_icon)
{
restrict::window_manager.default_icon(big_icon, small_icon);
}
void window_icon(window wd, const paint::image& img)
{
restrict::window_manager.icon(reinterpret_cast<restrict::core_window_t*>(wd), img);
}
void window_icon(window wd, const paint::image& big_icon, const paint::image& small_icon)
{
restrict::window_manager.icon(reinterpret_cast<restrict::core_window_t*>(wd), big_icon, small_icon);
}
bool empty_window(window wd)
{
return (restrict::window_manager.available(reinterpret_cast<restrict::core_window_t*>(wd)) == false);

View File

@@ -684,7 +684,7 @@ namespace nana
{
case keyboard::os_arrow_left:
case keyboard::os_arrow_right:
drawer_->editor()->respond_key(arg.key);
drawer_->editor()->respond_key(arg);
drawer_->editor()->reset_caret();
break;
case keyboard::os_arrow_up:
@@ -713,14 +713,14 @@ namespace nana
}
}
if (call_other_keys)
drawer_->editor()->respond_key(arg.key);
drawer_->editor()->respond_key(arg);
API::lazy_refresh();
}
void trigger::key_char(graph_reference graph, const arg_keyboard& arg)
{
if (drawer_->editor()->respond_char(arg.key))
if (drawer_->editor()->respond_char(arg))
API::lazy_refresh();
}
//end class trigger

View File

@@ -628,6 +628,8 @@ namespace nana
nana::string target; //It indicates which target is tracing.
nana::string url;
widget * buddy {nullptr};
void add_listener(std::function<void(command, const nana::string&)>&& fn)
{
listener_.emplace_back(std::move(fn));
@@ -740,6 +742,10 @@ namespace nana
impl_->call_listener(command::click, impl_->target);
system::open_url(url);
if (impl_->buddy) {
impl_->buddy->focus();
}
}
void trigger::refresh(graph_reference graph)
@@ -821,6 +827,11 @@ namespace nana
return *this;
}
void label::relate(widget& w)
{
get_drawer_trigger().impl()->buddy = &w;
}
nana::size label::measure(unsigned limited) const
{
if(empty())

View File

@@ -461,6 +461,7 @@ namespace nana{ namespace widgets
editor_._m_scrollbar();
return (adjusted_cond || adjusted_cond2);
}
private:
std::size_t _m_textline_from_screen(int y) const
{
@@ -1349,8 +1350,9 @@ namespace nana{ namespace widgets
attributes_.acceptive = acceptive;
}
bool text_editor::respond_char(char_type key) //key is a character of ASCII code
bool text_editor::respond_char(const arg_keyboard& arg) //key is a character of ASCII code
{
char_type key = arg.key;
switch (key)
{
case keyboard::end_of_text:
@@ -1400,14 +1402,28 @@ namespace nana{ namespace widgets
return false;
}
bool text_editor::respond_key(char_type key)
bool text_editor::respond_key(const arg_keyboard& arg)
{
char_type key = arg.key;
switch (key)
{
#if 0
case keyboard::os_arrow_left: move_left(); break;
case keyboard::os_arrow_right: move_right(); break;
case keyboard::os_arrow_up: move_ns(true); break;
case keyboard::os_arrow_down: move_ns(false); break;
#else
case keyboard::os_arrow_left:
case keyboard::os_arrow_right:
case keyboard::os_arrow_up:
case keyboard::os_arrow_down:
case keyboard::os_home:
case keyboard::os_end:
case keyboard::os_pageup:
case keyboard::os_pagedown:
_handle_move_key(arg);
break;
#endif
case keyboard::os_del:
if (this->attr().editable)
del();
@@ -1605,17 +1621,12 @@ namespace nana{ namespace widgets
//Set caret pos by screen point and get the caret pos.
auto pos = mouse_caret(scrpos);
if(!hit_select_area(pos))
if(!select(false))
{
if(!select(false))
{
select_.a = points_.caret; //Set begin caret
set_end_caret();
}
select_.mode_selection = selection::mode_mouse_selected;
select_.a = points_.caret; //Set begin caret
set_end_caret();
}
else
select_.mode_selection = selection::mode_no_selected;
select_.mode_selection = selection::mode_mouse_selected;
}
text_area_.border_renderer(graph_, _m_bgcolor());
@@ -2219,6 +2230,136 @@ namespace nana{ namespace widgets
points_.xpos = points_.caret.x;
}
void text_editor::_handle_move_key(const arg_keyboard& arg)
{
bool changed = false;
nana::upoint caret = points_.caret;
char_t key = arg.key;
size_t nlines = textbase_.lines();
if (arg.ctrl) {
switch (key) {
case keyboard::os_arrow_left:
case keyboard::os_arrow_right:
// TODO: move the caret word by word
break;
case keyboard::os_home:
if (caret.y != 0) {
caret.y = 0;
points_.offset.y = 0;
changed = true;
}
break;
case keyboard::os_end:
if (caret.y != nlines - 1) {
caret.y = nlines - 1;
changed = true;
}
break;
}
}
size_t lnsz = textbase_.getline(caret.y).size();
switch (key) {
case keyboard::os_arrow_left:
if (caret.x != 0) {
--caret.x;
changed = true;
}else {
if (caret.y != 0) {
--caret.y;
caret.x = textbase_.getline(caret.y).size();
changed = true;
}
}
break;
case keyboard::os_arrow_right:
if (caret.x < lnsz) {
++caret.x;
changed = true;
}else {
if (caret.y != nlines - 1) {
++caret.y;
caret.x = 0;
changed = true;
}
}
break;
case keyboard::os_arrow_up:
case keyboard::os_arrow_down:
{
auto screen_pt = behavior_->caret_to_screen(caret);
int offset = line_height();
if (key == keyboard::os_arrow_up) {
offset = -offset;
}
screen_pt.y += offset;
auto new_caret = behavior_->screen_to_caret(screen_pt);
if (new_caret != caret) {
caret = new_caret;
if (screen_pt.y < 0) {
scroll(true, true);
}
changed = true;
}
}
break;
case keyboard::os_home:
if (caret.x != 0) {
caret.x = 0;
changed = true;
}
break;
case keyboard::os_end:
if (caret.x < lnsz) {
caret.x = lnsz;
changed = true;
}
break;
case keyboard::os_pageup:
if (caret.y >= (int)screen_lines() && points_.offset.y >= (int)screen_lines()) {
points_.offset.y -= screen_lines();
caret.y -= screen_lines();
changed = true;
}
break;
case keyboard::os_pagedown:
if (caret.y + screen_lines() <= behavior_->take_lines()) {
points_.offset.y += screen_lines();
caret.y += screen_lines();
changed = true;
}
break;
}
if (select_.a != caret || select_.b != caret) {
changed = true;
}
if (changed) {
if (arg.shift) {
switch (key) {
case keyboard::os_arrow_left:
case keyboard::os_arrow_up:
case keyboard::os_home:
case keyboard::os_pageup:
select_.b = caret;
break;
case keyboard::os_arrow_right:
case keyboard::os_arrow_down:
case keyboard::os_end:
case keyboard::os_pagedown:
select_.b = caret;
break;
}
}else {
select_.b = caret;
select_.a = caret;
}
points_.caret = caret;
behavior_->adjust_caret_into_screen();
render(true);
_m_scrollbar();
points_.xpos = points_.caret.x;
}
}
nana::upoint text_editor::mouse_caret(const point& scrpos) //From screen position
{
points_.caret = behavior_->screen_to_caret(scrpos);
@@ -2826,6 +2967,8 @@ namespace nana{ namespace widgets
if (if_mask && mask_char_)
mask_str.reset(new nana::string(str.size(), mask_char_));
bool focused = API::is_focus_ready(window_); // do this many times is not efficient...
auto & linestr = (if_mask && mask_char_ ? *mask_str : str);
unicode_bidi bidi;
@@ -2847,7 +2990,7 @@ namespace nana{ namespace widgets
graph_.set_color(scheme_->selection.get_color());
//The text is not selected or the whole line text is selected
if ((!_m_get_sort_select_points(a, b)) || (select_.a.y != str_pos.y && select_.b.y != str_pos.y))
if (!focused || (!_m_get_sort_select_points(a, b)) || (select_.a.y != str_pos.y && select_.b.y != str_pos.y))
{
bool selected = (a.y < str_pos.y && str_pos.y < b.y);
for (auto & ent : reordered)
@@ -2857,7 +3000,7 @@ namespace nana{ namespace widgets
if ((text_pos.x + static_cast<int>(str_w) > text_area_.area.x) && (text_pos.x < xend))
{
if (selected)
if (selected && focused)
{
graph_.set_text_color(scheme_->selection_text.get_color());
graph_.rectangle(::nana::rectangle{ text_pos, { str_w, line_h_pixels } }, true);

View File

@@ -560,7 +560,7 @@ namespace nana
void drawer::key_press(graph_reference, const arg_keyboard& arg)
{
if (impl_->editor()->respond_key(arg.key))
if (impl_->editor()->respond_key(arg))
{
impl_->editor()->reset_caret();
impl_->draw_spins();
@@ -570,7 +570,7 @@ namespace nana
void drawer::key_char(graph_reference, const arg_keyboard& arg)
{
if (impl_->editor()->respond_char(arg.key))
if (impl_->editor()->respond_char(arg))
{
if (!impl_->value(impl_->editor()->text()))
impl_->draw_spins();

View File

@@ -15,6 +15,9 @@
#include <stdexcept>
#include <sstream>
#include <nana/gui/detail/bedrock.hpp>
#include <nana/gui/detail/inner_fwd_implement.hpp>
namespace nana
{
arg_textbox::arg_textbox(textbox& wdg)
@@ -89,7 +92,17 @@ namespace drawerbase {
void drawer::focus(graph_reference graph, const arg_focus& arg)
{
refresh(graph);
if (!editor_->attr().multi_lines && arg.getting)
{
static auto& brock = detail::bedrock::instance();
auto native_window = reinterpret_cast<native_window_type>(arg.receiver);
auto* root_runtime = brock.wd_manager.root_runtime(native_window);
if (root_runtime && root_runtime->condition.tabstop_focus_changed)
{
editor_->select(true);
editor_->move_caret_end();
}
}
editor_->show_caret(arg.getting);
editor_->reset_caret();
API::lazy_refresh();
@@ -136,7 +149,7 @@ namespace drawerbase {
void drawer::key_press(graph_reference, const arg_keyboard& arg)
{
if(editor_->respond_key(arg.key))
if(editor_->respond_key(arg))
{
editor_->reset_caret();
API::lazy_refresh();
@@ -145,7 +158,7 @@ namespace drawerbase {
void drawer::key_char(graph_reference, const arg_keyboard& arg)
{
if (editor_->respond_char(arg.key))
if (editor_->respond_char(arg))
API::lazy_refresh();
}