improve all widgets for bground effects
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* A Drawer Implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -297,9 +297,8 @@ namespace nana
|
||||
if (data_impl_->realizer && !data_impl_->refreshing)
|
||||
{
|
||||
data_impl_->refreshing = true;
|
||||
_m_effect_bground(true);
|
||||
data_impl_->realizer->refresh(graphics);
|
||||
_m_effect_bground(false);
|
||||
_m_effect_bground_subsequent();
|
||||
graphics.flush();
|
||||
data_impl_->refreshing = false;
|
||||
}
|
||||
@@ -372,27 +371,20 @@ namespace nana
|
||||
}
|
||||
}
|
||||
|
||||
void drawer::_m_effect_bground(bool before)
|
||||
void drawer::_m_effect_bground_subsequent()
|
||||
{
|
||||
auto & effect = data_impl_->window_handle->effect;
|
||||
|
||||
for (auto * dw : data_impl_->draws)
|
||||
dw->draw(graphics);
|
||||
|
||||
auto & effect = data_impl_->window_handle->effect;
|
||||
|
||||
if (effect.bground)
|
||||
{
|
||||
if (before)
|
||||
{
|
||||
if (effect.bground_fade_rate < 0.01)
|
||||
data_impl_->window_handle->other.glass_buffer.paste(graphics, 0, 0);
|
||||
}
|
||||
else if (effect.bground_fade_rate >= 0.01)
|
||||
if (effect.bground_fade_rate >= 0.01)
|
||||
data_impl_->window_handle->other.glass_buffer.blend(::nana::rectangle{ data_impl_->window_handle->other.glass_buffer.size() }, graphics, nana::point(), effect.bground_fade_rate);
|
||||
}
|
||||
}
|
||||
|
||||
bool drawer::_m_lazy_decleared() const
|
||||
{
|
||||
return (basic_window::update_state::refreshed == data_impl_->window_handle->other.upd_state);
|
||||
|
||||
}
|
||||
|
||||
drawer::method_state& drawer::_m_mth_state(int pos)
|
||||
|
||||
@@ -155,6 +155,12 @@ namespace API
|
||||
}
|
||||
}
|
||||
|
||||
void effects_bground(std::initializer_list<window> wdgs, const effects::bground_factory_interface& factory, double fade_rate)
|
||||
{
|
||||
for (auto wd : wdgs)
|
||||
effects_bground(wd, factory, fade_rate);
|
||||
}
|
||||
|
||||
bground_mode effects_bground_mode(window wd)
|
||||
{
|
||||
auto const iwd = reinterpret_cast<basic_window*>(wd);
|
||||
@@ -329,6 +335,32 @@ namespace API
|
||||
iwd->flags.space_click_enabled = enable;
|
||||
}
|
||||
|
||||
bool copy_transparent_background(window wd, paint::graphics& graph)
|
||||
{
|
||||
auto & buf = reinterpret_cast<basic_window*>(wd)->other.glass_buffer;
|
||||
internal_scope_guard lock;
|
||||
|
||||
if (bground_mode::basic != API::effects_bground_mode(wd))
|
||||
return false;
|
||||
|
||||
buf.paste(rectangle{ buf.size() }, graph, 0, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool copy_transparent_background(window wd, const rectangle& src_r, paint::graphics& graph, const point& dst_pt)
|
||||
{
|
||||
auto iwd = reinterpret_cast<basic_window*>(wd);
|
||||
internal_scope_guard lock;
|
||||
|
||||
if (bground_mode::basic != API::effects_bground_mode(wd))
|
||||
return false;
|
||||
|
||||
iwd->other.glass_buffer.paste(src_r, graph, dst_pt.x, dst_pt.y);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void lazy_refresh()
|
||||
{
|
||||
restrict::bedrock.thread_context_lazy_refresh();
|
||||
@@ -469,6 +501,11 @@ namespace API
|
||||
}
|
||||
}
|
||||
|
||||
bool is_transparent_background(window wd)
|
||||
{
|
||||
return (bground_mode::basic == effects_bground_mode(wd));
|
||||
}
|
||||
|
||||
native_window_type root(window wd)
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace nana{ namespace drawerbase
|
||||
|
||||
if (false == cite_.draw(graph, attr_.bgcolor, attr_.fgcolor, ::nana::rectangle{ graph.size() }, e_state))
|
||||
{
|
||||
if (bground_mode::basic != API::effects_bground_mode(wdg_->handle()))
|
||||
if (!API::is_transparent_background(*wdg_))
|
||||
{
|
||||
_m_draw_background(graph);
|
||||
_m_draw_border(graph);
|
||||
@@ -492,7 +492,7 @@ namespace nana{ namespace drawerbase
|
||||
|
||||
bool button::transparent() const
|
||||
{
|
||||
return (bground_mode::basic == API::effects_bground_mode(*this));
|
||||
return API::is_transparent_background(*this);
|
||||
}
|
||||
|
||||
button& button::edge_effects(bool enable)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* A CheckBox Implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -55,7 +55,7 @@ namespace nana{ namespace drawerbase
|
||||
auto wdg = impl_->widget_ptr;
|
||||
|
||||
//draw background
|
||||
if (bground_mode::basic != API::effects_bground_mode(*wdg))
|
||||
if (!API::dev::copy_transparent_background(*wdg, graph))
|
||||
graph.rectangle(true, wdg->bgcolor());
|
||||
|
||||
//draw title
|
||||
@@ -193,7 +193,7 @@ namespace nana{ namespace drawerbase
|
||||
|
||||
bool checkbox::transparent() const
|
||||
{
|
||||
return (bground_mode::basic == API::effects_bground_mode(*this));
|
||||
return API::is_transparent_background(*this);
|
||||
}
|
||||
//end class checkbox
|
||||
|
||||
|
||||
@@ -193,6 +193,7 @@ namespace nana
|
||||
if(r.width > place) r.width -= place;
|
||||
}
|
||||
editor_->text_area(r);
|
||||
editor_->render(state_.focused);
|
||||
}
|
||||
|
||||
widgets::skeletons::text_editor * editor() const
|
||||
@@ -233,6 +234,12 @@ namespace nana
|
||||
}
|
||||
|
||||
graph.gradual_rectangle(::nana::rectangle(graph.size()).pare_off(pare_off_px), clr_from, clr_to, true);
|
||||
if (API::is_transparent_background(this->widget_ptr()->handle()))
|
||||
{
|
||||
paint::graphics trns_graph{ graph.size() };
|
||||
if (API::dev::copy_transparent_background(this->widget_ptr()->handle(), trns_graph))
|
||||
trns_graph.blend(rectangle{ trns_graph.size() }, graph, { 0, 0 }, 0.5);
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
@@ -362,7 +369,6 @@ namespace nana
|
||||
if(editor_)
|
||||
{
|
||||
text_area(widget_->size());
|
||||
editor_->render(state_.focused);
|
||||
}
|
||||
_m_draw_push_button(enb);
|
||||
_m_draw_image();
|
||||
@@ -397,7 +403,8 @@ namespace nana
|
||||
if (calc_where(*graph_, pos.x, pos.y))
|
||||
state_.button_state = element_state::normal;
|
||||
|
||||
editor_->text(::nana::charset(items_[index]->item_text, ::nana::unicode::utf8), false);
|
||||
editor_->text(to_wstring(items_[index]->item_text), false);
|
||||
editor_->try_refresh();
|
||||
_m_draw_push_button(widget_->enabled());
|
||||
_m_draw_image();
|
||||
|
||||
@@ -511,9 +518,10 @@ namespace nana
|
||||
facade<element::button> button;
|
||||
button.draw(*graph_, ::nana::color{ 3, 65, 140 }, colors::white, r, estate);
|
||||
|
||||
facade<element::arrow> arrow("solid_triangle");
|
||||
facade<element::arrow> arrow;// ("solid_triangle");
|
||||
arrow.direction(::nana::direction::south);
|
||||
|
||||
r.x += 4;
|
||||
r.y += (r.height / 2) - 7;
|
||||
r.width = r.height = 16;
|
||||
arrow.draw(*graph_, {}, colors::white, r, element_state::normal);
|
||||
@@ -664,7 +672,6 @@ namespace nana
|
||||
|
||||
void trigger::mouse_down(graph_reference, const arg_mouse& arg)
|
||||
{
|
||||
//drawer_->set_mouse_press(true);
|
||||
drawer_->set_button_state(element_state::pressed, false);
|
||||
if(drawer_->widget_ptr()->enabled())
|
||||
{
|
||||
@@ -762,12 +769,14 @@ namespace nana
|
||||
if (call_other_keys)
|
||||
drawer_->editor()->respond_key(arg);
|
||||
|
||||
drawer_->editor()->try_refresh();
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
|
||||
void trigger::key_char(graph_reference, const arg_keyboard& arg)
|
||||
{
|
||||
if (drawer_->editor()->respond_char(arg))
|
||||
drawer_->editor()->respond_char(arg);
|
||||
if (drawer_->editor()->try_refresh())
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
//end class trigger
|
||||
|
||||
@@ -784,7 +784,7 @@ namespace nana
|
||||
if(nullptr == impl_->wd) return;
|
||||
|
||||
window wd = impl_->wd->handle();
|
||||
if(bground_mode::basic != API::effects_bground_mode(wd))
|
||||
if (!API::dev::copy_transparent_background(wd, graph))
|
||||
graph.rectangle(true, API::bgcolor(wd));
|
||||
|
||||
impl_->renderer.render(graph, API::fgcolor(wd), impl_->text_align, impl_->text_align_v);
|
||||
@@ -830,7 +830,7 @@ namespace nana
|
||||
|
||||
bool label::transparent() const throw()
|
||||
{
|
||||
return (bground_mode::basic == API::effects_bground_mode(*this));
|
||||
return API::is_transparent_background(*this);
|
||||
}
|
||||
|
||||
label& label::format(bool f)
|
||||
|
||||
@@ -3168,7 +3168,10 @@ namespace nana
|
||||
if (column_r.x < r.right())
|
||||
{
|
||||
column_r.width = (r.right() - column_r.x);
|
||||
graph.rectangle(column_r, true, essence_->scheme_ptr->header_bgcolor);
|
||||
if(API::dev::copy_transparent_background(essence_->listbox_ptr->handle(), column_r, graph, column_r.position()))
|
||||
graph.blend(column_r, essence_->scheme_ptr->header_bgcolor, 0.8);
|
||||
else
|
||||
graph.rectangle(column_r, true, essence_->scheme_ptr->header_bgcolor);
|
||||
}
|
||||
|
||||
const int y = r.bottom() - 1;
|
||||
@@ -3229,7 +3232,15 @@ namespace nana
|
||||
case item_state::floated: bgcolor = essence_->scheme_ptr->header_floated.get_color(); break;
|
||||
}
|
||||
|
||||
graph.gradual_rectangle(column_r, bgcolor.blend(colors::white, 0.9), bgcolor.blend(colors::black, 0.9), true);
|
||||
if(API::dev::copy_transparent_background(essence_->listbox_ptr->handle(), column_r, graph, column_r.position()))
|
||||
{
|
||||
paint::graphics grad_graph{column_r.dimension()};
|
||||
grad_graph.gradual_rectangle(rectangle{column_r.dimension()}, bgcolor.blend(colors::white, 0.1), bgcolor.blend(colors::black, 0.1), true);
|
||||
|
||||
grad_graph.blend(rectangle{column_r.dimension()}, graph, column_r.position(), 0.3);
|
||||
}
|
||||
else
|
||||
graph.gradual_rectangle(column_r, bgcolor.blend(colors::white, 0.9), bgcolor.blend(colors::black, 0.9), true);
|
||||
|
||||
paint::aligner text_aligner{ graph, column.alignment, column.alignment };
|
||||
|
||||
@@ -3329,23 +3340,28 @@ namespace nana
|
||||
essence_->graph->palette(false, bgcolor);
|
||||
|
||||
auto const header_w = essence_->header.pixels();
|
||||
auto const item_height_px = essence_->item_height();
|
||||
|
||||
auto origin = essence_->content_view->origin();
|
||||
if (header_w < origin.x + rect.width)
|
||||
essence_->graph->rectangle(rectangle{ point{ rect.x + static_cast<int>(header_w) - origin.x, rect.y },
|
||||
size{ rect.width + origin.x - header_w, rect.height } }, true);
|
||||
{
|
||||
rectangle r{ point{ rect.x + static_cast<int>(header_w)-origin.x, rect.y },
|
||||
size{ rect.width + origin.x - header_w, rect.height } };
|
||||
|
||||
if (!API::dev::copy_transparent_background(essence_->listbox_ptr->handle(), r, *essence_->graph, r.position()))
|
||||
essence_->graph->rectangle(r, true);
|
||||
}
|
||||
|
||||
es_lister & lister = essence_->lister;
|
||||
|
||||
auto & ptr_where = essence_->pointer_where;
|
||||
|
||||
int item_top = rect.y - (origin.y % essence_->item_height());
|
||||
int item_top = rect.y - (origin.y % item_height_px);
|
||||
auto first_disp = essence_->first_display();
|
||||
|
||||
// The first display is empty when the listbox is empty.
|
||||
if (!first_disp.empty())
|
||||
{
|
||||
|
||||
index_pair hoverred_pos(npos, npos); //the hoverred item.
|
||||
|
||||
//if where == lister || where == checker, 'second' indicates the offset to the relative display-order pos of the scroll offset_y which stands for the first item to be displayed in lister.
|
||||
@@ -3397,7 +3413,7 @@ namespace nana
|
||||
(hoverred_pos == idx ? item_state::highlighted : item_state::normal)
|
||||
);
|
||||
|
||||
item_top += essence_->item_height();
|
||||
item_top += item_height_px;
|
||||
}
|
||||
|
||||
++i_categ;
|
||||
@@ -3414,7 +3430,7 @@ namespace nana
|
||||
_m_draw_categ(*i_categ, rect.x - origin.x, item_top, txtoff, header_w, rect, bgcolor,
|
||||
(hoverred_pos.is_category() && (idx.cat == hoverred_pos.cat) ? item_state::highlighted : item_state::normal)
|
||||
);
|
||||
item_top += essence_->item_height();
|
||||
item_top += item_height_px;
|
||||
|
||||
if (false == i_categ->expand)
|
||||
continue;
|
||||
@@ -3431,7 +3447,7 @@ namespace nana
|
||||
(idx == hoverred_pos ? item_state::highlighted : item_state::normal)
|
||||
);
|
||||
|
||||
item_top += essence_->item_height();
|
||||
item_top += item_height_px;
|
||||
if (item_top >= rect.bottom())
|
||||
break;
|
||||
|
||||
@@ -3443,7 +3459,11 @@ namespace nana
|
||||
}
|
||||
|
||||
if (item_top < rect.bottom())
|
||||
essence_->graph->rectangle(rectangle{ rect.x, item_top, rect.width, static_cast<unsigned>(rect.bottom() - item_top) }, true, bgcolor);
|
||||
{
|
||||
rectangle bground_r{ rect.x, item_top, rect.width, static_cast<unsigned>(rect.bottom() - item_top) };
|
||||
if (!API::dev::copy_transparent_background(essence_->listbox_ptr->handle(), bground_r, *essence_->graph, bground_r.position()))
|
||||
essence_->graph->rectangle(bground_r, true, bgcolor);
|
||||
}
|
||||
|
||||
//Draw mouse selection
|
||||
//Check if the mouse selection box is present.
|
||||
@@ -3459,26 +3479,24 @@ namespace nana
|
||||
};
|
||||
|
||||
paint::graphics box_graph{ box_size };
|
||||
box_graph.rectangle(true, essence_->scheme_ptr->selection_box.get_color().blend(colors::white, 0.6));
|
||||
box_graph.rectangle(true, essence_->scheme_ptr->selection_box.get_color().blend(colors::white, 0.4));
|
||||
box_graph.rectangle(false, essence_->scheme_ptr->selection_box.get_color());
|
||||
|
||||
box_graph.blend(rectangle{ box_size }, *essence_->graph, essence_->coordinate_cast(box_position, false), 0.5);
|
||||
}
|
||||
}
|
||||
private:
|
||||
void _m_draw_categ(const category_t& categ, int x, int y, int txtoff, unsigned width, const nana::rectangle& r, nana::color bgcolor, item_state state) const
|
||||
void _m_draw_categ(const category_t& categ, int x, int y, int txtoff, unsigned width, const nana::rectangle& r, nana::color bgcolor, item_state state)
|
||||
{
|
||||
const bool sel = categ.selected();
|
||||
if (sel && (categ.expand == false))
|
||||
bgcolor = static_cast<color_rgb>(0xD5EFFC);
|
||||
|
||||
if (state == item_state::highlighted)
|
||||
bgcolor = bgcolor.blend(static_cast<color_rgb>(0x99defd), 0.8);
|
||||
|
||||
const auto item_height = essence_->item_height();
|
||||
|
||||
rectangle bground_r{ x, y, width, item_height };
|
||||
auto graph = essence_->graph;
|
||||
graph->rectangle(rectangle{ x, y, width, item_height }, true, bgcolor);
|
||||
|
||||
item_data item;
|
||||
item.flags.selected = categ.selected();
|
||||
|
||||
this->_m_draw_item_bground(bground_r, bgcolor, {}, state, item);
|
||||
|
||||
color txt_color{ static_cast<color_rgb>(0x3399) };
|
||||
|
||||
@@ -3506,10 +3524,53 @@ namespace nana
|
||||
}
|
||||
|
||||
//Draw selecting inner rectangle
|
||||
if (sel && (categ.expand == false))
|
||||
if (item.flags.selected && (categ.expand == false))
|
||||
_m_draw_item_border(r.x, y, (std::min)(r.width, width - essence_->content_view->origin().x));
|
||||
}
|
||||
|
||||
color _m_draw_item_bground(const rectangle& bground_r, color bgcolor, color cell_color, item_state state, const item_data& item)
|
||||
{
|
||||
auto graph = essence_->graph;
|
||||
|
||||
auto const is_transparent = API::dev::copy_transparent_background(essence_->listbox_ptr->handle(), bground_r, *graph, bground_r.position());
|
||||
|
||||
if (is_transparent)
|
||||
bgcolor = color{};
|
||||
|
||||
if (item.flags.selected)
|
||||
{
|
||||
bgcolor = essence_->scheme_ptr->item_selected;
|
||||
|
||||
if (!cell_color.invisible())
|
||||
bgcolor = bgcolor.blend(cell_color, 0.5);
|
||||
}
|
||||
else if (!cell_color.invisible())
|
||||
bgcolor = cell_color;
|
||||
else if (!item.bgcolor.invisible())
|
||||
bgcolor = item.bgcolor;
|
||||
|
||||
if (item_state::highlighted == state)
|
||||
{
|
||||
if (item.flags.selected)
|
||||
bgcolor = bgcolor.blend(colors::black, 0.9);
|
||||
else
|
||||
bgcolor = bgcolor.blend(essence_->scheme_ptr->item_highlighted, 0.3);
|
||||
}
|
||||
|
||||
if (is_transparent)
|
||||
{
|
||||
if(!bgcolor.invisible())
|
||||
graph->blend(bground_r, bgcolor, 0.2);
|
||||
}
|
||||
else
|
||||
{
|
||||
graph->rectangle(bground_r, true, bgcolor);
|
||||
|
||||
}
|
||||
|
||||
return bgcolor;
|
||||
}
|
||||
|
||||
/// Draws an item
|
||||
void _m_draw_item(const category_t& cat,
|
||||
const index_pair& item_pos,
|
||||
@@ -3534,28 +3595,16 @@ namespace nana
|
||||
|
||||
auto & cells = (cat.model_ptr ? model_cells : *item.cells);
|
||||
|
||||
if (item.flags.selected) // fetch the "def" colors
|
||||
bgcolor = essence_->scheme_ptr->item_selected;
|
||||
else if (!item.bgcolor.invisible())
|
||||
bgcolor = item.bgcolor;
|
||||
|
||||
if(!item.fgcolor.invisible())
|
||||
fgcolor = item.fgcolor;
|
||||
|
||||
if (item_state::highlighted == state) // and blend it if "highlighted"
|
||||
{
|
||||
if (item.flags.selected)
|
||||
bgcolor = bgcolor.blend(colors::black, 0.98); // or "selected"
|
||||
else
|
||||
bgcolor = bgcolor.blend(essence_->scheme_ptr->item_highlighted, 0.7);/// \todo create a parametre for amount of blend
|
||||
}
|
||||
|
||||
const unsigned show_w = (std::min)(content_r.width, width - essence_->content_view->origin().x);
|
||||
|
||||
auto graph = essence_->graph;
|
||||
|
||||
//draw the background for the whole item
|
||||
graph->rectangle(rectangle{ content_r.x, y, show_w, essence_->item_height() }, true, bgcolor);
|
||||
rectangle bground_r{ content_r.x, y, show_w, essence_->item_height() };
|
||||
auto const state_bgcolor = this->_m_draw_item_bground(bground_r, bgcolor, {}, state, item);
|
||||
|
||||
int column_x = x;
|
||||
|
||||
@@ -3563,7 +3612,6 @@ namespace nana
|
||||
{
|
||||
const auto column_pos = seqs[display_order];
|
||||
const auto & col = essence_->header.at(column_pos); // deduce the corresponding header which is in a kind of dislay order
|
||||
auto it_bgcolor = bgcolor;
|
||||
|
||||
if (col.width_px > essence_->scheme_ptr->text_margin)
|
||||
{
|
||||
@@ -3664,7 +3712,8 @@ namespace nana
|
||||
}
|
||||
}
|
||||
|
||||
auto cell_txtcolor = fgcolor;
|
||||
auto col_bgcolor = bgcolor;
|
||||
auto col_fgcolor = fgcolor;
|
||||
|
||||
if (cells.size() > column_pos) // process only if the cell is visible
|
||||
{
|
||||
@@ -3673,24 +3722,13 @@ namespace nana
|
||||
|
||||
if (m_cell.custom_format) // adapt to costum format if need
|
||||
{
|
||||
if (!item.bgcolor.invisible())
|
||||
cell_txtcolor = m_cell.custom_format->bgcolor;
|
||||
|
||||
if (item.flags.selected) // fetch the "def" colors
|
||||
it_bgcolor = essence_->scheme_ptr->item_selected;
|
||||
col_fgcolor = m_cell.custom_format->fgcolor;
|
||||
|
||||
cell_txtcolor = m_cell.custom_format->fgcolor;
|
||||
|
||||
if (item_state::highlighted == state) // and blend it if "highlighted"
|
||||
{
|
||||
if (item.flags.selected)
|
||||
it_bgcolor = it_bgcolor.blend(colors::black, 0.98); // or "selected"
|
||||
else
|
||||
it_bgcolor = it_bgcolor.blend(essence_->scheme_ptr->item_highlighted, 0.7); /// \todo create a parametre for amount of blend
|
||||
}
|
||||
|
||||
graph->rectangle(rectangle{ column_x, y, col.width_px, essence_->item_height() }, true, it_bgcolor);
|
||||
bground_r = rectangle{ column_x, y, col.width_px, essence_->item_height() };
|
||||
col_bgcolor = this->_m_draw_item_bground(bground_r, bgcolor, m_cell.custom_format->bgcolor, state, item);
|
||||
}
|
||||
else
|
||||
col_bgcolor = state_bgcolor;
|
||||
|
||||
if (draw_column)
|
||||
{
|
||||
@@ -3702,7 +3740,7 @@ namespace nana
|
||||
else if (align::right == col.alignment)
|
||||
text_margin_right = essence_->scheme_ptr->text_margin;
|
||||
|
||||
graph->palette(true, cell_txtcolor);
|
||||
graph->palette(true, col_fgcolor);
|
||||
text_aligner.draw(m_cell.text, { column_x + content_pos, y + txtoff }, col.width_px - content_pos - text_margin_right);
|
||||
}
|
||||
}
|
||||
@@ -3710,7 +3748,7 @@ namespace nana
|
||||
if (0 == display_order)
|
||||
{
|
||||
if (essence_->checkable)
|
||||
crook_renderer_.draw(*graph, it_bgcolor, cell_txtcolor, essence_->checkarea(column_x, y), estate);
|
||||
crook_renderer_.draw(*graph, col_bgcolor, col_fgcolor, essence_->checkarea(column_x, y), estate);
|
||||
if (item.img)
|
||||
item.img.stretch(rectangle{ item.img.size() }, *graph, img_r);
|
||||
}
|
||||
@@ -4196,16 +4234,6 @@ namespace nana
|
||||
bool do_expand = (lister.expand(item_pos.cat) == false);
|
||||
lister.expand(item_pos.cat, do_expand);
|
||||
|
||||
if(false == do_expand)
|
||||
{
|
||||
auto last = lister.advance(lister.last(), -static_cast<int>(essence_->count_of_exposed(false)));
|
||||
if (!last.empty())
|
||||
{
|
||||
auto px = lister.distance(lister.first(), last) * essence_->item_height();
|
||||
essence_->content_view->change_position(static_cast<int>(px), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
essence_->calc_content_size(false);
|
||||
essence_->content_view->sync(false);
|
||||
refresh(graph);
|
||||
@@ -4727,20 +4755,6 @@ namespace nana
|
||||
return to_utf8(cat_->text);
|
||||
}
|
||||
|
||||
bool assign_colors_for_last(essence* ess, category_t* cat)
|
||||
{
|
||||
auto wd = ess->lister.wd_ptr();
|
||||
if (wd && !API::empty_window(wd->handle()))
|
||||
{
|
||||
auto & m = cat->items.back();
|
||||
m.bgcolor = wd->bgcolor();
|
||||
m.fgcolor = wd->fgcolor();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cat_proxy::push_back(std::string s)
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
@@ -4766,8 +4780,7 @@ namespace nana
|
||||
else
|
||||
cat_->items.emplace_back(std::move(s));
|
||||
|
||||
if (assign_colors_for_last(ess_, cat_))
|
||||
ess_->update();
|
||||
ess_->update();
|
||||
}
|
||||
|
||||
//Behavior of a container
|
||||
@@ -4947,8 +4960,6 @@ namespace nana
|
||||
}
|
||||
|
||||
cat_->sorted.push_back(cat_->items.size() - 1);
|
||||
|
||||
assign_colors_for_last(ess_, cat_);
|
||||
}
|
||||
|
||||
void cat_proxy::_m_try_append_model(const const_virtual_pointer& dptr)
|
||||
@@ -4964,7 +4975,6 @@ namespace nana
|
||||
|
||||
cat_->sorted.push_back(cat_->items.size());
|
||||
cat_->items.emplace_back();
|
||||
assign_colors_for_last(ess_, cat_);
|
||||
}
|
||||
|
||||
void cat_proxy::_m_cat_by_pos() noexcept
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* A Panel Implementation
|
||||
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -31,7 +31,7 @@ namespace nana
|
||||
|
||||
void drawer::refresh(graph_reference graph)
|
||||
{
|
||||
if(bground_mode::basic != API::effects_bground_mode(window_))
|
||||
if (!API::dev::copy_transparent_background(window_, graph))
|
||||
graph.rectangle(true, API::bgcolor(window_));
|
||||
}
|
||||
//end class drawer
|
||||
|
||||
@@ -194,9 +194,9 @@ namespace nana
|
||||
{
|
||||
auto graph = impl_->graph_ptr;
|
||||
|
||||
if (graph && (bground_mode::basic != API::effects_bground_mode(*impl_->wdg_ptr)))
|
||||
if (graph && (!API::dev::copy_transparent_background(*impl_->wdg_ptr, *graph)))
|
||||
{
|
||||
if (w < graph->size().width || h < graph->size().height /* .width ??? */ || impl_->backimg.image.alpha())
|
||||
if (w < graph->size().width || h < graph->size().height || impl_->backimg.image.alpha())
|
||||
{
|
||||
auto & bground = impl_->gradual_bground;
|
||||
if (bground.gradual_from.invisible() || bground.gradual_to.invisible())
|
||||
@@ -320,7 +320,7 @@ namespace nana
|
||||
|
||||
bool picture::transparent() const
|
||||
{
|
||||
return (bground_mode::basic == API::effects_bground_mode(*this));
|
||||
return API::is_transparent_background(*this);
|
||||
}
|
||||
//end class picture
|
||||
}//end namespace nana
|
||||
|
||||
@@ -209,7 +209,10 @@ namespace nana {
|
||||
vert.value(origin.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
vert.close();
|
||||
origin.y = 0;
|
||||
}
|
||||
|
||||
if (imd_area.height != disp_area.height)
|
||||
{
|
||||
@@ -233,7 +236,10 @@ namespace nana {
|
||||
horz.value(origin.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
horz.close();
|
||||
origin.x = 0;
|
||||
}
|
||||
|
||||
this->enable_update = true;
|
||||
}
|
||||
@@ -308,7 +314,31 @@ namespace nana {
|
||||
|
||||
void content_view::content_size(const size& sz, bool try_update)
|
||||
{
|
||||
if (sz.height < impl_->content_size.height)
|
||||
{
|
||||
if (impl_->origin.y + impl_->disp_area.height > sz.height)
|
||||
{
|
||||
if (impl_->disp_area.height > sz.height)
|
||||
impl_->origin.y = 0;
|
||||
else
|
||||
impl_->origin.y = sz.height - impl_->disp_area.height;
|
||||
}
|
||||
}
|
||||
|
||||
if (sz.width < impl_->content_size.width)
|
||||
{
|
||||
if (impl_->origin.x + impl_->disp_area.width > sz.width)
|
||||
{
|
||||
if (impl_->disp_area.width > sz.width)
|
||||
impl_->origin.x = 0;
|
||||
else
|
||||
impl_->origin.x = sz.width - impl_->disp_area.width;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl_->content_size = sz;
|
||||
|
||||
impl_->size_changed(try_update);
|
||||
}
|
||||
|
||||
|
||||
@@ -388,6 +388,13 @@ namespace nana{ namespace widgets
|
||||
const keyword_scheme * scheme;
|
||||
};
|
||||
|
||||
enum class sync_graph
|
||||
{
|
||||
none,
|
||||
refresh,
|
||||
lazy_refresh
|
||||
};
|
||||
|
||||
|
||||
struct text_editor::implementation
|
||||
{
|
||||
@@ -397,6 +404,8 @@ namespace nana{ namespace widgets
|
||||
|
||||
skeletons::textbase<wchar_t> textbase;
|
||||
|
||||
sync_graph try_refresh{ sync_graph::none };
|
||||
|
||||
struct inner_capacities
|
||||
{
|
||||
editor_behavior_interface * behavior;
|
||||
@@ -411,14 +420,12 @@ namespace nana{ namespace widgets
|
||||
paint::graphics buffer; //A offscreen buffer which keeps the background that painted by external part.
|
||||
}counterpart;
|
||||
|
||||
|
||||
struct indent_rep
|
||||
{
|
||||
bool enabled{ false };
|
||||
std::function<std::string()> generator;
|
||||
}indent;
|
||||
|
||||
|
||||
struct inner_keywords
|
||||
{
|
||||
std::map<std::string, std::shared_ptr<keyword_scheme>> schemes;
|
||||
@@ -487,13 +494,10 @@ namespace nana{ namespace widgets
|
||||
if ((0 == textlines) || (0 == line_px))
|
||||
return{};
|
||||
|
||||
auto const offset_top = editor_._m_text_topline();
|
||||
const int text_area_top = editor_.text_area_.area.y;
|
||||
|
||||
if (top < text_area_top)
|
||||
top = offset_top ? offset_top - 1 : 0;
|
||||
if (top < editor_.text_area_.area.y)
|
||||
top = (std::max)(editor_._m_text_topline() - 1, 0);
|
||||
else
|
||||
top = (top - text_area_top) / line_px + offset_top;
|
||||
top = (top - editor_.text_area_.area.y + editor_.impl_->cview->origin().y) / line_px;
|
||||
|
||||
return{ (textlines <= static_cast<std::size_t>(top) ? textlines - 1 : static_cast<std::size_t>(top)),
|
||||
0 };
|
||||
@@ -676,16 +680,9 @@ namespace nana{ namespace widgets
|
||||
if ((0 == editor_.textbase().lines()) || (0 == line_px))
|
||||
return coord;
|
||||
|
||||
const int text_area_top = editor_.text_area_.area.y;
|
||||
auto const offset_top = editor_._m_text_topline();
|
||||
auto screen_rows = (top - editor_.text_area_.area.y + editor_.impl_->cview->origin().y) / line_px;
|
||||
|
||||
auto screen_line = (text_area_top - top) / line_px;
|
||||
if ((top < text_area_top) && (screen_line > offset_top))
|
||||
screen_line = 0;
|
||||
else
|
||||
screen_line = offset_top - screen_line;
|
||||
|
||||
coord = _m_textline(static_cast<std::size_t>(screen_line));
|
||||
coord = _m_textline(static_cast<std::size_t>(screen_rows));
|
||||
if (linemtr_.size() <= coord.first)
|
||||
{
|
||||
coord.first = linemtr_.size() - 1;
|
||||
@@ -1261,6 +1258,7 @@ namespace nana{ namespace widgets
|
||||
put(key);
|
||||
}
|
||||
reset_caret();
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -1289,6 +1287,7 @@ namespace nana{ namespace widgets
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1316,8 +1315,7 @@ namespace nana{ namespace widgets
|
||||
_m_reset();
|
||||
impl_->capacities.behavior->pre_calc_lines(width_pixels());
|
||||
|
||||
render(API::is_focus_ready(window_));
|
||||
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
_m_reset_content_size();
|
||||
return true;
|
||||
}
|
||||
@@ -1326,7 +1324,7 @@ namespace nana{ namespace widgets
|
||||
{
|
||||
this->attributes_.alignment = alignment;
|
||||
this->reset_caret();
|
||||
render(API::is_focus_ready(window_));
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
_m_reset_content_size();
|
||||
}
|
||||
|
||||
@@ -1340,11 +1338,9 @@ namespace nana{ namespace widgets
|
||||
if (impl_->counterpart.enabled)
|
||||
impl_->counterpart.buffer.make(r.dimension());
|
||||
|
||||
impl_->capacities.behavior->pre_calc_lines(width_pixels());
|
||||
|
||||
impl_->cview->disp_area(r, { -1, 1 }, { 1, -1 }, { 2, 2 });
|
||||
if (impl_->cview->content_size().empty() || this->attributes_.line_wrapped)
|
||||
_m_reset_content_size();
|
||||
_m_reset_content_size(true);
|
||||
|
||||
move_caret(points_.caret);
|
||||
return true;
|
||||
@@ -1381,14 +1377,12 @@ namespace nana{ namespace widgets
|
||||
else
|
||||
impl_->capacities.behavior = new behavior_normal(*this);
|
||||
|
||||
impl_->capacities.behavior->pre_calc_lines(width_pixels());
|
||||
_m_reset_content_size(true);
|
||||
|
||||
impl_->cview->move_origin(point{} -impl_->cview->origin());
|
||||
move_caret(upoint{});
|
||||
|
||||
_m_reset_content_size();
|
||||
|
||||
render(API::is_focus_ready(window_));
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -1478,14 +1472,19 @@ namespace nana{ namespace widgets
|
||||
return px;
|
||||
}
|
||||
|
||||
unsigned text_editor::screen_lines() const
|
||||
unsigned text_editor::screen_lines(bool completed_line) const
|
||||
{
|
||||
auto const line_px = line_height();
|
||||
if (line_px)
|
||||
{
|
||||
auto h = impl_->cview->view_area().height;
|
||||
if (graph_ && h)
|
||||
{
|
||||
if (completed_line)
|
||||
return (h / line_px);
|
||||
|
||||
return (h / line_px + (h % line_px ? 1 : 0));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1559,23 +1558,23 @@ namespace nana{ namespace widgets
|
||||
else if (selection::mode::move_selected == select_.mode_selection)
|
||||
select_.mode_selection = selection::mode::move_selected_take_effect;
|
||||
|
||||
_m_draw_border();
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool text_editor::mouse_pressed(const arg_mouse& arg)
|
||||
void text_editor::mouse_pressed(const arg_mouse& arg)
|
||||
{
|
||||
if(!attributes_.enable_caret)
|
||||
return false;
|
||||
return;
|
||||
|
||||
if (event_code::mouse_down == arg.evt_code)
|
||||
{
|
||||
if (select_.ignore_press || (!hit_text_area(arg.pos)))
|
||||
{
|
||||
select_.ignore_press = false;
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (::nana::mouse::left_button == arg.button)
|
||||
@@ -1614,13 +1613,11 @@ namespace nana{ namespace widgets
|
||||
}
|
||||
}
|
||||
|
||||
_m_draw_border();
|
||||
return true;
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
}
|
||||
else if (event_code::mouse_up == arg.evt_code)
|
||||
{
|
||||
select_.ignore_press = false;
|
||||
bool updated = false;
|
||||
|
||||
if (select_.mode_selection == selection::mode::mouse_selected)
|
||||
{
|
||||
@@ -1630,13 +1627,18 @@ namespace nana{ namespace widgets
|
||||
else if (selection::mode::move_selected == select_.mode_selection || selection::mode::move_selected_take_effect == select_.mode_selection)
|
||||
{
|
||||
//move_selected indicates the mouse is pressed on the selected text, but the mouse has not moved. So the text_editor should cancel the selection.
|
||||
//move_selected_take_effect indicates the mouse is pressed on the selected text, and the mouse has moved. So the text_editor should try move the selection.
|
||||
//move_selected_take_effect indicates the text_editor should try to move the selection.
|
||||
|
||||
if((selection::mode::move_selected == select_.mode_selection) || !move_select())
|
||||
if ((selection::mode::move_selected == select_.mode_selection) || !move_select())
|
||||
{
|
||||
//no move occurs
|
||||
select(false);
|
||||
|
||||
move_caret(_m_screen_to_caret(arg.pos));
|
||||
}
|
||||
|
||||
select_.mode_selection = selection::mode::no_selected;
|
||||
updated = true;
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
}
|
||||
|
||||
API::release_capture(window_);
|
||||
@@ -1644,12 +1646,7 @@ namespace nana{ namespace widgets
|
||||
text_area_.captured = false;
|
||||
if (hit_text_area(arg.pos) == false)
|
||||
API::window_cursor(window_, nana::cursor::arrow);
|
||||
|
||||
_m_draw_border();
|
||||
|
||||
return updated;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
textbase<text_editor::char_type> & text_editor::textbase()
|
||||
@@ -1662,6 +1659,19 @@ namespace nana{ namespace widgets
|
||||
return impl_->textbase;
|
||||
}
|
||||
|
||||
bool text_editor::try_refresh()
|
||||
{
|
||||
if (sync_graph::none != impl_->try_refresh)
|
||||
{
|
||||
if (sync_graph::refresh == impl_->try_refresh)
|
||||
render(API::is_focus_ready(window_));
|
||||
|
||||
impl_->try_refresh = sync_graph::none;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool text_editor::getline(std::size_t pos, std::wstring& text) const
|
||||
{
|
||||
if (impl_->textbase.lines() <= pos)
|
||||
@@ -1677,7 +1687,8 @@ namespace nana{ namespace widgets
|
||||
|
||||
impl_->textbase.erase_all();
|
||||
_m_reset();
|
||||
impl_->capacities.behavior->pre_calc_lines(width_pixels());
|
||||
_m_reset_content_size(true);
|
||||
|
||||
if (!end_caret)
|
||||
{
|
||||
auto undo_ptr = std::unique_ptr<undo_input_text>{ new undo_input_text(*this, str) };
|
||||
@@ -1691,9 +1702,7 @@ namespace nana{ namespace widgets
|
||||
{
|
||||
impl_->capacities.behavior->adjust_caret_into_screen();
|
||||
reset_caret();
|
||||
render(API::is_focus_ready(window_));
|
||||
|
||||
_m_reset_content_size();
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
points_.xpos = 0;
|
||||
}
|
||||
}
|
||||
@@ -1755,7 +1764,7 @@ namespace nana{ namespace widgets
|
||||
if (reset_caret && (!hit_text_area(pos)))
|
||||
{
|
||||
impl_->capacities.behavior->adjust_caret_into_screen();
|
||||
render(true);
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
caret->visible(true);
|
||||
return true;
|
||||
}
|
||||
@@ -1777,9 +1786,9 @@ namespace nana{ namespace widgets
|
||||
API::open_caret(window_, true).get()->dimension({ 1, line_height() });
|
||||
}
|
||||
|
||||
void text_editor::reset_caret()
|
||||
void text_editor::reset_caret(bool stay_in_view)
|
||||
{
|
||||
move_caret(points_.caret);
|
||||
move_caret(points_.caret, stay_in_view);
|
||||
}
|
||||
|
||||
void text_editor::show_caret(bool isshow)
|
||||
@@ -1821,14 +1830,14 @@ namespace nana{ namespace widgets
|
||||
if(select_.b.y) --select_.b.y;
|
||||
select_.b.x = static_cast<unsigned>(impl_->textbase.getline(select_.b.y).size());
|
||||
select_.mode_selection = selection::mode::method_selected;
|
||||
render(true);
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
select_.mode_selection = selection::mode::no_selected;
|
||||
if (_m_cancel_select(0))
|
||||
{
|
||||
render(true);
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -1840,8 +1849,8 @@ namespace nana{ namespace widgets
|
||||
select_.b = points_.caret;
|
||||
points_.xpos = points_.caret.x;
|
||||
|
||||
if (new_sel_end || (stay_in_view && impl_->capacities.behavior->adjust_caret_into_screen()))
|
||||
render(true);
|
||||
if(new_sel_end || (stay_in_view && impl_->capacities.behavior->adjust_caret_into_screen()))
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
}
|
||||
|
||||
bool text_editor::hit_text_area(const point& pos) const
|
||||
@@ -1877,7 +1886,7 @@ namespace nana{ namespace widgets
|
||||
points_.caret = select_.b;
|
||||
|
||||
if (impl_->capacities.behavior->adjust_caret_into_screen())
|
||||
render(true);
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
|
||||
reset_caret();
|
||||
return true;
|
||||
@@ -1886,7 +1895,7 @@ namespace nana{ namespace widgets
|
||||
if (_m_move_select(true))
|
||||
{
|
||||
impl_->capacities.behavior->adjust_caret_into_screen();
|
||||
render(true);
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -1906,7 +1915,7 @@ namespace nana{ namespace widgets
|
||||
unsigned exclude_px = API::open_caret(window_, true).get()->dimension().width;
|
||||
|
||||
if (attributes_.line_wrapped)
|
||||
exclude_px += impl_->cview->space();
|
||||
exclude_px += impl_->cview->extra_space(false);
|
||||
|
||||
return (text_area_.area.width > exclude_px ? text_area_.area.width - exclude_px : 0);
|
||||
}
|
||||
@@ -1948,8 +1957,11 @@ namespace nana{ namespace widgets
|
||||
graph_.rectangle(false, bgcolor);
|
||||
|
||||
//Draw background
|
||||
if(attributes_.enable_background)
|
||||
graph_.rectangle(text_area_.area, true, bgcolor);
|
||||
if (!API::dev::copy_transparent_background(window_, graph_))
|
||||
{
|
||||
if (attributes_.enable_background)
|
||||
graph_.rectangle(text_area_.area, true, bgcolor);
|
||||
}
|
||||
|
||||
if (impl_->customized_renderers.background)
|
||||
impl_->customized_renderers.background(graph_, text_area_.area, bgcolor);
|
||||
@@ -1982,6 +1994,7 @@ namespace nana{ namespace widgets
|
||||
impl_->text_position.emplace_back(upoint{});
|
||||
|
||||
_m_draw_border();
|
||||
impl_->try_refresh = sync_graph::none;
|
||||
}
|
||||
//public:
|
||||
void text_editor::put(std::wstring text)
|
||||
@@ -2006,7 +2019,7 @@ namespace nana{ namespace widgets
|
||||
{
|
||||
impl_->capacities.behavior->adjust_caret_into_screen();
|
||||
reset_caret();
|
||||
render(API::is_focus_ready(window_));
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
_m_reset_content_size();
|
||||
points_.xpos = points_.caret.x;
|
||||
}
|
||||
@@ -2033,10 +2046,14 @@ namespace nana{ namespace widgets
|
||||
|
||||
points_.caret.x ++;
|
||||
|
||||
if (refresh || _m_update_caret_line(secondary_before))
|
||||
render(true);
|
||||
|
||||
if (!refresh)
|
||||
{
|
||||
if (!_m_update_caret_line(secondary_before))
|
||||
draw_corner();
|
||||
}
|
||||
else
|
||||
draw_corner();
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
|
||||
_m_reset_content_size();
|
||||
points_.xpos = points_.caret.x;
|
||||
@@ -2232,14 +2249,13 @@ namespace nana{ namespace widgets
|
||||
if (record_undo)
|
||||
impl_->undo.push(std::move(undo_ptr));
|
||||
|
||||
_m_reset_content_size(has_to_redraw);
|
||||
|
||||
if(has_to_redraw)
|
||||
{
|
||||
impl_->capacities.behavior->pre_calc_lines(width_pixels());
|
||||
impl_->capacities.behavior->adjust_caret_into_screen();
|
||||
render(true);
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
}
|
||||
|
||||
_m_reset_content_size();
|
||||
}
|
||||
|
||||
void text_editor::undo(bool reverse)
|
||||
@@ -2249,11 +2265,10 @@ namespace nana{ namespace widgets
|
||||
else
|
||||
impl_->undo.undo();
|
||||
|
||||
impl_->capacities.behavior->pre_calc_lines(width_pixels());
|
||||
impl_->capacities.behavior->adjust_caret_into_screen();
|
||||
render(true);
|
||||
_m_reset_content_size(true);
|
||||
|
||||
_m_reset_content_size();
|
||||
impl_->capacities.behavior->adjust_caret_into_screen();
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
}
|
||||
|
||||
void text_editor::set_undo_queue_length(std::size_t len)
|
||||
@@ -2265,7 +2280,7 @@ namespace nana{ namespace widgets
|
||||
{
|
||||
const bool redraw_required = _m_cancel_select(0);
|
||||
if (_m_move_caret_ns(to_north) || redraw_required)
|
||||
render(true);
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
}
|
||||
|
||||
void text_editor::move_left()
|
||||
@@ -2280,7 +2295,7 @@ namespace nana{ namespace widgets
|
||||
pending = false;
|
||||
bool adjust_y = (attributes_.line_wrapped && impl_->capacities.behavior->adjust_caret_into_screen());
|
||||
if (_m_move_offset_x_while_over_border(-2) || adjust_y)
|
||||
render(true);
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
}
|
||||
else if (points_.caret.y) //Move to previous line
|
||||
points_.caret.x = static_cast<unsigned>(textbase().getline(--points_.caret.y).size());
|
||||
@@ -2289,7 +2304,7 @@ namespace nana{ namespace widgets
|
||||
}
|
||||
|
||||
if (pending && impl_->capacities.behavior->adjust_caret_into_screen())
|
||||
render(true);
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
|
||||
points_.xpos = points_.caret.x;
|
||||
}
|
||||
@@ -2318,7 +2333,7 @@ namespace nana{ namespace widgets
|
||||
do_render = impl_->capacities.behavior->adjust_caret_into_screen();
|
||||
|
||||
if (do_render)
|
||||
render(true);
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
|
||||
points_.xpos = points_.caret.x;
|
||||
}
|
||||
@@ -2477,9 +2492,20 @@ namespace nana{ namespace widgets
|
||||
impl_->cview->move_origin(origin - impl_->cview->origin());
|
||||
impl_->cview->sync(true);
|
||||
points_.xpos = points_.caret.x;
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned text_editor::_m_width_px(bool include_vs) const
|
||||
{
|
||||
unsigned exclude_px = API::open_caret(window_, true).get()->dimension().width;
|
||||
|
||||
if (!include_vs)
|
||||
exclude_px += impl_->cview->space();
|
||||
|
||||
return (text_area_.area.width > exclude_px ? text_area_.area.width - exclude_px : 0);
|
||||
}
|
||||
|
||||
void text_editor::_m_draw_border()
|
||||
{
|
||||
if (!API::widget_borderless(this->window_))
|
||||
@@ -2510,7 +2536,7 @@ namespace nana{ namespace widgets
|
||||
points_.caret = _m_screen_to_caret(scrpos);
|
||||
|
||||
if (stay_in_view && impl_->capacities.behavior->adjust_caret_into_screen())
|
||||
render(true);
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
|
||||
move_caret(points_.caret);
|
||||
return points_.caret;
|
||||
@@ -2790,7 +2816,9 @@ namespace nana{ namespace widgets
|
||||
auto top = _m_caret_to_screen(upoint{ 0, static_cast<unsigned>(pos) }).y;
|
||||
|
||||
const unsigned pixels = line_height();
|
||||
graph_.rectangle({ text_area_.area.x, top, width_pixels(), static_cast<unsigned>(pixels * secondary_count_before) }, true, API::bgcolor(window_));
|
||||
const rectangle update_area = { text_area_.area.x, top, width_pixels(), static_cast<unsigned>(pixels * secondary_count_before) };
|
||||
if (!API::dev::copy_transparent_background(window_, update_area, graph_, update_area.position()))
|
||||
graph_.rectangle(update_area, true, API::bgcolor(window_));
|
||||
|
||||
auto fgcolor = API::fgcolor(window_);
|
||||
auto text_ptr = textbase().getline(pos).c_str();
|
||||
@@ -2803,9 +2831,10 @@ namespace nana{ namespace widgets
|
||||
}
|
||||
|
||||
_m_draw_border();
|
||||
impl_->try_refresh = sync_graph::lazy_refresh;
|
||||
}
|
||||
else
|
||||
render(API::is_focus_ready(window_));
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
}
|
||||
|
||||
bool text_editor::_m_accepts(char_type ch) const
|
||||
@@ -2835,22 +2864,58 @@ namespace nana{ namespace widgets
|
||||
return (!API::window_enabled(window_) ? static_cast<color_rgb>(0xE0E0E0) : API::bgcolor(window_));
|
||||
}
|
||||
|
||||
void text_editor::_m_reset_content_size()
|
||||
void text_editor::_m_reset_content_size(bool calc_lines)
|
||||
{
|
||||
auto const height = static_cast<unsigned>(impl_->capacities.behavior->take_lines() * line_height());
|
||||
size csize;
|
||||
|
||||
unsigned width = 0;
|
||||
if (this->attributes_.line_wrapped)
|
||||
{
|
||||
width = width_pixels();
|
||||
if (calc_lines)
|
||||
{
|
||||
//detect if vertical scrollbar is required
|
||||
auto const max_lines = screen_lines(true);
|
||||
auto const text_lines = textbase().lines();
|
||||
|
||||
csize.width = _m_width_px(true);
|
||||
if (text_lines > max_lines)
|
||||
{
|
||||
//enable vertical scrollbar
|
||||
csize.width = _m_width_px(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::size_t lines = 0;
|
||||
for (std::size_t i = 0; i < text_lines; ++i)
|
||||
{
|
||||
impl_->capacities.behavior->pre_calc_line(i, csize.width);
|
||||
lines += impl_->capacities.behavior->take_lines(i);
|
||||
|
||||
if (lines > max_lines)
|
||||
{
|
||||
//enable vertical scrollbar
|
||||
csize.width = _m_width_px(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_->capacities.behavior->pre_calc_lines(csize.width);
|
||||
}
|
||||
else
|
||||
csize.width = impl_->cview->content_size().width;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (calc_lines)
|
||||
impl_->capacities.behavior->pre_calc_lines(0);
|
||||
|
||||
auto maxline = textbase().max_line();
|
||||
width = _m_text_extent_size(textbase().getline(maxline.first).c_str(), maxline.second).width;
|
||||
csize.width = _m_text_extent_size(textbase().getline(maxline.first).c_str(), maxline.second).width;
|
||||
}
|
||||
|
||||
impl_->cview->content_size({ width, height });
|
||||
csize.height = static_cast<unsigned>(impl_->capacities.behavior->take_lines() * line_height());
|
||||
|
||||
impl_->cview->content_size(csize);
|
||||
}
|
||||
|
||||
void text_editor::_m_reset()
|
||||
@@ -3188,10 +3253,7 @@ namespace nana{ namespace widgets
|
||||
int text_editor::_m_text_topline() const
|
||||
{
|
||||
auto px = static_cast<int>(line_height());
|
||||
if (0 == px)
|
||||
return 0;
|
||||
|
||||
return (impl_->cview->origin().y / px);
|
||||
return (px ? (impl_->cview->origin().y / px) : px);
|
||||
}
|
||||
|
||||
int text_editor::_m_text_x(const text_section& sct) const
|
||||
@@ -3508,6 +3570,7 @@ namespace nana{ namespace widgets
|
||||
return false;
|
||||
}
|
||||
}
|
||||
impl_->try_refresh = sync_graph::refresh;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -300,7 +300,7 @@ namespace nana
|
||||
{
|
||||
if(!graph.size().empty())
|
||||
{
|
||||
proto_.renderer->background(other_.wd, graph, (bground_mode::basic == API::effects_bground_mode(other_.wd)), other_.widget->scheme());
|
||||
proto_.renderer->background(other_.wd, graph, API::dev::copy_transparent_background(other_.wd, graph), other_.widget->scheme());
|
||||
_m_draw_elements(graph);
|
||||
}
|
||||
}
|
||||
@@ -897,7 +897,7 @@ namespace nana
|
||||
|
||||
bool slider::transparent() const
|
||||
{
|
||||
return (bground_mode::basic == API::effects_bground_mode(*this));
|
||||
return API::is_transparent_background(*this);
|
||||
}
|
||||
//end class slider
|
||||
}//end namespace nana
|
||||
|
||||
@@ -372,7 +372,8 @@ namespace nana
|
||||
return true;
|
||||
}
|
||||
|
||||
if (editor_->mouse_pressed(arg))
|
||||
editor_->mouse_pressed(arg);
|
||||
if(editor_->try_refresh())
|
||||
{
|
||||
_m_draw_spins(buttons::none);
|
||||
return true;
|
||||
@@ -383,10 +384,11 @@ namespace nana
|
||||
|
||||
bool mouse_move(bool left_button, const ::nana::point& pos)
|
||||
{
|
||||
if (editor_->mouse_move(left_button, pos))
|
||||
editor_->mouse_move(left_button, pos);
|
||||
if(editor_->try_refresh())
|
||||
{
|
||||
editor_->reset_caret();
|
||||
render();
|
||||
_m_draw_spins(spin_stated_);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -570,10 +572,11 @@ namespace nana
|
||||
|
||||
void drawer::key_char(graph_reference, const arg_keyboard& arg)
|
||||
{
|
||||
if (impl_->editor()->respond_char(arg))
|
||||
impl_->editor()->respond_char(arg);
|
||||
if (impl_->editor()->try_refresh())
|
||||
{
|
||||
if (!impl_->value(to_utf8(impl_->editor()->text()), false))
|
||||
impl_->draw_spins();
|
||||
impl_->value(to_utf8(impl_->editor()->text()), false);
|
||||
impl_->draw_spins();
|
||||
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
|
||||
@@ -103,22 +103,22 @@ namespace drawerbase {
|
||||
|
||||
void drawer::mouse_down(graph_reference, const arg_mouse& arg)
|
||||
{
|
||||
if (editor_->mouse_pressed(arg))
|
||||
{
|
||||
editor_->render(true);
|
||||
editor_->mouse_pressed(arg);
|
||||
if(editor_->try_refresh())
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void drawer::mouse_move(graph_reference, const arg_mouse& arg)
|
||||
{
|
||||
if(editor_->mouse_move(arg.left_button, arg.pos))
|
||||
editor_->mouse_move(arg.left_button, arg.pos);
|
||||
if(editor_->try_refresh())
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
|
||||
void drawer::mouse_up(graph_reference, const arg_mouse& arg)
|
||||
{
|
||||
if(editor_->mouse_pressed(arg))
|
||||
editor_->mouse_pressed(arg);
|
||||
if(editor_->try_refresh())
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
|
||||
@@ -145,16 +145,16 @@ namespace drawerbase {
|
||||
|
||||
void drawer::key_press(graph_reference, const arg_keyboard& arg)
|
||||
{
|
||||
if(editor_->respond_key(arg))
|
||||
{
|
||||
editor_->reset_caret();
|
||||
editor_->respond_key(arg);
|
||||
editor_->reset_caret(true);
|
||||
if(editor_->try_refresh())
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void drawer::key_char(graph_reference, const arg_keyboard& arg)
|
||||
{
|
||||
if (editor_->respond_char(arg))
|
||||
editor_->respond_char(arg);
|
||||
if(editor_->try_refresh())
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
|
||||
@@ -163,6 +163,10 @@ namespace drawerbase {
|
||||
_m_text_area(arg.width, arg.height);
|
||||
refresh(graph);
|
||||
editor_->reset_caret();
|
||||
|
||||
if (!editor_->try_refresh())
|
||||
refresh(graph);
|
||||
|
||||
API::dev::lazy_refresh();
|
||||
}
|
||||
|
||||
@@ -225,7 +229,10 @@ namespace drawerbase {
|
||||
internal_scope_guard lock;
|
||||
auto editor = get_drawer_trigger().editor();
|
||||
if (editor && editor->load(file.data()))
|
||||
API::update_window(handle());
|
||||
{
|
||||
if (editor->try_refresh())
|
||||
API::update_window(handle());
|
||||
}
|
||||
}
|
||||
|
||||
void textbox::store(std::string file)
|
||||
@@ -267,7 +274,9 @@ namespace drawerbase {
|
||||
editor->move_caret_end(true);
|
||||
|
||||
editor->textbase().reset();
|
||||
API::update_window(this->handle());
|
||||
|
||||
if (editor->try_refresh())
|
||||
API::update_window(this->handle());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -383,6 +392,8 @@ namespace drawerbase {
|
||||
editor->move_caret_end(false);
|
||||
|
||||
editor->put(to_wstring(text));
|
||||
|
||||
editor->try_refresh();
|
||||
API::update_window(this->handle());
|
||||
}
|
||||
return *this;
|
||||
@@ -399,8 +410,11 @@ namespace drawerbase {
|
||||
{
|
||||
internal_scope_guard lock;
|
||||
auto editor = get_drawer_trigger().editor();
|
||||
if (editor->line_wrapped(autl))
|
||||
if (editor && editor->line_wrapped(autl))
|
||||
{
|
||||
editor->try_refresh();
|
||||
API::update_window(handle());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -420,6 +434,8 @@ namespace drawerbase {
|
||||
{
|
||||
auto wd = handle();
|
||||
API::eat_tabstop(wd, ml); //textbox handles the Tab pressing when it is multi-line.
|
||||
|
||||
editor->try_refresh();
|
||||
API::update_window(wd);
|
||||
}
|
||||
return *this;
|
||||
@@ -495,7 +511,7 @@ namespace drawerbase {
|
||||
internal_scope_guard lock;
|
||||
auto editor = get_drawer_trigger().editor();
|
||||
if(editor && editor->select(yes))
|
||||
API::update_window(*this);
|
||||
API::refresh_window(*this);
|
||||
}
|
||||
|
||||
std::pair<upoint, upoint> textbox::selection() const
|
||||
@@ -525,7 +541,8 @@ namespace drawerbase {
|
||||
if(editor)
|
||||
{
|
||||
editor->paste();
|
||||
API::update_window(*this);
|
||||
if (editor->try_refresh())
|
||||
API::update_window(*this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,7 +595,10 @@ namespace drawerbase {
|
||||
internal_scope_guard lock;
|
||||
auto editor = get_drawer_trigger().editor();
|
||||
if (editor)
|
||||
{
|
||||
editor->set_highlight(name, fgcolor, bgcolor);
|
||||
API::refresh_window(handle());
|
||||
}
|
||||
}
|
||||
|
||||
void textbox::erase_highlight(const std::string& name)
|
||||
@@ -586,7 +606,10 @@ namespace drawerbase {
|
||||
internal_scope_guard lock;
|
||||
auto editor = get_drawer_trigger().editor();
|
||||
if (editor)
|
||||
{
|
||||
editor->erase_highlight(name);
|
||||
API::refresh_window(handle());
|
||||
}
|
||||
}
|
||||
|
||||
void textbox::set_keywords(const std::string& name, bool case_sensitive, bool whole_word_match, std::initializer_list<std::wstring> kw_list)
|
||||
@@ -597,6 +620,7 @@ namespace drawerbase {
|
||||
{
|
||||
for (auto & kw : kw_list)
|
||||
editor->set_keyword(kw, name, case_sensitive, whole_word_match);
|
||||
API::refresh_window(handle());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,6 +632,7 @@ namespace drawerbase {
|
||||
{
|
||||
for (auto & kw : kw_list_utf8)
|
||||
editor->set_keyword(::nana::charset(kw, ::nana::unicode::utf8), name, case_sensitive, whole_word_match);
|
||||
API::refresh_window(handle());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -616,7 +641,10 @@ namespace drawerbase {
|
||||
internal_scope_guard lock;
|
||||
auto editor = get_drawer_trigger().editor();
|
||||
if (editor)
|
||||
{
|
||||
editor->erase_keyword(to_wstring(kw));
|
||||
API::refresh_window(handle());
|
||||
}
|
||||
}
|
||||
|
||||
textbox& textbox::text_align(::nana::align alignment)
|
||||
@@ -626,7 +654,7 @@ namespace drawerbase {
|
||||
if (editor)
|
||||
{
|
||||
editor->text_align(alignment);
|
||||
API::update_window(this->handle());
|
||||
API::refresh_window(handle());
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace nana
|
||||
nana::paint::graphics item_graph({ item_r_.width, item_r_.height });
|
||||
item_graph.typeface(graph_->typeface());
|
||||
|
||||
renderer_->set_color(widget_->bgcolor(), widget_->fgcolor());
|
||||
renderer_->begin_paint(*widget_);
|
||||
renderer_->bground(item_graph, this);
|
||||
renderer_->expander(item_graph, this);
|
||||
renderer_->crook(item_graph, this);
|
||||
@@ -343,7 +343,9 @@ namespace nana
|
||||
if (attr.auto_draw || ignore_auto_draw)
|
||||
{
|
||||
//Draw background
|
||||
data.graph->rectangle(true, data.widget_ptr->bgcolor());
|
||||
rectangle bground_r{ data.graph->size() };
|
||||
if (!API::dev::copy_transparent_background(data.widget_ptr->handle(), bground_r, *data.graph, {}))
|
||||
data.graph->rectangle(true, data.widget_ptr->bgcolor());
|
||||
|
||||
//Draw tree
|
||||
attr.tree_cont.for_each(shape.first, Renderer(this, nana::point(static_cast<int>(attr.tree_cont.indent_size(shape.first) * shape.indent_pixels) - shape.offset_x, 1)));
|
||||
@@ -1201,13 +1203,11 @@ namespace nana
|
||||
class internal_renderer
|
||||
: public renderer_interface
|
||||
{
|
||||
nana::color bgcolor_;
|
||||
nana::color fgcolor_;
|
||||
window window_handle_;
|
||||
|
||||
void set_color(const nana::color & bgcolor, const nana::color& fgcolor) override
|
||||
void begin_paint(::nana::widget& wdg) override
|
||||
{
|
||||
bgcolor_ = bgcolor;
|
||||
fgcolor_ = fgcolor;
|
||||
window_handle_ = wdg.handle();
|
||||
}
|
||||
|
||||
void bground(graph_reference graph, const compset_interface * compset) const override
|
||||
@@ -1234,8 +1234,19 @@ namespace nana
|
||||
|
||||
if (clrptr)
|
||||
{
|
||||
graph.rectangle(attr.area, false, clrptr[1]);
|
||||
graph.rectangle(attr.area.pare_off(1), true, *clrptr);
|
||||
if (API::is_transparent_background(window_handle_))
|
||||
{
|
||||
paint::graphics item_graph{ attr.area.dimension() };
|
||||
item_graph.rectangle(false, clrptr[1]);
|
||||
item_graph.rectangle(rectangle{attr.area.dimension()}.pare_off(1), true, *clrptr);
|
||||
|
||||
item_graph.blend(rectangle{ attr.area.dimension() }, graph, attr.area.position(), 0.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
graph.rectangle(attr.area, false, clrptr[1]);
|
||||
graph.rectangle(attr.area.pare_off(1), true, *clrptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1255,7 +1266,7 @@ namespace nana
|
||||
auto r = attr.area;
|
||||
r.y += (attr.area.height - 16) / 2;
|
||||
r.width = r.height = 16;
|
||||
arrow.draw(graph, bgcolor_, (attr.mouse_pointed ? colors::deep_sky_blue : colors::black), r, element_state::normal);
|
||||
arrow.draw(graph, API::bgcolor(window_handle_), (attr.mouse_pointed ? colors::deep_sky_blue : colors::black), r, element_state::normal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1266,7 +1277,7 @@ namespace nana
|
||||
{
|
||||
attr.area.y += (attr.area.height - 16) / 2;
|
||||
crook_.check(compset->item_attribute().checked);
|
||||
crook_.draw(graph, bgcolor_, fgcolor_, attr.area, attr.mouse_pointed ? element_state::hovered : element_state::normal);
|
||||
crook_.draw(graph, API::bgcolor(window_handle_), API::fgcolor(window_handle_), attr.area, attr.mouse_pointed ? element_state::hovered : element_state::normal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1308,7 +1319,7 @@ namespace nana
|
||||
{
|
||||
comp_attribute_t attr;
|
||||
if (compset->comp_attribute(component::text, attr))
|
||||
graph.string(point{ attr.area.x, attr.area.y + 3 }, compset->item_attribute().text, fgcolor_);
|
||||
graph.string(point{ attr.area.x, attr.area.y + 3 }, compset->item_attribute().text, API::fgcolor(window_handle_));
|
||||
}
|
||||
private:
|
||||
mutable facade<element::crook> crook_;
|
||||
@@ -1408,8 +1419,6 @@ namespace nana
|
||||
|
||||
item_renderer(implement * impl, const nana::point& pos)
|
||||
: impl_(impl),
|
||||
bgcolor_(impl->data.widget_ptr->bgcolor()),
|
||||
fgcolor_(impl->data.widget_ptr->fgcolor()),
|
||||
pos_(pos)
|
||||
{
|
||||
}
|
||||
@@ -1441,7 +1450,7 @@ namespace nana
|
||||
node_r_.height = comp_placer->item_height(*impl_->data.graph);
|
||||
|
||||
auto renderer = draw_impl->data.renderer;
|
||||
renderer->set_color(bgcolor_, fgcolor_);
|
||||
renderer->begin_paint(*draw_impl->data.widget_ptr);
|
||||
renderer->bground(*draw_impl->data.graph, this);
|
||||
renderer->expander(*draw_impl->data.graph, this);
|
||||
renderer->crook(*draw_impl->data.graph, this);
|
||||
@@ -1476,8 +1485,6 @@ namespace nana
|
||||
}
|
||||
private:
|
||||
trigger::implement * impl_;
|
||||
::nana::color bgcolor_;
|
||||
::nana::color fgcolor_;
|
||||
::nana::point pos_;
|
||||
const node_type * iterated_node_;
|
||||
item_attribute_t node_attr_;
|
||||
|
||||
Reference in New Issue
Block a user