Merge branch 'hotfix-1.4.1' into feature-listbox

This commit is contained in:
Jinhao 2016-12-13 08:58:31 +08:00
commit 7535db186c
18 changed files with 1688 additions and 1479 deletions

View File

@ -39,6 +39,9 @@ namespace nana
{ {
namespace listbox namespace listbox
{ {
using size_type = std::size_t;
using native_string_type = ::nana::detail::native_string_type;
/// An interface of column operations /// An interface of column operations
class column_interface class column_interface
{ {
@ -62,6 +65,22 @@ namespace nana
*/ */
virtual void width(unsigned minimum, unsigned maximum) = 0; 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 /// Sets alignment of column text
/** /**
* @param align Alignment * @param align Alignment
@ -625,8 +644,6 @@ namespace nana
std::unique_ptr<container_interface> container_ptr_; 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 /// usefull for both absolute and display (sorted) positions
struct index_pair struct index_pair
@ -839,10 +856,18 @@ namespace nana
size_type columns() const noexcept; size_type columns() const noexcept;
item_proxy& text(size_type col, cell); /// Converts a position of column between display position and absolute position
item_proxy& text(size_type col, std::string); /**
item_proxy& text(size_type col, const std::wstring&); * @param col The display position or absolute position.
std::string text(size_type col) const; * @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&); void icon(const nana::paint::image&);
@ -1377,18 +1402,20 @@ the nana::detail::basic_window member pointer scheme
/// Access a column at specified position /// Access a column at specified position
/** /**
* @param pos Position of column * @param pos Position of column
* @param disp_order Indicates whether the pos is display position or absolute position.
* @return Reference to the requested column * @return Reference to the requested column
* @except std::out_of_range if !(pos < columns()) * @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 /// Access a column at specified position
/** /**
* @param pos Position of column * @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 * @return Constant reference to the requested column
* @except std::out_of_range if !(pos < columns()) * @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 /// Returns the number of columns
size_type column_size() const; size_type column_size() const;
@ -1418,7 +1445,7 @@ the nana::detail::basic_window member pointer scheme
/// Returns an index of item which contains the specified point. /// Returns an index of item which contains the specified point.
index_pair cast(const point & screen_pos) const; index_pair cast(const point & screen_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); size_type column_from_pos(const point & pos);
void checkable(bool); void checkable(bool);

View File

@ -248,7 +248,7 @@ namespace nana
API::refresh_window(this->handle()); 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(); return this->get_drawer_trigger().ext_renderer();
} }

View File

@ -24,6 +24,9 @@ namespace nana
{ {
friend class i18n_eval; friend class i18n_eval;
public: 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(const std::string& file);
void load_utf8(const std::string& file); void load_utf8(const std::string& file);

View File

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

View File

@ -12,7 +12,7 @@
#ifndef NANA_SYSTEM_DATAEXCH_HPP #ifndef NANA_SYSTEM_DATAEXCH_HPP
#define NANA_SYSTEM_DATAEXCH_HPP #define NANA_SYSTEM_DATAEXCH_HPP
#include <nana/basic_types.hpp> #include <nana/gui/basis.hpp>
namespace nana{ namespace nana{
@ -31,15 +31,15 @@ namespace system{
text, pixmap text, pixmap
}; };
void set(const std::string & text_utf8); void set(const std::string & text_utf8, native_window_type owner = nullptr);
void set(const std::wstring& text); 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::string& text_utf8);
void get(std::wstring& text); void get(std::wstring& text);
private: 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); 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) void platform_spec::write_selection(native_window_type owner, Atom type, const void * buf, size_t bufsize)
{ {
platform_scope_guard psg; platform_scope_guard psg;
::XSetSelectionOwner(display_, XA_PRIMARY, reinterpret_cast<Window>(owner), CurrentTime);
::XSetSelectionOwner(display_, atombase_.clipboard, reinterpret_cast<Window>(owner), CurrentTime); ::XSetSelectionOwner(display_, atombase_.clipboard, reinterpret_cast<Window>(owner), CurrentTime);
::XFlush(display_); ::XFlush(display_);
if(XA_STRING == type || atombase_.utf8_string == type) if(XA_STRING == type || atombase_.utf8_string == type)

View File

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

View File

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

View File

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

View File

@ -50,7 +50,7 @@ namespace nana
{ {
std::wstring type; std::wstring type;
ires>>m.name>>type>>type; ires>>m.name>>type>>type;
m.directory = (type == L"Directory"); m.directory = (to_utf8(type) == internationalization()("NANA_FILEBOX_DIRECTORY"));
return ires; return ires;
} }
@ -65,6 +65,8 @@ namespace nana
_m_add(tm, item.modified_time.tm_min)<<':'; _m_add(tm, item.modified_time.tm_min)<<':';
_m_add(tm, item.modified_time.tm_sec); _m_add(tm, item.modified_time.tm_sec);
internationalization i18n;
ores<<item.name<<tm.str(); ores<<item.name<<tm.str();
if(!item.directory) if(!item.directory)
{ {
@ -72,12 +74,12 @@ namespace nana
if(pos != item.name.npos && (pos + 1 < item.name.size())) if(pos != item.name.npos && (pos + 1 < item.name.size()))
ores<<item.name.substr(pos + 1); ores<<item.name.substr(pos + 1);
else else
ores<<L"File"; ores<<i18n("NANA_FILEBOX_FILE");
ores<<_m_trans(item.bytes); ores<<_m_trans(item.bytes);
} }
else else
ores<<L"Directory"; ores << i18n("NANA_FILEBOX_DIRECTORY");
return ores; return ores;
} }
@ -114,7 +116,8 @@ namespace nana
return s + ustr[uid]; return s + ustr[uid];
} }
ss<<bytes<<" Bytes"; internationalization i18n;
ss<<bytes<<" "<<i18n("NANA_FILEBOX_BYTES");
return ss.str(); return ss.str();
} }
}; };
@ -138,6 +141,7 @@ namespace nana
filebox_implement(window owner, bool io_read, const std::string& title) filebox_implement(window owner, bool io_read, const std::string& title)
: form(owner, API::make_center(owner, 630, 440)), io_read_(io_read) : form(owner, API::make_center(owner, 630, 440)), io_read_(io_read)
{ {
internationalization i18n;
path_.create(*this); path_.create(*this);
path_.splitstr("/"); path_.splitstr("/");
path_.events().selected.connect_unignorable([this](const arg_categorize<int>&) path_.events().selected.connect_unignorable([this](const arg_categorize<int>&)
@ -157,7 +161,7 @@ namespace nana
filter_.create(*this); filter_.create(*this);
filter_.multi_lines(false); 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&) filter_.events().key_release.connect_unignorable([this](const arg_keyboard&)
{ {
@ -165,23 +169,23 @@ namespace nana
}); });
btn_folder_.create(*this); 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&) btn_folder_.events().click.connect_unignorable([this](const arg_click&)
{ {
form fm(this->handle(), API::make_center(*this, 300, 35)); 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)); textbox folder(fm, nana::rectangle(5, 5, 160, 25));
folder.multi_lines(false); folder.multi_lines(false);
button btn(fm, nana::rectangle(170, 5, 60, 25)); 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)); btn.events().click.connect_unignorable(folder_creator(*this, fm, folder));
button btn_cancel(fm, nana::rectangle(235, 5, 60, 25)); 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&) btn_cancel.events().click.connect_unignorable([&fm](const arg_click&)
{ {
@ -193,10 +197,10 @@ namespace nana
tree_.create(*this); tree_.create(*this);
ls_file_.create(*this); ls_file_.create(*this);
ls_file_.append_header("Name", 190); ls_file_.append_header(i18n("NANA_FILEBOX_HEADER_NAME"), 190);
ls_file_.append_header("Modified", 145); ls_file_.append_header(i18n("NANA_FILEBOX_HEADER_MODIFIED"), 145);
ls_file_.append_header("Type", 80); ls_file_.append_header(i18n("NANA_FILEBOX_HEADER_TYPE"), 80);
ls_file_.append_header("Size", 70); ls_file_.append_header(i18n("NANA_FILEBOX_HEADER_SIZE"), 70);
auto fn_sel_file = [this](const arg_mouse& arg){ auto fn_sel_file = [this](const arg_mouse& arg){
_m_sel_file(arg); _m_sel_file(arg);
@ -274,7 +278,7 @@ namespace nana
}); });
lb_file_.create(*this); lb_file_.create(*this);
lb_file_.caption("File:"); lb_file_.i18n(i18n_eval("NANA_FILEBOX_FILE_COLON"));
tb_file_.create(*this); tb_file_.create(*this);
tb_file_.multi_lines(false); tb_file_.multi_lines(false);
@ -290,14 +294,15 @@ namespace nana
cb_types_.events().selected.connect_unignorable([this](const arg_combox&){ _m_list_fs(); }); cb_types_.events().selected.connect_unignorable([this](const arg_combox&){ _m_list_fs(); });
btn_ok_.create(*this); 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&) btn_ok_.events().click.connect_unignorable([this](const arg_click&)
{ {
_m_ok(); _m_ok();
}); });
btn_cancel_.create(*this); 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&) btn_cancel_.events().click.connect_unignorable([this](const arg_click&)
{ {
@ -309,7 +314,7 @@ namespace nana
_m_init_tree(); _m_init_tree();
if(0 == title.size()) if(0 == title.size())
caption(io_read ? "Open" : "Save As"); this->i18n(i18n_eval(io_read ? "NANA_FILEBOX_OPEN" : "NANA_FILEBOX_SAVE_AS"));
else else
caption(title); caption(title);
} }
@ -640,11 +645,12 @@ namespace nana
{ {
auto path = tx_path_.caption(); 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); mb.icon(msgbox::icon_warning);
if(0 == path.size() || path[0] == '.' || path[0] == '/') 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(); mb();
return; return;
} }
@ -657,14 +663,14 @@ namespace nana
if(fst.type() != file_type::not_found && fst.type() != file_type::none) 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(); mb();
return; return;
} }
if(false == fs::create_directory(fspath)) 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(); mb();
return; return;
} }
@ -741,11 +747,12 @@ namespace nana
auto file = tb_file_.caption(); auto file = tb_file_.caption();
if(file.size()) if(file.size())
{ {
internationalization i18n;
if(file[0] == '.') if(file[0] == '.')
{ {
msgbox mb(*this, caption()); msgbox mb(*this, caption());
mb.icon(msgbox::icon_warning); mb.icon(msgbox::icon_warning);
mb<<file<<std::endl<<"The filename is invalid."; mb<<file<<std::endl<<i18n("NANA_FILEBOX_ERROR_INVALID_FILENAME");
mb(); mb();
return; return;
} }
@ -780,7 +787,7 @@ namespace nana
{ {
msgbox mb(*this, caption()); msgbox mb(*this, caption());
mb.icon(msgbox::icon_information); mb.icon(msgbox::icon_information);
mb<<"The file \""<<tar<<"\"\n is not existing. Please check and retry."; mb << i18n("NANA_FILEBOX_ERROR_NOT_EXISTING_AND_RETRY", tar);
mb(); mb();
return; return;
@ -792,7 +799,7 @@ namespace nana
{ {
msgbox mb(*this, caption(), msgbox::yes_no); msgbox mb(*this, caption(), msgbox::yes_no);
mb.icon(msgbox::icon_question); mb.icon(msgbox::icon_question);
mb<<"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()) if(msgbox::pick_no == mb())
return; return;
} }

View File

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

View File

@ -1039,6 +1039,49 @@ namespace nana
return result; 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) double _m_revise_adjustable(std::pair<unsigned, std::size_t>& fa, unsigned area_px)
{ {
if (fa.first >= area_px || 0 == fa.second) if (fa.first >= area_px || 0 == fa.second)
@ -1046,16 +1089,20 @@ namespace nana
double var_px = area_px - fa.first; double var_px = area_px - fa.first;
struct revise_t /*
struct revise_t //deprecated
{ {
division * div; division * div;
double min_px; double min_px;
double max_px; double max_px;
}; };
*/
std::size_t min_count = 0; std::size_t min_count = 0;
double sum_min_px = 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) for (auto& child : children)
{ {
if ((!child->weight.empty()) || !child->display) if ((!child->weight.empty()) || !child->display)
@ -1088,7 +1135,8 @@ namespace nana
if (revises.empty()) if (revises.empty())
return var_px / fa.second; 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)(); double v = (std::numeric_limits<double>::max)();
@ -1102,7 +1150,9 @@ namespace nana
} }
return v; return v;
}; };
*/
/*
auto remove_full = [&revises](double value, std::size_t& full_count) auto remove_full = [&revises](double value, std::size_t& full_count)
{ {
full_count = 0; full_count = 0;
@ -1124,6 +1174,7 @@ namespace nana
} }
return reached_mins; return reached_mins;
}; };
*/
double block_px = 0; double block_px = 0;
double level_px = 0; double level_px = 0;
@ -1132,7 +1183,8 @@ namespace nana
while ((rest_px > 0) && blocks) 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; double fill_px = 0;
//blocks may be equal to min_count. E.g, all child divisions have min/max attribute. //blocks may be equal to min_count. E.g, all child divisions have min/max attribute.
if (blocks > min_count) if (blocks > min_count)
@ -1150,7 +1202,8 @@ namespace nana
rest_px -= (lowest-level_px) * (blocks - min_count); rest_px -= (lowest-level_px) * (blocks - min_count);
std::size_t full_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; blocks -= full_count;
level_px = lowest; level_px = lowest;
} }
@ -1578,10 +1631,7 @@ namespace nana
name = child->name; name = child->name;
return 1; return 1;
} }
}
for (auto & child : div->children)
{
auto depth = _m_search_name(child.get(), name); auto depth = _m_search_name(child.get(), name);
if (depth >= 0) if (depth >= 0)
return depth + 1; return depth + 1;
@ -2700,7 +2750,8 @@ namespace nana
max_px.reset(); 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()) if (min_px.empty() && max_px.empty())
{ {
div->weight = weight; div->weight = weight;
@ -2710,6 +2761,23 @@ namespace nana
div->min_px = min_px; div->min_px = min_px;
div->max_px = max_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); div->gap = std::move(gap);

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -41,7 +41,7 @@ namespace nana
class tokenizer class tokenizer
{ {
public: public:
tokenizer(const std::string& file) tokenizer(const std::string& file, bool utf8)
{ {
std::ifstream ifs(file.data(), std::ios::binary); std::ifstream ifs(file.data(), std::ios::binary);
if (ifs) if (ifs)
@ -54,6 +54,11 @@ namespace nana
data_.reset(new char[len]); data_.reset(new char[len]);
ifs.read(data_.get(), len); ifs.read(data_.get(), len);
read_ptr_ = data_.get(); 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; end_ptr_ = read_ptr_ + len;
} }
} }
@ -78,6 +83,7 @@ namespace nana
if (escape) if (escape)
{ {
escape = false; escape = false;
str_ += '\\';
str_ += *i; str_ += *i;
continue; continue;
} }
@ -151,7 +157,44 @@ namespace nana
struct data struct data
{ {
std::function<void(const std::string&)> on_missing;
std::unordered_map<std::string, std::string> table; 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() static std::shared_ptr<data>& get_data_ptr()
@ -167,7 +210,7 @@ namespace nana
{ {
auto impl = std::make_shared<data>(); auto impl = std::make_shared<data>();
tokenizer tknizer(file); tokenizer tknizer(file, utf8);
while (true) while (true)
{ {
if (token::msgid != tknizer.read()) if (token::msgid != tknizer.read())
@ -188,9 +231,9 @@ namespace nana
std::string str; std::string str;
if (utf8) if (utf8)
str = nana::charset(std::move(tknizer.get_str()), nana::unicode::utf8); str = tknizer.get_str();
else 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; std::string::size_type pos = 0;
while (true) while (true)
@ -293,6 +336,10 @@ namespace nana
} }
}//end namespace internationalization_parts }//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) void internationalization::load(const std::string& file)
{ {
@ -324,6 +371,9 @@ namespace nana
if (i != impl->table.end()) if (i != impl->table.end())
return i->second; return i->second;
if (impl->on_missing)
impl->on_missing(msgid);
return std::move(msgid); return std::move(msgid);
} }

View File

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

View File

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

View File

@ -515,7 +515,7 @@ namespace nana
cur.level = _m_paragraph_level(str, end); cur.level = _m_paragraph_level(str, end);
//First character type //First character type
bidi_char begin_char_type; bidi_char begin_char_type = {};
const char_type * begin_character = nullptr; const char_type * begin_character = nullptr;
for(const char_type * c = str; c < end; ++c) for(const char_type * c = str; c < end; ++c)
@ -616,7 +616,7 @@ namespace nana
e.bidi_char_type = bidi_char_type; e.bidi_char_type = bidi_char_type;
} }
std::vector<unicode_bidi::entity>::iterator unicode_bidi::_m_search_first_character() std::vector<unicode_bidi::entity>::iterator unicode_bidi::_m_search_first_character()
{ {
return levels_.begin(); return levels_.begin();
@ -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. //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. //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. //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) for(auto i = begin_character; i != end; ++i)
{ {
if(level_of_run != i->level) if(level_of_run != i->level)