Merge branch 'hotfix-1.4.1' into develop

This commit is contained in:
Jinhao
2017-01-13 07:17:55 +08:00
26 changed files with 6060 additions and 5811 deletions

View File

@@ -56,7 +56,7 @@ matrix:
- llvm-toolchain-precise
before_install:
- git clone --depth=1 --branch=develop https://github.com/qPCR4vir/nana-demo.git ../nana-demo
- git clone --depth=1 --branch=hotfix-1.4 https://github.com/qPCR4vir/nana-demo.git ../nana-demo
- export PATH="$HOME/bin:$PATH"
- mkdir ~/bin
- wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.4/cmake-3.4.0-rc3-Linux-x86_64.sh || true

View File

@@ -33,6 +33,9 @@ namespace nana
{
namespace listbox
{
using size_type = std::size_t;
using native_string_type = ::nana::detail::native_string_type;
/// An interface of column operations
class column_interface
{
@@ -56,6 +59,22 @@ namespace nana
*/
virtual void width(unsigned minimum, unsigned maximum) = 0;
/// Returns the position of the column
/**
* @param disp_order Indicates whether the display position or absolute position to be returned
* @return the position of the column.
*/
virtual size_type position(bool disp_order) const noexcept = 0;
/// Returns the caption of column
virtual std::string text() const noexcept = 0;
/// Sets the caption of column
/**
* @param text_utf8 A UTF-8 string for the caption.
*/
virtual void text(std::string text_utf8) = 0;
/// Sets alignment of column text
/**
* @param align Alignment
@@ -619,8 +638,6 @@ namespace nana
std::unique_ptr<container_interface> container_ptr_;
};
using size_type = std::size_t;
using native_string_type = ::nana::detail::native_string_type;
/// usefull for both absolute and display (sorted) positions
struct index_pair
@@ -757,8 +774,6 @@ namespace nana
trigger();
~trigger();
essence& ess() const;
private:
void _m_draw_border();
private:
void attached(widget_reference, graph_reference) override;
void detached() override;
@@ -832,10 +847,18 @@ namespace nana
size_type columns() const;
item_proxy& text(size_type col, cell);
item_proxy& text(size_type col, std::string);
item_proxy& text(size_type col, const std::wstring&);
std::string text(size_type col) const;
/// Converts a position of column between display position and absolute position
/**
* @param col The display position or absolute position.
* @param disp_order Indicates whether the col is a display position or absolute position. If this parameter is true, the col is display position
* @return absolute position if disp_order is false, display position otherwise.
*/
size_type column_cast(size_type col, bool disp_order) const;
item_proxy& text(size_type abs_col, cell);
item_proxy& text(size_type abs_col, std::string);
item_proxy& text(size_type abs_col, const std::wstring&);
std::string text(size_type abs_col) const;
void icon(const nana::paint::image&);
@@ -1369,18 +1392,20 @@ the nana::detail::basic_window member pointer scheme
/// Access a column at specified position
/**
* @param pos Position of column
* @param disp_order Indicates whether the pos is display position or absolute position.
* @return Reference to the requested column
* @except std::out_of_range if !(pos < columns())
*/
column_interface & column_at(size_type pos);
column_interface & column_at(size_type pos, bool disp_order = false);
/// Access a column at specified position
/**
* @param pos Position of column
* @param disp_order Indicates whether the pos is display position or absolute position.
* @return Constant reference to the requested column
* @except std::out_of_range if !(pos < columns())
*/
const column_interface & column_at(size_type pos) const;
const column_interface & column_at(size_type pos, bool disp_order = false) const;
/// Returns the number of columns
size_type column_size() const;
@@ -1410,7 +1435,7 @@ the nana::detail::basic_window member pointer scheme
/// Returns an index of item which contains the specified point.
index_pair cast(const point & pos) const;
/// Returns the column which contains the specified point.
/// Returns the absolute position of column which contains the specified point.
size_type column_from_pos(const point & pos);
void checkable(bool);

View File

@@ -248,7 +248,7 @@ namespace nana
API::refresh_window(this->handle());
}
pat::cloneable<item_renderer>& renderer() const
const pat::cloneable<item_renderer>& renderer() const
{
return this->get_drawer_trigger().ext_renderer();
}

View File

@@ -421,6 +421,9 @@ namespace nana
bool checkable() const; ///< Determinte whether the checkboxs are enabled.
/// Clears the contents
void clear();
/// \brief Creates an icon scheme with the specified name.
///
/// The icon scheme includes 3 images for node states.

View File

@@ -24,6 +24,9 @@ namespace nana
{
friend class i18n_eval;
public:
/// Sets a handler to handle a msgid which hasn't been translated.
static void set_missing(std::function<void(const std::string& msgid_utf8)> handler);
void load(const std::string& file);
void load_utf8(const std::string& file);

View File

@@ -426,7 +426,7 @@ namespace detail
unsigned char * fade_table = nullptr;
std::unique_ptr<unsigned char[]> autoptr;
nana::pixel_argb_t rgb_imd;
nana::pixel_argb_t rgb_imd = {};
if(fade_rate != 0.0)
{
autoptr = detail::alloc_fade_table(1 - fade_rate);

View File

@@ -12,7 +12,7 @@
#ifndef NANA_SYSTEM_DATAEXCH_HPP
#define NANA_SYSTEM_DATAEXCH_HPP
#include <nana/basic_types.hpp>
#include <nana/gui/basis.hpp>
namespace nana{
@@ -31,15 +31,15 @@ namespace system{
text, pixmap
};
void set(const std::string & text_utf8);
void set(const std::wstring& text);
void set(const std::string & text_utf8, native_window_type owner = nullptr);
void set(const std::wstring& text, native_window_type owner = nullptr);
bool set(const nana::paint::graphics& g);
bool set(const nana::paint::graphics& g, native_window_type owner = nullptr);
void get(std::string& text_utf8);
void get(std::wstring& text);
private:
bool _m_set(format, const void* buf, std::size_t size);
bool _m_set(format, const void* buf, std::size_t size, native_window_type);
void* _m_get(format, size_t& size);
};

View File

@@ -1131,6 +1131,7 @@ namespace detail
void platform_spec::write_selection(native_window_type owner, Atom type, const void * buf, size_t bufsize)
{
platform_scope_guard psg;
::XSetSelectionOwner(display_, XA_PRIMARY, reinterpret_cast<Window>(owner), CurrentTime);
::XSetSelectionOwner(display_, atombase_.clipboard, reinterpret_cast<Window>(owner), CurrentTime);
::XFlush(display_);
if(XA_STRING == type || atombase_.utf8_string == type)

View File

@@ -237,7 +237,7 @@ namespace detail
if(wd_manager().available(wd) == false)
return false;
core_window_t * prev_wd;
core_window_t * prev_wd = nullptr;
if(thrd)
{
prev_wd = thrd->event_window;

View File

@@ -760,7 +760,7 @@ namespace detail
if (bedrock::instance().wd_manager().available(wd) == false)
return;
basic_window* prev_event_wd;
basic_window* prev_event_wd = nullptr;
if (thrd)
{
prev_event_wd = thrd->event_window;
@@ -1630,7 +1630,7 @@ namespace detail
if (wd_manager().available(wd) == false)
return false;
basic_window* prev_event_wd;
basic_window* prev_event_wd = nullptr;
if (thrd)
{
prev_event_wd = thrd->event_window;

View File

@@ -318,6 +318,7 @@ namespace nana
data_impl_->realizer = &realizer;
realizer._m_reset_overrided();
realizer.attached(wd, graphics);
realizer.typeface_changed(graphics);
}
drawer_trigger* drawer::detached()

View File

@@ -50,7 +50,7 @@ namespace nana
{
std::wstring type;
ires>>m.name>>type>>type;
m.directory = (type == L"Directory");
m.directory = (to_utf8(type) == internationalization()("NANA_FILEBOX_DIRECTORY"));
return ires;
}
@@ -65,6 +65,8 @@ namespace nana
_m_add(tm, item.modified_time.tm_min)<<':';
_m_add(tm, item.modified_time.tm_sec);
internationalization i18n;
ores<<item.name<<tm.str();
if(!item.directory)
{
@@ -72,12 +74,12 @@ namespace nana
if(pos != item.name.npos && (pos + 1 < item.name.size()))
ores<<item.name.substr(pos + 1);
else
ores<<L"File";
ores<<i18n("NANA_FILEBOX_FILE");
ores<<_m_trans(item.bytes);
}
else
ores<<L"Directory";
ores << i18n("NANA_FILEBOX_DIRECTORY");
return ores;
}
@@ -114,7 +116,8 @@ namespace nana
return s + ustr[uid];
}
ss<<bytes<<" Bytes";
internationalization i18n;
ss<<bytes<<" "<<i18n("NANA_FILEBOX_BYTES");
return ss.str();
}
};
@@ -138,6 +141,7 @@ namespace nana
filebox_implement(window owner, bool io_read, const std::string& title)
: form(owner, API::make_center(owner, 630, 440)), io_read_(io_read)
{
internationalization i18n;
path_.create(*this);
path_.splitstr("/");
path_.events().selected.connect_unignorable([this](const arg_categorize<int>&)
@@ -157,7 +161,7 @@ namespace nana
filter_.create(*this);
filter_.multi_lines(false);
filter_.tip_string("Filter");
filter_.tip_string(i18n("NANA_FILEBOX_FILTER"));
filter_.events().key_release.connect_unignorable([this](const arg_keyboard&)
{
@@ -165,23 +169,23 @@ namespace nana
});
btn_folder_.create(*this);
btn_folder_.caption("&New Folder");
btn_folder_.i18n(i18n_eval("NANA_FILEBOX_NEW_FOLDER_SHORTKEY"));
btn_folder_.events().click.connect_unignorable([this](const arg_click&)
{
form fm(this->handle(), API::make_center(*this, 300, 35));
fm.caption("Name the new folder");
fm.i18n(i18n_eval("NANA_FILEBOX_NEW_FOLDER_CAPTION"));
textbox folder(fm, nana::rectangle(5, 5, 160, 25));
folder.multi_lines(false);
button btn(fm, nana::rectangle(170, 5, 60, 25));
btn.caption("Create");
btn.i18n(i18n_eval("NANA_BUTTON_CREATE"));
btn.events().click.connect_unignorable(folder_creator(*this, fm, folder));
button btn_cancel(fm, nana::rectangle(235, 5, 60, 25));
btn_cancel.caption("Cancel");
btn_cancel.i18n(i18n_eval("NANA_BUTTON_CANCEL"));
btn_cancel.events().click.connect_unignorable([&fm](const arg_click&)
{
@@ -193,10 +197,10 @@ namespace nana
tree_.create(*this);
ls_file_.create(*this);
ls_file_.append_header("Name", 190);
ls_file_.append_header("Modified", 145);
ls_file_.append_header("Type", 80);
ls_file_.append_header("Size", 70);
ls_file_.append_header(i18n("NANA_FILEBOX_HEADER_NAME"), 190);
ls_file_.append_header(i18n("NANA_FILEBOX_HEADER_MODIFIED"), 145);
ls_file_.append_header(i18n("NANA_FILEBOX_HEADER_TYPE"), 80);
ls_file_.append_header(i18n("NANA_FILEBOX_HEADER_SIZE"), 70);
auto fn_sel_file = [this](const arg_mouse& arg){
_m_sel_file(arg);
@@ -274,7 +278,7 @@ namespace nana
});
lb_file_.create(*this);
lb_file_.caption("File:");
lb_file_.i18n(i18n_eval("NANA_FILEBOX_FILE_COLON"));
tb_file_.create(*this);
tb_file_.multi_lines(false);
@@ -290,14 +294,15 @@ namespace nana
cb_types_.events().selected.connect_unignorable([this](const arg_combox&){ _m_list_fs(); });
btn_ok_.create(*this);
btn_ok_.caption("&OK");
btn_ok_.i18n(i18n_eval("NANA_BUTTON_OK_SHORTKEY"));
btn_ok_.events().click.connect_unignorable([this](const arg_click&)
{
_m_ok();
});
btn_cancel_.create(*this);
btn_cancel_.caption("&Cancel");
btn_cancel_.i18n(i18n_eval("NANA_BUTTON_CANCEL_SHORTKEY"));
btn_cancel_.events().click.connect_unignorable([this](const arg_click&)
{
@@ -309,7 +314,7 @@ namespace nana
_m_init_tree();
if(0 == title.size())
caption(io_read ? "Open" : "Save As");
this->i18n(i18n_eval(io_read ? "NANA_FILEBOX_OPEN" : "NANA_FILEBOX_SAVE_AS"));
else
caption(title);
}
@@ -640,11 +645,12 @@ namespace nana
{
auto path = tx_path_.caption();
msgbox mb(fm_, "Create Folder");
internationalization i18n;
msgbox mb(fm_, i18n("NANA_FILEBOX_NEW_FOLDER"));
mb.icon(msgbox::icon_warning);
if(0 == path.size() || path[0] == '.' || path[0] == '/')
{
mb<<L"Please input a valid name for the new folder.";
mb << i18n("NANA_FILEBOX_ERROR_INVALID_FOLDER_NAME");
mb();
return;
}
@@ -657,14 +663,14 @@ namespace nana
if(fst.type() != file_type::not_found && fst.type() != file_type::none)
{
mb<<L"The folder is existing, please rename it.";
mb<<i18n("NANA_FILEBOX_ERROR_RENAME_FOLDER_BECAUSE_OF_EXISTING");
mb();
return;
}
if(false == fs::create_directory(fspath))
{
mb<<L"Failed to create the folder, please rename it.";
mb<<i18n("NANA_FILEBOX_ERROR_RENAME_FOLDER_BECAUSE_OF_FAILED_CREATION");
mb();
return;
}
@@ -734,69 +740,74 @@ namespace nana
void _m_ok()
{
if(0 == selection_.target.size())
std::string tar = selection_.target;
if(selection_.target.empty())
{
auto file = tb_file_.caption();
if(file.size())
{
if(file[0] == L'.')
internationalization i18n;
if(file[0] == '.')
{
msgbox mb(*this, caption());
mb.icon(msgbox::icon_warning);
mb<<file<<std::endl<<L"The filename is invalid.";
mb<<file<<std::endl<<i18n("NANA_FILEBOX_ERROR_INVALID_FILENAME");
mb();
return;
}
std::string tar;
if(file[0] == '/')
tar = file;
else
tar = addr_.filesystem + file;
bool good = true;
auto fattr = fs::status(tar);
if(fattr.type() == fs::file_type::not_found)
//Check if the selected name is a directory
auto is_dir = fs::is_directory(fattr);
if(!is_dir && _m_append_def_extension(tar))
{
good = (_m_append_def_extension(tar) && (fs::status(tar).type() == fs::file_type::not_found));
//Add the extension, then check if it is a directory again.
fattr = fs::status(tar);
is_dir = fs::is_directory(fattr);
}
if(good && fs::is_directory(fattr))
if(is_dir)
{
_m_load_cat_path(tar);
tb_file_.caption("");
tb_file_.caption(std::string{});
return;
}
if(io_read_)
{
if(false == good)
if(fs::file_type::not_found == fattr.type())
{
msgbox mb(*this, caption());
mb.icon(msgbox::icon_information);
mb<<L"The file \""<<nana::charset(tar, nana::unicode::utf8)<<L"\"\n is not existing. Please check and retry.";
mb << i18n("NANA_FILEBOX_ERROR_NOT_EXISTING_AND_RETRY", tar);
mb();
return;
}
else
_m_finish(kind::filesystem, tar);
}
else
{
if(good)
if(fs::file_type::not_found != fattr.type())
{
msgbox mb(*this, caption(), msgbox::yes_no);
mb.icon(msgbox::icon_question);
mb<<L"The input file is existing, do you want to overwrite it?";
mb<<i18n("NANA_FILEBOX_ERROR_QUERY_REWRITE_BECAUSE_OF_EXISTING");
if(msgbox::pick_no == mb())
return;
}
_m_finish(kind::filesystem, tar);
}
}
}
else
_m_finish(kind::filesystem, selection_.target);
_m_finish(kind::filesystem, tar);
}
void _m_tr_expand(item_proxy node, bool exp)

View File

@@ -61,14 +61,14 @@ namespace nana
{
_m_click(arg);
});
yes_.i18n(i18n_eval("OK"));
yes_.i18n(i18n_eval("NANA_BUTTON_OK"));
width_pixel += 77;
if(msgbox::yes_no == btn || msgbox::yes_no_cancel == btn)
{
yes_.i18n(i18n_eval("Yes"));
yes_.i18n(i18n_eval("NANA_BUTTON_YES"));
no_.create(*this);
no_.i18n(i18n_eval("No"));
no_.i18n(i18n_eval("NANA_BUTTON_NO"));
no_.events().click.connect_unignorable([this](const arg_click& arg)
{
_m_click(arg);
@@ -79,7 +79,7 @@ namespace nana
if(msgbox::yes_no_cancel == btn)
{
cancel_.create(*this);
cancel_.i18n(i18n_eval("Cancel"));
cancel_.i18n(i18n_eval("NANA_BUTTON_CANCEL"));
cancel_.events().click.connect_unignorable([this](const arg_click& arg)
{
_m_click(arg);
@@ -493,7 +493,7 @@ namespace nana
auto desc_extent = desc_.measure(470);
btn_ok_.create(*this);
btn_ok_.i18n(i18n_eval("OK"));
btn_ok_.i18n(i18n_eval("NANA_BUTTON_OK"));
btn_ok_.events().click.connect_unignorable([this]{
if (verifier_ && !verifier_(handle()))
@@ -504,7 +504,7 @@ namespace nana
});
btn_cancel_.create(*this);
btn_cancel_.i18n(i18n_eval("Cancel"));
btn_cancel_.i18n(i18n_eval("NANA_BUTTON_CANCEL"));
btn_cancel_.events().click.connect_unignorable([this]{
close();
});
@@ -1141,7 +1141,7 @@ namespace nana
impl->path_edit.multi_lines(false);
impl->browse.create(impl->dock);
impl->browse.i18n(i18n_eval("Browse"));
impl->browse.i18n(i18n_eval("NANA_BUTTON_BROWSE"));
impl->browse.events().click.connect_unignorable([wd, impl](const arg_click&)
{
impl->fbox.owner(wd);

View File

@@ -331,6 +331,8 @@ namespace nana
impl_->set_icon(image_ico);
impl_->icon = image_ico;
}
#else
static_cast<void>(icon_file); //eliminate unused parameter warning
#endif
}
@@ -341,6 +343,8 @@ namespace nana
auto icon_handle = paint::image_accessor::icon(image_ico);
if (icon_handle)
impl_->icons.emplace_back(static_cast<paint::image&&>(image_ico));
#else
static_cast<void>(icon_file); //eliminate unused parameter warning
#endif
}

View File

@@ -472,8 +472,6 @@ namespace nana
if (depth < 0 || start_pos >= div.length())
return{};
const char* p = div.c_str() + start_pos;
while (depth >= 0)
{
auto pos = div.find_last_of("<>", start_pos);
@@ -1041,6 +1039,49 @@ namespace nana
return result;
}
struct revised_division
{
division * div;
double min_px;
double max_px;
};
static double _m_find_lowest_revised_division(const std::vector<revised_division>& revises, double level_px)
{
double v = (std::numeric_limits<double>::max)();
for(auto & rev : revises)
{
if (rev.min_px >= 0 && rev.min_px < v && rev.min_px > level_px)
v = rev.min_px;
else if (rev.max_px >= 0 && rev.max_px < v)
v = rev.max_px;
}
return v;
}
static std::size_t _m_remove_revised(std::vector<revised_division>& revises, double value, std::size_t& full_count)
{
full_count = 0;
std::size_t reached_mins = 0;
auto i = revises.begin();
while (i != revises.end())
{
if (i->max_px == value)
{
++full_count;
i = revises.erase(i);
}
else
{
if (i->min_px == value)
++reached_mins;
++i;
}
}
return reached_mins;
}
double _m_revise_adjustable(std::pair<unsigned, std::size_t>& fa, unsigned area_px)
{
if (fa.first >= area_px || 0 == fa.second)
@@ -1048,16 +1089,20 @@ namespace nana
double var_px = area_px - fa.first;
struct revise_t
/*
struct revise_t //deprecated
{
division * div;
double min_px;
double max_px;
};
*/
std::size_t min_count = 0;
double sum_min_px = 0;
std::vector<revise_t> revises;
//std::vector<revise_t> revises; //deprecated
std::vector<revised_division> revises;
for (auto& child : children)
{
if ((!child->weight.empty()) || !child->display)
@@ -1090,7 +1135,8 @@ namespace nana
if (revises.empty())
return var_px / fa.second;
auto find_lowest = [&revises](double level_px)
/*
auto find_lowest = [&revises](double level_px) //deprecated
{
double v = (std::numeric_limits<double>::max)();
@@ -1104,7 +1150,9 @@ namespace nana
}
return v;
};
*/
/*
auto remove_full = [&revises](double value, std::size_t& full_count)
{
full_count = 0;
@@ -1126,6 +1174,7 @@ namespace nana
}
return reached_mins;
};
*/
double block_px = 0;
double level_px = 0;
@@ -1134,7 +1183,8 @@ namespace nana
while ((rest_px > 0) && blocks)
{
auto lowest = find_lowest(level_px);
//auto lowest = find_lowest(level_px); //deprecated
auto lowest = _m_find_lowest_revised_division(revises, level_px);
double fill_px = 0;
//blocks may be equal to min_count. E.g, all child divisions have min/max attribute.
if (blocks > min_count)
@@ -1152,7 +1202,8 @@ namespace nana
rest_px -= (lowest-level_px) * (blocks - min_count);
std::size_t full_count;
min_count -= remove_full(lowest, full_count);
//min_count -= remove_full(lowest, full_count); //deprecated
min_count -= _m_remove_revised(revises, lowest, full_count);
blocks -= full_count;
level_px = lowest;
}
@@ -1580,10 +1631,7 @@ namespace nana
name = child->name;
return 1;
}
}
for (auto & child : div->children)
{
auto depth = _m_search_name(child.get(), name);
if (depth >= 0)
return depth + 1;
@@ -2702,7 +2750,8 @@ namespace nana
max_px.reset();
}
//The weight will be ignored if one of min and max is specified.
/*
//The weight will be ignored if one of min and max is specified. //deprecated
if (min_px.empty() && max_px.empty())
{
div->weight = weight;
@@ -2712,6 +2761,23 @@ namespace nana
div->min_px = min_px;
div->max_px = max_px;
}
*/
if (!min_px.empty())
div->min_px = min_px;
if (!max_px.empty())
div->max_px = max_px;
if ((!min_px.empty()) && (!weight.empty()) && (weight.get_value(100) < min_px.get_value(100)))
weight.reset();
if ((!max_px.empty()) && (!weight.empty()) && (weight.get_value(100) > max_px.get_value(100)))
weight.reset();
if(!weight.empty())
div->weight = weight;
div->gap = std::move(gap);

View File

@@ -12,6 +12,9 @@
* @Author: Stefan Pfeifer(st-321), Ariel Vina-Rodriguez (qPCR4vir)
*
* @brief group is a widget used to visually group and layout other widgets.
*
* @contributor:
* dankan1890(https://github.com/dankan1890)
*/
@@ -77,6 +80,9 @@ namespace nana{
if (options.empty())
place_content.field_display(field_options, false);
if (caption.caption().empty())
place_content.field_display(field_title, false);
}
};

View File

@@ -122,12 +122,12 @@ namespace nana
struct column
: public column_interface
{
native_string_type text;
native_string_type caption;
unsigned width_px;
std::pair<unsigned, unsigned> range_width_px;
bool visible_state{ true };
/// Position of column when it was creating
/// Absolute position of column when it was creating
size_type index;
nana::align alignment{ nana::align::left };
@@ -144,7 +144,7 @@ namespace nana
{
if (this != &other)
{
text = other.text;
caption = other.caption;
width_px = other.width_px;
range_width_px = other.range_width_px;
visible_state = other.visible_state;
@@ -157,7 +157,7 @@ namespace nana
}
column(column&& other):
text(std::move(other.text)),
caption(std::move(other.caption)),
width_px(other.width_px),
range_width_px(other.range_width_px),
visible_state(other.visible_state),
@@ -172,7 +172,7 @@ namespace nana
{
if (this != &other)
{
text = std::move(other.text);
caption = std::move(other.caption);
width_px = other.width_px;
range_width_px = other.range_width_px;
visible_state = other.visible_state;
@@ -184,7 +184,7 @@ namespace nana
}
column(essence* ess, native_string_type&& text, unsigned px, size_type pos) :
text(std::move(text)),
caption(std::move(text)),
width_px(px),
index(pos),
ess_(ess)
@@ -232,6 +232,19 @@ namespace nana
}
}
size_type position(bool disp_order) const noexcept override; //The definition is provided after essence
std::string text() const noexcept override
{
return to_utf8(caption);
}
void text(std::string text_utf8) override
{
caption = to_nstring(std::move(text_utf8));
_m_refresh();
}
void text_align(::nana::align align) noexcept override
{
if (alignment != align)
@@ -279,7 +292,7 @@ namespace nana
first=false;
else
head_str += exp_opt.sep;
head_str += to_utf8(at(exp_opt.columns_order[idx]).text);
head_str += this->at(exp_opt.columns_order[idx]).text();
}
return head_str;
}
@@ -419,25 +432,55 @@ namespace nana
return cont_;
}
/// find and return a ref to the column that originaly was at position "pos" previous to any list reorganization.
column& at(size_type pos)
size_type cast(size_type pos, bool disp_order) const
{
for(auto & m : cont_)
if (pos >= cont_.size())
throw std::out_of_range("listbox: invalid header index.");
size_type order = 0; //order for display position
for (auto & m : cont_)
{
if (m.index == pos)
return m;
if (!m.visible_state)
continue;
if (disp_order)
{
if (0 == pos)
return m.index;
--pos;
}
else
{
if (m.index == pos)
return order;
++order;
}
}
throw std::out_of_range("Nana.GUI.Listbox: invalid header index.");
throw std::invalid_argument("listbox: invalid header index");
}
const column& at(size_type pos) const
/// find and return a ref to the column that originaly was at position "pos" previous to any list reorganization.
column& at(size_type pos, bool disp_order = false)
{
if(pos >= cont_.size())
throw std::out_of_range("listbox: invalid header index.");
if (!disp_order)
pos = this->cast(pos, false);
return cont_[pos];
}
const column& at(size_type pos, bool disp_order = false) const
{
for(const auto & m : cont_)
{
if (m.index == pos)
return m;
}
throw std::out_of_range("Nana.GUI.Listbox: invalid header index.");
if (pos >= cont_.size())
throw std::out_of_range("listbox: invalid header index.");
if (!disp_order)
pos = this->cast(pos, false);
return cont_[pos];
}
/// Returns the position(original index when it is creating) of the current column at point x
@@ -1315,9 +1358,9 @@ namespace nana
return *(cat->items.at(pos).cells);
}
void text(category_t* cat, size_type pos, size_type col, cell&& cl, size_type columns)
void text(category_t* cat, size_type pos, size_type abs_col, cell&& cl, size_type columns)
{
if ((col < columns) && (pos < cat->items.size()))
if ((abs_col < columns) && (pos < cat->items.size()))
{
std::vector<cell> model_cells;
@@ -1330,16 +1373,16 @@ namespace nana
auto & cells = (cat->model_ptr ? model_cells : *(cat->items[pos].cells));
if (col < cells.size())
if (abs_col < cells.size())
{
cells[col] = std::move(cl);
if (sorted_index_ == col)
cells[abs_col] = std::move(cl);
if (sorted_index_ == abs_col)
sort();
}
else
{ //If the index of specified sub item is over the number of sub items that item contained,
//it fills the non-exist items.
cells.resize(col);
cells.resize(abs_col);
cells.emplace_back(std::move(cl));
}
@@ -1348,9 +1391,9 @@ namespace nana
}
}
void text(category_t* cat, size_type pos, size_type col, std::string&& str, size_type columns)
void text(category_t* cat, size_type pos, size_type abs_col, std::string&& str, size_type columns)
{
if ((col < columns) && (pos < cat->items.size()))
if ((abs_col < columns) && (pos < cat->items.size()))
{
std::vector<cell> model_cells;
@@ -1363,16 +1406,16 @@ namespace nana
auto & cells = (cat->model_ptr ? model_cells : *(cat->items[pos].cells));
if (col < cells.size())
if (abs_col < cells.size())
{
cells[col].text.swap(str);
if (sorted_index_ == col)
cells[abs_col].text.swap(str);
if (sorted_index_ == abs_col)
sort();
}
else
{ //If the index of specified sub item is over the number of sub items that item contained,
//it fills the non-exist items.
cells.resize(col);
cells.resize(abs_col);
cells.emplace_back(std::move(str));
}
@@ -2255,8 +2298,9 @@ namespace nana
/// @param with_rest: Means whether including extra one item that is not completely contained in reset pixels.
size_type number_of_lister_items(bool with_rest) const
{
unsigned lister_s = graph->height() - 2 - header_visible_px() - (scroll.h.empty() ? 0 : scroll.scale);
return (lister_s / scheme_ptr->item_height) + (with_rest && (lister_s % scheme_ptr->item_height) ? 1 : 0);
unsigned exposed_px = content_area().height - header_visible_px() - (scroll.h.empty() ? 0 : scroll.scale);
auto const item_px = (std::max)(static_cast<decltype(scheme_ptr->item_height)>(1), scheme_ptr->item_height);
return (exposed_px / item_px) + (with_rest && (exposed_px % item_px) ? 1 : 0);
}
//keep the first selected item in the display area: the distances are in display positions!
@@ -2362,42 +2406,31 @@ namespace nana
{
internal_scope_guard lock;
const unsigned border_px = 1;
const unsigned border_px_twice = (border_px << 1);
const nana::size sz = graph->size();
if ((sz.width <= border_px_twice) || (sz.height <= border_px_twice))
{
scroll.h.close();
scroll.v.close();
return;
}
auto const ctt_area = this->content_area();
// Adjust the ranged column assume the vertical scrollbar is enabled.
auto range_adjusted = this->header.calc_ranged_columns(sz.width - border_px_twice - scroll.scale);
auto columns_pixels = header.pixels();
auto range_adjusted = this->header.calc_ranged_columns(ctt_area.width - scroll.scale);
auto const columns_pixels = header.pixels();
//H scroll enabled
//If range_adjusted is true, it indicates no horzontal scroll bar is enabled.
bool enable_horz = ((!range_adjusted) && (columns_pixels + 4 > sz.width)); // 4px = left and right borders(2px) + left and right gaps(2px)
bool enable_horz = ((!range_adjusted) && (columns_pixels + 2 > ctt_area.width)); // 2px = left and right gaps(2px)
unsigned head_scroll = 2 + header_visible_px() + (enable_horz ? scroll.scale : 0); // 2px left and right gaps(2px)
unsigned lister_s = sz.height > head_scroll ? sz.height - head_scroll : 0;
size_type screen_number = (lister_s / scheme_ptr->item_height);
size_type exposed_count = ((ctt_area.height > head_scroll ? ctt_area.height - head_scroll : 0) / scheme_ptr->item_height);
//V scroll enabled
auto enable_vert = (lister.the_number_of_expanded() > screen_number);
auto enable_vert = (lister.the_number_of_expanded() > exposed_count);
if (enable_vert)
{
if (!enable_horz)
enable_horz = ((columns_pixels + 2 + scroll.scale) > sz.width);
enable_horz = (columns_pixels + scroll.scale > ctt_area.width);
}
else if (range_adjusted)
{
//No vertical scrollbar, then re-adjust the range columns for a new width that excludes vert scroll.
this->header.calc_ranged_columns(sz.width - border_px_twice);
this->header.calc_ranged_columns(ctt_area.width);
}
//event hander for scrollbars
@@ -2417,7 +2450,7 @@ namespace nana
API::refresh_window(this->lister.wd_ptr()->handle());
};
unsigned horz_px = sz.width - border_px_twice;
auto horz_px = ctt_area.width;
if (enable_vert)
{
if (horz_px < scroll.scale)
@@ -2426,7 +2459,7 @@ namespace nana
horz_px -= scroll.scale;
}
unsigned vert_px = sz.height - border_px_twice;
auto vert_px = ctt_area.height;
if (enable_horz)
{
if (vert_px < scroll.scale)
@@ -2438,7 +2471,7 @@ namespace nana
const auto wd_handle = lister.wd_ptr()->handle();
if (enable_horz && horz_px)
{
rectangle r(border_px, static_cast<int>(sz.height - border_px) - static_cast<int>(scroll.scale), horz_px, scroll.scale);
rectangle r(ctt_area.x, ctt_area.bottom() - static_cast<int>(scroll.scale), horz_px, scroll.scale);
if(scroll.h.empty())
{
scroll.h.create(wd_handle, r);
@@ -2453,7 +2486,7 @@ namespace nana
if (enable_vert && vert_px)
{
rectangle r(static_cast<int>(sz.width - border_px) - static_cast<int>(scroll.scale), border_px, scroll.scale, vert_px);
rectangle r(ctt_area.right() - static_cast<int>(scroll.scale), ctt_area.y, scroll.scale, vert_px);
if(scroll.v.empty())
{
scroll.v.create(wd_handle, r);
@@ -2554,28 +2587,43 @@ namespace nana
pos.x += static_cast<int>(scroll.x_offset()) - 2;
}
bool rect_header(nana::rectangle& r) const
void draw_peripheral()
{
if(header.visible())
{
if (lister.wd_ptr()->borderless())
{
r.dimension(graph->size());
r.height = scheme_ptr->header_height;
return !r.empty();
}
auto ctt_area = this->content_area();
if (!API::widget_borderless(*lister.wd_ptr()))
{
//Draw Border
graph->rectangle(false, static_cast<color_rgb>(0x9cb6c5));
graph->line({ ctt_area.x, ctt_area.y }, { ctt_area.x, ctt_area.bottom() - 1 }, colors::white);
graph->line({ ctt_area.right() - 1, ctt_area.y }, { ctt_area.right() - 1, ctt_area.bottom() - 1 });
const unsigned ex_width = 4 + (scroll.v.empty() ? 0 : scroll.scale - 1);
if(graph->width() > ex_width)
{
r.x = 2;
r.y = 1;
r.width = graph->width() - ex_width;
r.height = scheme_ptr->header_height;
return true;
}
}
return false;
if ((scroll.h.empty() == false) && (scroll.v.empty() == false))
{
graph->rectangle({ ctt_area.right() - static_cast<int>(scroll.scale),
ctt_area.bottom() - static_cast<int>(scroll.scale),
scroll.scale,
scroll.scale },
true, colors::button_face);
}
}
rectangle content_area() const
{
rectangle r{ graph->size() };
if (!this->listbox_ptr->borderless())
{
r.x = 1;
r.width -= (r.width > 2 ? 2 : r.width);
r.y = 1;
r.height -= (r.height > 2 ? 2 : r.height);
}
return r;
}
unsigned header_visible_px() const
@@ -2583,31 +2631,45 @@ namespace nana
return (header.visible() ? scheme_ptr->header_height : 0);
}
bool rect_header(nana::rectangle& r) const
{
if(header.visible())
{
r = this->content_area();
r.height = scheme_ptr->header_height;
if (lister.wd_ptr()->borderless())
return !r.empty();
const unsigned ex_width = 2 + (scroll.v.empty() ? 0 : scroll.scale - 1);
if(r.width > ex_width)
{
r.x += 1;
r.width -= ex_width;
return true;
}
}
return false;
}
bool rect_lister(nana::rectangle& r) const
{
auto head_pixels = header_visible_px();
unsigned width = (scroll.v.empty() ? 0 : scroll.scale - 1);
unsigned height = (scroll.h.empty() ? 0 : scroll.scale) + head_pixels;
unsigned extr_w = (scroll.v.empty() ? 0 : scroll.scale - 1);
unsigned extr_h = (scroll.h.empty() ? 0 : scroll.scale) + head_pixels;
r = this->content_area();
r.y += head_pixels;
if (!lister.wd_ptr()->borderless())
{
width += 4;
height += 2;
r.x = 2;
r.y = head_pixels + 1;
}
else
{
r.x = 0;
r.y = head_pixels;
extr_w += 2;
r.x += 1;
}
nana::size gsz = graph->size();
if(gsz.width <= width || gsz.height <= height) return false;
if(r.width <= extr_w || r.height <= extr_h)
return false;
r.width = gsz.width - width;
r.height = gsz.height - height;
return true;
}
@@ -2967,6 +3029,11 @@ namespace nana
API::refresh_window(ess_->lister.wd_ptr()->handle());
}
size_type es_header::column::position(bool disp_order) const noexcept
{
return (disp_order ? ess_->header.cast(index, false) : index);
}
void es_header::column::fit_content(unsigned maximize) noexcept
{
auto content_px = ess_->lister.column_content_pixels(index);
@@ -3510,7 +3577,7 @@ namespace nana
else if (align::center == column.alignment)
text_margin = 0;
text_aligner.draw(column.text, text_pos, column_r.width - text_margin);
text_aligner.draw(column.caption, text_pos, column_r.width - text_margin);
}
if (column.index == essence_->lister.sort_index())
@@ -3745,7 +3812,7 @@ namespace nana
//Draw selecting inner rectangle
if (sel && (categ.expand == false))
{
_m_draw_border(r.x, y, (std::min)(r.width, width - essence_->scroll.x_offset()));
_m_draw_item_border(r.x, y, (std::min)(r.width, width - essence_->scroll.x_offset()));
}
}
@@ -3807,6 +3874,8 @@ namespace nana
if (col.width_px > essence_->scheme_ptr->text_margin)
{
int content_pos = 0;
element_state estate = element_state::normal;
nana::rectangle img_r;
//Draw the image in the 1st column in display order
if (0 == display_order)
@@ -3815,7 +3884,6 @@ namespace nana
{
content_pos += 18; // checker width, geom scheme?
element_state estate = element_state::normal;
if (essence_->pointer_where.first == parts::checker)
{
switch (state)
@@ -3830,7 +3898,6 @@ namespace nana
using state = facade<element::crook>::state;
crook_renderer_.check(item.flags.checked ? state::checked : state::unchecked);
crook_renderer_.draw(*graph, bgcolor, fgcolor, essence_->checkarea(column_x, y), estate);
}
if (essence_->if_image)
@@ -3838,10 +3905,10 @@ namespace nana
//Draw the image in the 1st column in display order
if (item.img)
{
nana::rectangle img_r(item.img_show_size);
nana::rectangle imgt(item.img_show_size);
img_r = imgt;
img_r.x = content_pos + column_x + (16 - static_cast<int>(item.img_show_size.width)) / 2; // center in 16 - geom scheme?
img_r.y = y + (static_cast<int>(essence_->scheme_ptr->item_height) - static_cast<int>(item.img_show_size.height)) / 2; // center
item.img.stretch(rectangle{ item.img.size() }, *graph, img_r);
}
content_pos += 18; // image width, geom scheme?
}
@@ -3903,24 +3970,32 @@ namespace nana
}
}
auto cell_txtcolor = fgcolor;
if (cells.size() > column_pos) // process only if the cell is visible
{
auto cell_txtcolor = fgcolor;
auto & m_cell = cells[column_pos];
review_utf8(m_cell.text);
if (m_cell.custom_format && (!m_cell.custom_format->bgcolor.invisible())) // adapt to costum format if need
if (m_cell.custom_format) // adapt to costum format if need
{
it_bgcolor = m_cell.custom_format->bgcolor;
if (item.flags.selected)
it_bgcolor = it_bgcolor.blend(bgcolor, 0.5);
if (item_state::highlighted == state)
it_bgcolor = it_bgcolor.blend(static_cast<color_rgb>(0x99defd), 0.8);
if (!item.bgcolor.invisible())
cell_txtcolor = m_cell.custom_format->bgcolor;
graph->rectangle(rectangle{ column_x, y, col.width_px, essence_->scheme_ptr->item_height }, true, it_bgcolor);
if (item.flags.selected) // fetch the "def" colors
it_bgcolor = essence_->scheme_ptr->item_selected;
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_->scheme_ptr->item_height }, true, it_bgcolor);
}
if (draw_column)
@@ -3938,6 +4013,14 @@ namespace nana
}
}
if (0 == display_order)
{
if (essence_->checkable)
crook_renderer_.draw(*graph, it_bgcolor, cell_txtcolor, essence_->checkarea(column_x, y), estate);
if (item.img)
item.img.stretch(rectangle{ item.img.size() }, *graph, img_r);
}
graph->line({ column_x - 1, y }, { column_x - 1, y + static_cast<int>(essence_->scheme_ptr->item_height) - 1 }, static_cast<color_rgb>(0xEBF4F9));
}
@@ -3946,7 +4029,7 @@ namespace nana
//Draw selecting inner rectangle
if(item.flags.selected)
_m_draw_border(content_r.x, y, show_w);
_m_draw_item_border(content_r.x, y, show_w);
}
inline_pane * _m_get_inline_pane(const category_t& cat, std::size_t column_pos) const
@@ -3985,7 +4068,7 @@ namespace nana
return nullptr;
}
void _m_draw_border(int x, int y, unsigned width) const
void _m_draw_item_border(int x, int y, unsigned width) const
{
//Draw selecting inner rectangle
rectangle r{ x, y, width, essence_->scheme_ptr->item_height };
@@ -4021,36 +4104,11 @@ namespace nana
return *essence_;
}
void trigger::_m_draw_border()
{
if (API::widget_borderless(*essence_->lister.wd_ptr()))
return;
auto & graph = *essence_->graph;
int right = static_cast<int>(graph.width()) - 1;
int bottom = static_cast<int>(graph.height()) - 1;
//Draw Border
graph.rectangle(false, static_cast<color_rgb>(0x9cb6c5));
graph.line({ 1, 1 }, { 1, bottom - 1}, colors::white);
graph.line({ right - 1, 1 }, { right - 1, bottom - 1 });
if ((essence_->scroll.h.empty() == false) && (essence_->scroll.v.empty() == false))
graph.rectangle({ right - static_cast<int>(essence_->scroll.scale),
bottom - static_cast<int>(essence_->scroll.scale),
essence_->scroll.scale,
essence_->scroll.scale },
true, colors::button_face);
}
void trigger::attached(widget_reference widget, graph_reference graph)
{
essence_->listbox_ptr = static_cast<nana::listbox*>(&widget);
essence_->scheme_ptr = static_cast<::nana::listbox::scheme_type*>(API::dev::get_scheme(widget));
essence_->graph = &graph;
typeface_changed(graph);
essence_->lister.bind(essence_, widget);
widget.bgcolor(colors::white);
@@ -4081,7 +4139,8 @@ namespace nana
drawer_header_->draw(graph, r);
if (essence_->rect_lister(r))
drawer_lister_->draw(r);
_m_draw_border();
essence_->draw_peripheral();
}
void trigger::mouse_move(graph_reference graph, const arg_mouse& arg)
@@ -4274,7 +4333,7 @@ namespace nana
if(update)
{
_m_draw_border();
essence_->draw_peripheral();
API::dev::lazy_refresh();
}
}
@@ -4461,7 +4520,7 @@ namespace nana
export_options exp_opt {essence_->def_exp_options};
exp_opt.columns_order = essence_->header.all_headers(true);
exp_opt.only_selected_items = true;
::nana::system::dataexch().set(essence_->to_string(exp_opt));
::nana::system::dataexch().set(essence_->to_string(exp_opt), API::root(essence_->listbox_ptr->handle()));
return;
}
case keyboard::select_all :
@@ -4626,6 +4685,12 @@ namespace nana
return ess_->header.cont().size();
}
size_type item_proxy::column_cast(size_type pos, bool disp_order) const
{
return ess_->header.cast(pos, disp_order);
}
item_proxy& item_proxy::text(size_type col, cell cl)
{
ess_->lister.text(cat_, pos_.item, col, std::move(cl), columns());
@@ -5104,25 +5169,25 @@ namespace nana
internal_scope_guard lock;
auto const pos = cat_->items.size();
if (cat_->model_ptr)
{
es_lister::throw_if_immutable_model(cat_->model_ptr.get());
auto container = cat_->model_ptr->container();
auto item_index = container->size();
cat_->items.emplace_back();
container->emplace_back();
container->assign(item_index, cells);
container->assign(pos, cells);
}
else
{
cat_->sorted.push_back(cat_->items.size());
cells.resize(columns());
cat_->items.emplace_back(std::move(cells));
}
cat_->sorted.push_back(pos);
assign_colors_for_last(ess_, cat_);
}
@@ -5407,14 +5472,14 @@ namespace nana
return item_pos;
}
auto listbox::column_at(size_type pos) -> column_interface&
auto listbox::column_at(size_type pos, bool disp_order) -> column_interface&
{
return _m_ess().header.at(pos);
return _m_ess().header.at(pos, disp_order);
}
auto listbox::column_at(size_type pos) const -> const column_interface&
auto listbox::column_at(size_type pos, bool disp_order) const -> const column_interface&
{
return _m_ess().header.at(pos);
return _m_ess().header.at(pos, disp_order);
}
auto listbox::column_size() const ->size_type

View File

@@ -2311,7 +2311,7 @@ namespace nana{ namespace widgets
{
auto text = _m_make_select_string();
if (!text.empty())
nana::system::dataexch().set(text);
nana::system::dataexch().set(text, API::root(this->window_));
}
void text_editor::cut()

View File

@@ -866,8 +866,7 @@ namespace nana
item_proxy& item_proxy::check(bool ck)
{
trigger_->check(node_, ck ? checkstate::checked : checkstate::unchecked);
if(trigger_->draw())
API::update_window(trigger_->impl()->data.widget_ptr->handle());
trigger_->draw();
return *this;
}
@@ -1664,7 +1663,8 @@ namespace nana
if (!impl_->attr.auto_draw)
return false;
impl_->draw(false);
if(impl_->draw(false))
API::update_window(impl_->data.widget_ptr->handle());
return true;
}
@@ -2198,6 +2198,13 @@ namespace nana
return get_drawer_trigger().checkable();
}
void treebox::clear()
{
auto impl = get_drawer_trigger().impl();
impl->attr.tree_cont.clear();
get_drawer_trigger().draw();
}
treebox::node_image_type& treebox::icon(const std::string& id) const
{
return get_drawer_trigger().icon(id);

View File

@@ -41,7 +41,7 @@ namespace nana
class tokenizer
{
public:
tokenizer(const std::string& file)
tokenizer(const std::string& file, bool utf8)
{
std::ifstream ifs(file.data(), std::ios::binary);
if (ifs)
@@ -54,6 +54,11 @@ namespace nana
data_.reset(new char[len]);
ifs.read(data_.get(), len);
read_ptr_ = data_.get();
if (utf8 && len > 3)
{
if (static_cast<unsigned char>(read_ptr_[0]) == 0xEF && static_cast<unsigned char>(read_ptr_[1]) == 0xBB && static_cast<unsigned char>(read_ptr_[2]) == 0xBF)
read_ptr_ += 3;
}
end_ptr_ = read_ptr_ + len;
}
}
@@ -78,6 +83,7 @@ namespace nana
if (escape)
{
escape = false;
str_ += '\\';
str_ += *i;
continue;
}
@@ -151,7 +157,44 @@ namespace nana
struct data
{
std::function<void(const std::string&)> on_missing;
std::unordered_map<std::string, std::string> table;
data()
{
//initializes nana's translation
table["NANA_BUTTON_OK"] = "OK";
table["NANA_BUTTON_OK_SHORTKEY"] = "&OK";
table["NANA_BUTTON_YES"] = "Yes";
table["NANA_BUTTON_NO"] = "No";
table["NANA_BUTTON_BROWSE"] = "Browse";
table["NANA_BUTTON_CANCEL"] = "Cancel";
table["NANA_BUTTON_CANCEL_SHORTKEY"] = "&Cancel";
table["NANA_BUTTON_CREATE"] = "Create";
table["NANA_FILEBOX_BYTES"] = "Bytes";
table["NANA_FILEBOX_FILESYSTEM"] = "FILESYSTEM";
table["NANA_FILEBOX_FILTER"] = "Filter";
table["NANA_FILEBOX_NEW_FOLDER"] = "New Folder";
table["NANA_FILEBOX_NEW_FOLDER_SHORTKEY"] = "&New Folder";
table["NANA_FILEBOX_HEADER_NAME"] = "Name";
table["NANA_FILEBOX_HEADER_MODIFIED"] = "Modified";
table["NANA_FILEBOX_HEADER_TYPE"] = "Type";
table["NANA_FILEBOX_HEADER_SIZE"] = "Size";
table["NANA_FILEBOX_NEW_FOLDER_CAPTION"] = "Name the new folder";
table["NANA_FILEBOX_SAVE_AS"] = "Save As";
table["NANA_FILEBOX_OPEN"] = "Open";
table["NANA_FILEBOX_DIRECTORY"] = "Directory";
table["NANA_FILEBOX_FILE"] = "File";
table["NANA_FILEBOX_FILE_COLON"] = "File:";
table["NANA_FILEBOX_ERROR_INVALID_FOLDER_NAME"] = "Please input a valid name for the new folder.";
table["NANA_FILEBOX_ERROR_RENAME_FOLDER_BECAUSE_OF_EXISTING"] = "The folder is existing, please rename it.";
table["NANA_FILEBOX_ERROR_RENAME_FOLDER_BECAUSE_OF_FAILED_CREATION"] = "Failed to create the folder, please rename it.";
table["NANA_FILEBOX_ERROR_INVALID_FILENAME"] = "The filename is invalid.";
table["NANA_FILEBOX_ERROR_NOT_EXISTING_AND_RETRY"] = "The file \"%arg0\"\n is not existing. Please check and retry.";
table["NANA_FILEBOX_ERROR_QUERY_REWRITE_BECAUSE_OF_EXISTING"] = "The input file is existing, do you want to overwrite it?";
}
};
static std::shared_ptr<data>& get_data_ptr()
@@ -167,7 +210,7 @@ namespace nana
{
auto impl = std::make_shared<data>();
tokenizer tknizer(file);
tokenizer tknizer(file, utf8);
while (true)
{
if (token::msgid != tknizer.read())
@@ -188,9 +231,9 @@ namespace nana
std::string str;
if (utf8)
str = nana::charset(std::move(tknizer.get_str()), nana::unicode::utf8);
str = tknizer.get_str();
else
str = nana::charset(std::move(tknizer.get_str()));
str = nana::charset(std::move(tknizer.get_str())).to_bytes(nana::unicode::utf8);
std::string::size_type pos = 0;
while (true)
@@ -293,6 +336,10 @@ namespace nana
}
}//end namespace internationalization_parts
void internationalization::set_missing(std::function<void(const std::string& msgid_utf8)> handler)
{
internationalization_parts::get_data_ptr()->on_missing = std::move(handler);
}
void internationalization::load(const std::string& file)
{
@@ -324,6 +371,9 @@ namespace nana
if (i != impl->table.end())
return i->second;
if (impl->on_missing)
impl->on_missing(msgid);
return std::move(msgid);
}

View File

@@ -57,7 +57,7 @@ typedef struct
class image_ico_ex
: public basic_image_pixbuf
{
bool _m_read_ico(const void* data, std::size_t size)
bool _m_read_ico(const void* data, std::size_t /*size*/)
{
auto width = 0;
auto height = 0;
@@ -94,7 +94,7 @@ class image_ico_ex
cursor += offset;
auto icon = reinterpret_cast<ICONIMAGE*>(cursor);
auto realBitsCount = static_cast<int>(icon->icHeader.biBitCount);
auto hasAndMask = (realBitsCount < 32) && (height != icon->icHeader.biHeight);
auto hasAndMask = (realBitsCount < 32) && (height != static_cast<int>(icon->icHeader.biHeight));
cursor += 40;
pixbuf_.open(width, height);

View File

@@ -777,12 +777,22 @@ namespace paint
::ReleaseDC(reinterpret_cast<HWND>(dst), dc);
}
#elif defined(NANA_X11)
Display * display = nana::detail::platform_spec::instance().open_display();
auto & spec = nana::detail::platform_spec::instance();
Display * display = spec.open_display();
nana::detail::platform_scope_guard lock;
::XCopyArea(display,
impl_->handle->pixmap, reinterpret_cast<Window>(dst), impl_->handle->context,
sx, sy, width, height, dx, dy);
::XMapWindow(display, reinterpret_cast<Window>(dst));
XWindowAttributes attr;
spec.set_error_handler();
::XGetWindowAttributes(display, reinterpret_cast<Window>(dst), &attr);
if(BadWindow != spec.rev_error_handler() && attr.map_state != IsUnmapped)
::XMapWindow(display, reinterpret_cast<Window>(dst));
::XFlush(display);
#endif
}

View File

@@ -457,7 +457,8 @@ namespace nana{ namespace paint
HDC context = drawable->context;
HBITMAP pixmap = drawable->pixmap;
HBITMAP orig_bmp = pixmap;
HBITMAP orig_bmp = nullptr;
if(need_dup)
{
context = ::CreateCompatibleDC(drawable->context);
@@ -795,7 +796,8 @@ namespace nana{ namespace paint
std::unique_ptr<unsigned char[]> autoptr;
auto rgb_color = clr.px_color().value;
nana::pixel_color_t rgb_imd = { 0 };
nana::pixel_color_t rgb_imd = {};
if(fade)
{
autoptr = detail::alloc_fade_table(1 - fade_rate);

View File

@@ -29,28 +29,28 @@
namespace nana{ namespace system{
//class dataexch
void dataexch::set(const std::string& text)
void dataexch::set(const std::string& text, native_window_type owner)
{
#ifdef NANA_WINDOWS
std::wstring wstr = ::nana::charset(text, nana::unicode::utf8);
_m_set(format::text, wstr.c_str(), (wstr.length() + 1) * sizeof(wchar_t));
_m_set(format::text, wstr.c_str(), (wstr.length() + 1) * sizeof(wchar_t), owner);
#elif defined(NANA_X11)
_m_set(format::text, text.c_str(), text.length() + 1);
_m_set(format::text, text.c_str(), text.length() + 1, owner);
#endif
}
void dataexch::set(const std::wstring& text)
void dataexch::set(const std::wstring& text, native_window_type owner)
{
#ifdef NANA_WINDOWS
_m_set(format::text, text.c_str(), (text.length() + 1) * sizeof(wchar_t));
_m_set(format::text, text.c_str(), (text.length() + 1) * sizeof(wchar_t), owner);
#else
std::string str = to_utf8(text);
_m_set(format::text, str.c_str(), str.size() + 1);
_m_set(format::text, str.c_str(), str.size() + 1, owner);
#endif
}
bool dataexch::set(const nana::paint::graphics& g)
bool dataexch::set(const nana::paint::graphics& g, native_window_type owner)
{
#if defined(NANA_WINDOWS)
size sz = g.size();
@@ -100,11 +100,14 @@ namespace nana{ namespace system{
}
if (::GlobalUnlock(h_gmem) || GetLastError() == NO_ERROR)
if (::OpenClipboard(::GetFocus()))
if (::OpenClipboard(reinterpret_cast<HWND>(owner)))
{
if (::EmptyClipboard())
if (::SetClipboardData(CF_DIB, h_gmem))
if (::CloseClipboard())
return true;
::CloseClipboard();
}
}
assert(false);
::GlobalFree(h_gmem);
@@ -180,12 +183,12 @@ namespace nana{ namespace system{
}
}
//private:
bool dataexch::_m_set(format fmt, const void* buf, std::size_t size)
bool dataexch::_m_set(format fmt, const void* buf, std::size_t size, native_window_type owner)
{
bool res = false;
#if defined(NANA_WINDOWS)
if(::OpenClipboard(::GetFocus()))
if(::OpenClipboard(reinterpret_cast<HWND>(owner)))
{
if(::EmptyClipboard())
{
@@ -208,26 +211,18 @@ namespace nana{ namespace system{
}
#elif defined(NANA_X11)
auto & spec = ::nana::detail::platform_spec::instance();
native_window_type owner = nullptr;
Atom atom_type;
switch(fmt)
{
internal_scope_guard lock;
auto wd = detail::bedrock::instance().focus();
if(wd) owner = wd->root;
case format::text: atom_type = spec.atombase().utf8_string; break;
default:
return false;
}
if(owner)
{
Atom atom_type;
switch(fmt)
{
case format::text: atom_type = spec.atombase().utf8_string; break;
default:
return false;
}
spec.write_selection(owner, atom_type, buf, size);
return true;
spec.write_selection(owner, atom_type, buf, size);
return true;
}
#endif
return res;
}

View File

@@ -515,7 +515,7 @@ namespace nana
cur.level = _m_paragraph_level(str, end);
//First character type
bidi_char begin_char_type;
bidi_char begin_char_type = {};
const char_type * begin_character = nullptr;
for(const char_type * c = str; c < end; ++c)
@@ -811,7 +811,7 @@ namespace nana
//N1. A sequence of neutrals takes the direction of the surrounding strong text if the text on both sides has the same direction.
//European and Arabic numbers act as if they were R in terms of their influence on neutrals.
//Start-of-level-run (sor) and end-of-level-run (eor) are used at level run boundaries.
bidi_char left;
bidi_char left = {};
for(auto i = begin_character; i != end; ++i)
{
if(level_of_run != i->level)