Merge branch 'develop'
This commit is contained in:
commit
b25949c9b3
@ -58,7 +58,7 @@ matrix:
|
|||||||
before_install:
|
before_install:
|
||||||
- git clone --depth=1 --branch=develop https://github.com/qPCR4vir/nana-demo.git ../nana-demo
|
- git clone --depth=1 --branch=develop https://github.com/qPCR4vir/nana-demo.git ../nana-demo
|
||||||
- export PATH="$HOME/bin:$PATH"
|
- export PATH="$HOME/bin:$PATH"
|
||||||
- mkdir ~/bin
|
#- mkdir ~/bin #it seemd that a bin already exists from 20170901
|
||||||
- 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
|
- 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
|
||||||
- chmod -R +x /tmp/tools
|
- chmod -R +x /tmp/tools
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ NANAINC = $(NANAPATH)/include
|
|||||||
NANALIB = $(NANAPATH)/build/bin
|
NANALIB = $(NANAPATH)/build/bin
|
||||||
|
|
||||||
INCS = -I$(NANAINC)
|
INCS = -I$(NANAINC)
|
||||||
LIBS = -L$(NANALIB) -lnana -lX11 -lpthread -lrt -lXft -lpng -lasound
|
LIBS = -L$(NANALIB) -lnana -lX11 -lpthread -lrt -lXft -lpng -lasound -lfontconfig
|
||||||
|
|
||||||
LINKOBJ = $(SOURCES:.cpp=.o)
|
LINKOBJ = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
|||||||
@ -91,9 +91,10 @@ namespace detail
|
|||||||
|
|
||||||
void manage_form_loader(core_window_t*, bool insert_or_remove);
|
void manage_form_loader(core_window_t*, bool insert_or_remove);
|
||||||
public:
|
public:
|
||||||
bool emit(event_code, core_window_t*, const event_arg&, bool ask_update, thread_context*);
|
// if 'bForce__EmitInternal', then ONLY internal (widget's) events are processed (even through explicit filtering)
|
||||||
|
bool emit(event_code, core_window_t*, const event_arg&, bool ask_update, thread_context*, const bool bForce__EmitInternal = false);
|
||||||
private:
|
private:
|
||||||
void _m_emit_core(event_code, core_window_t*, bool draw_only, const event_arg&);
|
void _m_emit_core(event_code, core_window_t*, bool draw_only, const event_arg&, const bool bForce__EmitInternal);
|
||||||
void _m_event_filter(event_code, core_window_t*, thread_context*);
|
void _m_event_filter(event_code, core_window_t*, thread_context*);
|
||||||
private:
|
private:
|
||||||
static bedrock bedrock_object;
|
static bedrock bedrock_object;
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
#include "general_events.hpp"
|
#include "general_events.hpp"
|
||||||
#include <nana/paint/graphics.hpp>
|
#include <nana/paint/graphics.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@ -27,6 +28,25 @@ namespace nana
|
|||||||
class drawer;
|
class drawer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class drawer_trigger;
|
||||||
|
class event_filter_status
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
event_filter_status();
|
||||||
|
event_filter_status(const event_filter_status& rOther);
|
||||||
|
event_filter_status(const unsigned evt_disabled_);
|
||||||
|
const event_filter_status& operator=(const event_filter_status& rOther);
|
||||||
|
const event_filter_status& operator=(const unsigned evt_disabled_);
|
||||||
|
|
||||||
|
bool operator[](const nana::event_code evt_code) const;
|
||||||
|
bool operator==(const event_filter_status& rOther) const;
|
||||||
|
bool operator!=(const event_filter_status& rOther) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned evt_disabled_;
|
||||||
|
friend class drawer_trigger;
|
||||||
|
};
|
||||||
|
|
||||||
class drawer_trigger
|
class drawer_trigger
|
||||||
{
|
{
|
||||||
friend class detail::drawer;
|
friend class detail::drawer;
|
||||||
@ -70,11 +90,19 @@ namespace nana
|
|||||||
virtual void key_release(graph_reference, const arg_keyboard&);
|
virtual void key_release(graph_reference, const arg_keyboard&);
|
||||||
virtual void shortkey(graph_reference, const arg_keyboard&);
|
virtual void shortkey(graph_reference, const arg_keyboard&);
|
||||||
|
|
||||||
|
void filter_event(const event_code evt_code, const bool bDisabled);
|
||||||
|
void filter_event(const std::vector<event_code> evt_codes, const bool bDisabled);
|
||||||
|
void filter_event(const event_filter_status& evt_all_states);
|
||||||
|
bool filter_event(const event_code evt_code);
|
||||||
|
event_filter_status filter_event();
|
||||||
|
void clear_filter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _m_reset_overrided();
|
void _m_reset_overrided();
|
||||||
bool _m_overrided(event_code) const;
|
bool _m_overrided(event_code) const;
|
||||||
private:
|
private:
|
||||||
unsigned overrided_{ 0xFFFFFFFF };
|
unsigned overrided_{ 0xFFFFFFFF };
|
||||||
|
unsigned evt_disabled_{ 0 }; // bit set if event is filtered
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
@ -99,23 +127,23 @@ namespace nana
|
|||||||
void bind(basic_window*);
|
void bind(basic_window*);
|
||||||
|
|
||||||
void typeface_changed();
|
void typeface_changed();
|
||||||
void click(const arg_click&);
|
void click(const arg_click&, const bool);
|
||||||
void dbl_click(const arg_mouse&);
|
void dbl_click(const arg_mouse&, const bool);
|
||||||
void mouse_enter(const arg_mouse&);
|
void mouse_enter(const arg_mouse&, const bool);
|
||||||
void mouse_move(const arg_mouse&);
|
void mouse_move(const arg_mouse&, const bool);
|
||||||
void mouse_leave(const arg_mouse&);
|
void mouse_leave(const arg_mouse&, const bool);
|
||||||
void mouse_down(const arg_mouse&);
|
void mouse_down(const arg_mouse&, const bool);
|
||||||
void mouse_up(const arg_mouse&);
|
void mouse_up(const arg_mouse&, const bool);
|
||||||
void mouse_wheel(const arg_wheel&);
|
void mouse_wheel(const arg_wheel&, const bool);
|
||||||
void mouse_dropfiles(const arg_dropfiles&);
|
void mouse_dropfiles(const arg_dropfiles&, const bool);
|
||||||
void resizing(const arg_resizing&);
|
void resizing(const arg_resizing&, const bool);
|
||||||
void resized(const arg_resized&);
|
void resized(const arg_resized&, const bool);
|
||||||
void move(const arg_move&);
|
void move(const arg_move&, const bool);
|
||||||
void focus(const arg_focus&);
|
void focus(const arg_focus&, const bool);
|
||||||
void key_press(const arg_keyboard&);
|
void key_press(const arg_keyboard&, const bool);
|
||||||
void key_char(const arg_keyboard&);
|
void key_char(const arg_keyboard&, const bool);
|
||||||
void key_release(const arg_keyboard&);
|
void key_release(const arg_keyboard&, const bool);
|
||||||
void shortkey(const arg_keyboard&);
|
void shortkey(const arg_keyboard&, const bool);
|
||||||
void map(window, bool forced, const rectangle* update_area = nullptr); //Copy the root buffer to screen
|
void map(window, bool forced, const rectangle* update_area = nullptr); //Copy the root buffer to screen
|
||||||
void refresh();
|
void refresh();
|
||||||
drawer_trigger* realizer() const;
|
drawer_trigger* realizer() const;
|
||||||
@ -130,7 +158,7 @@ namespace nana
|
|||||||
method_state& _m_mth_state(int pos);
|
method_state& _m_mth_state(int pos);
|
||||||
|
|
||||||
template<typename Arg, typename Mfptr>
|
template<typename Arg, typename Mfptr>
|
||||||
void _m_emit(event_code evt_code, const Arg& arg, Mfptr mfptr)
|
void _m_emit(event_code evt_code, const Arg& arg, Mfptr mfptr, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
const int pos = static_cast<int>(evt_code);
|
const int pos = static_cast<int>(evt_code);
|
||||||
|
|
||||||
@ -139,8 +167,10 @@ namespace nana
|
|||||||
|
|
||||||
if (realizer && (method_state::not_overrided != mth_state))
|
if (realizer && (method_state::not_overrided != mth_state))
|
||||||
{
|
{
|
||||||
|
const bool bFiltered = !bForce__EmitInternal && realizer->filter_event(evt_code);
|
||||||
if (method_state::pending == mth_state)
|
if (method_state::pending == mth_state)
|
||||||
{
|
{
|
||||||
|
if (!bFiltered)
|
||||||
(realizer->*mfptr)(graphics, arg);
|
(realizer->*mfptr)(graphics, arg);
|
||||||
|
|
||||||
//Check realizer, when the window is closed in that event handler, the drawer will be
|
//Check realizer, when the window is closed in that event handler, the drawer will be
|
||||||
@ -149,7 +179,10 @@ namespace nana
|
|||||||
mth_state = (realizer->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided);
|
mth_state = (realizer->_m_overrided(evt_code) ? method_state::overrided : method_state::not_overrided);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (!bFiltered)
|
||||||
(realizer->*mfptr)(graphics, arg);
|
(realizer->*mfptr)(graphics, arg);
|
||||||
|
}
|
||||||
|
|
||||||
_m_effect_bground_subsequent();
|
_m_effect_bground_subsequent();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -108,6 +108,7 @@ namespace nana
|
|||||||
virtual window create(window, unsigned label_px) = 0;
|
virtual window create(window, unsigned label_px) = 0;
|
||||||
virtual unsigned fixed_pixels() const;
|
virtual unsigned fixed_pixels() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class boolean
|
class boolean
|
||||||
: public abstract_content
|
: public abstract_content
|
||||||
@ -240,7 +241,6 @@ namespace nana
|
|||||||
{
|
{
|
||||||
std::vector<abstract_content*> contents;
|
std::vector<abstract_content*> contents;
|
||||||
_m_fetch_args(contents, std::forward<Args>(args)...);
|
_m_fetch_args(contents, std::forward<Args>(args)...);
|
||||||
|
|
||||||
if (contents.empty())
|
if (contents.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -261,6 +261,14 @@ namespace nana
|
|||||||
|
|
||||||
/// Sets a verifier to verify the user input.
|
/// Sets a verifier to verify the user input.
|
||||||
void verify(std::function<bool(window)> verifier);
|
void verify(std::function<bool(window)> verifier);
|
||||||
|
|
||||||
|
/** Sets the minimum width for the entry fields
|
||||||
|
@param[in] pixels new minimum width
|
||||||
|
|
||||||
|
If not called, the default is 100 pixels
|
||||||
|
*/
|
||||||
|
void min_width_entry_field( unsigned pixels );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _m_fetch_args(std::vector<abstract_content*>&);
|
void _m_fetch_args(std::vector<abstract_content*>&);
|
||||||
|
|
||||||
@ -279,6 +287,7 @@ namespace nana
|
|||||||
std::function<bool(window)> verifier_;
|
std::function<bool(window)> verifier_;
|
||||||
::nana::paint::image images_[4];
|
::nana::paint::image images_[4];
|
||||||
::nana::rectangle valid_areas_[4];
|
::nana::rectangle valid_areas_[4];
|
||||||
|
unsigned min_width_entry_field_pixels_;
|
||||||
};
|
};
|
||||||
}//end namespace nana
|
}//end namespace nana
|
||||||
#include <nana/pop_ignore_diagnostic>
|
#include <nana/pop_ignore_diagnostic>
|
||||||
|
|||||||
@ -106,6 +106,8 @@ namespace API
|
|||||||
* This function will copy the drawer surface into system window after the event process finished.
|
* This function will copy the drawer surface into system window after the event process finished.
|
||||||
*/
|
*/
|
||||||
void lazy_refresh();
|
void lazy_refresh();
|
||||||
|
|
||||||
|
void draw_shortkey_underline(paint::graphics&, const std::string& text, wchar_t shortkey, std::size_t shortkey_position, const point& text_pos, const color&);
|
||||||
}//end namespace dev
|
}//end namespace dev
|
||||||
|
|
||||||
/// Returns the widget pointer of the specified window.
|
/// Returns the widget pointer of the specified window.
|
||||||
@ -118,8 +120,13 @@ namespace API
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
general_events* get_general_events(window);
|
general_events* get_general_events(window);
|
||||||
|
|
||||||
|
// emits both internal and external event (internal event can be filtered)
|
||||||
bool emit_event(event_code, window, const ::nana::event_arg&);
|
bool emit_event(event_code, window, const ::nana::event_arg&);
|
||||||
|
|
||||||
|
// explicitly emits internal event (internal event not to be filtered)
|
||||||
|
bool emit_internal_event(event_code, window, const ::nana::event_arg&);
|
||||||
|
|
||||||
class enum_widgets_function_base
|
class enum_widgets_function_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -253,6 +260,12 @@ namespace API
|
|||||||
return detail::emit_event(evt_code, wd, arg);
|
return detail::emit_event(evt_code, wd, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename EventArg, typename std::enable_if<std::is_base_of< ::nana::event_arg, EventArg>::value>::type* = nullptr>
|
||||||
|
bool emit_internal_event(event_code evt_code, window wd, const EventArg& arg)
|
||||||
|
{
|
||||||
|
return detail::emit_internal_event(evt_code, wd, arg);
|
||||||
|
}
|
||||||
|
|
||||||
void umake_event(event_handle);
|
void umake_event(event_handle);
|
||||||
|
|
||||||
template<typename Widget = ::nana::widget>
|
template<typename Widget = ::nana::widget>
|
||||||
|
|||||||
@ -535,7 +535,7 @@ namespace nana
|
|||||||
throw std::invalid_argument("invalid listbox model container type");
|
throw std::invalid_argument("invalid listbox model container type");
|
||||||
|
|
||||||
if (nullptr == p->pointer())
|
if (nullptr == p->pointer())
|
||||||
throw std::runtime_error("the modal is immutable");
|
throw std::runtime_error("the modal is immutable, please declare model_guard with const");
|
||||||
|
|
||||||
return *static_cast<stlcontainer*>(p->pointer());
|
return *static_cast<stlcontainer*>(p->pointer());
|
||||||
}
|
}
|
||||||
@ -1250,8 +1250,9 @@ By \a clicking on one header the list get \a reordered, first up, and then down
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
listbox.anyobj(0, 0, 10); //the type of customer's object is int.
|
auto cat = listbox.at(0);
|
||||||
listbox.anyobj(0, 0, 20);
|
cat.at(0).value(10); //10 is custom data.
|
||||||
|
cat.at(1).value(20); //20 is custom data.
|
||||||
5. listbox is a widget_object, with template parameters drawerbase::listbox::trigger and drawerbase::listbox::scheme
|
5. listbox is a widget_object, with template parameters drawerbase::listbox::trigger and drawerbase::listbox::scheme
|
||||||
amon others.
|
amon others.
|
||||||
That means that listbox have a member trigger_ constructed first and accecible with get_drawer_trigger() and
|
That means that listbox have a member trigger_ constructed first and accecible with get_drawer_trigger() and
|
||||||
@ -1402,7 +1403,9 @@ the nana::detail::basic_window member pointer scheme
|
|||||||
|
|
||||||
/// Scrolls the view to the first or last item of a specified category
|
/// Scrolls the view to the first or last item of a specified category
|
||||||
void scroll(bool to_bottom, size_type cat_pos = ::nana::npos);
|
void scroll(bool to_bottom, size_type cat_pos = ::nana::npos);
|
||||||
void scroll(bool to_bottom, const index_pair& pos);
|
|
||||||
|
/// Scrolls the view to show an item sepcified by absolute position at top/bottom of the listbox.
|
||||||
|
void scroll(bool to_bottom, const index_pair& abs_pos);
|
||||||
|
|
||||||
/// Appends a new column with a header text and the specified width at the end, and return it position
|
/// Appends a new column with a header text and the specified width at the end, and return it position
|
||||||
size_type append_header(std::string text_utf8, unsigned width = 120);
|
size_type append_header(std::string text_utf8, unsigned width = 120);
|
||||||
|
|||||||
@ -181,6 +181,11 @@ namespace nana
|
|||||||
void renderer(const pat::cloneable<renderer_interface>&); ///< Sets a user-defined renderer.
|
void renderer(const pat::cloneable<renderer_interface>&); ///< Sets a user-defined renderer.
|
||||||
const pat::cloneable<renderer_interface>& renderer() const;
|
const pat::cloneable<renderer_interface>& renderer() const;
|
||||||
|
|
||||||
|
/// Returns the handle of menu window
|
||||||
|
/**
|
||||||
|
* @return handle of menu window, nullptr if the menu hasn't been popped up.
|
||||||
|
*/
|
||||||
|
window handle() const;
|
||||||
private:
|
private:
|
||||||
void _m_popup(window, const point& position, bool called_by_menubar);
|
void _m_popup(window, const point& position, bool called_by_menubar);
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* A Menubar implementation
|
* A Menubar implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2009-2014 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2009-2017 Jinhao(cnjinhao@hotmail.com)
|
||||||
*
|
*
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -57,13 +57,11 @@ namespace nana
|
|||||||
class trigger
|
class trigger
|
||||||
: public drawer_trigger
|
: public drawer_trigger
|
||||||
{
|
{
|
||||||
class itembase;
|
struct essence;
|
||||||
public:
|
public:
|
||||||
trigger();
|
trigger();
|
||||||
~trigger();
|
~trigger();
|
||||||
nana::menu* push_back(const std::string&);
|
essence& ess() const;
|
||||||
nana::menu* at(size_t) const;
|
|
||||||
std::size_t size() const;
|
|
||||||
private:
|
private:
|
||||||
void attached(widget_reference, graph_reference) override;
|
void attached(widget_reference, graph_reference) override;
|
||||||
void refresh(graph_reference) override;
|
void refresh(graph_reference) override;
|
||||||
@ -76,38 +74,9 @@ namespace nana
|
|||||||
void key_release(graph_reference, const arg_keyboard&) override;
|
void key_release(graph_reference, const arg_keyboard&) override;
|
||||||
void shortkey(graph_reference, const arg_keyboard&) override;
|
void shortkey(graph_reference, const arg_keyboard&) override;
|
||||||
private:
|
private:
|
||||||
void _m_move(bool to_left);
|
void _m_move(graph_reference, bool to_left);
|
||||||
bool _m_popup_menu();
|
|
||||||
void _m_total_close();
|
|
||||||
bool _m_close_menu();
|
|
||||||
std::size_t _m_item_by_pos(const ::nana::point&);
|
|
||||||
bool _m_track_mouse(const ::nana::point&);
|
|
||||||
private:
|
private:
|
||||||
widget *widget_;
|
essence * const ess_;
|
||||||
paint::graphics *graph_;
|
|
||||||
|
|
||||||
itembase* items_;
|
|
||||||
|
|
||||||
struct state_type
|
|
||||||
{
|
|
||||||
enum behavior_t
|
|
||||||
{
|
|
||||||
behavior_none, behavior_focus, behavior_menu,
|
|
||||||
};
|
|
||||||
|
|
||||||
state_type();
|
|
||||||
|
|
||||||
std::size_t active;
|
|
||||||
behavior_t behavior;
|
|
||||||
|
|
||||||
bool menu_active;
|
|
||||||
bool passive_close;
|
|
||||||
|
|
||||||
bool nullify_mouse;
|
|
||||||
|
|
||||||
nana::menu *menu;
|
|
||||||
nana::point mouse_pos;
|
|
||||||
}state_;
|
|
||||||
};
|
};
|
||||||
}//end namespace menubar
|
}//end namespace menubar
|
||||||
}//end namespace drawerbase
|
}//end namespace drawerbase
|
||||||
@ -126,6 +95,16 @@ namespace nana
|
|||||||
menu& push_back(const std::string&); ///< Appends a new (empty) menu.
|
menu& push_back(const std::string&); ///< Appends a new (empty) menu.
|
||||||
menu& at(size_t index) const; ///< Gets the menu specified by index.
|
menu& at(size_t index) const; ///< Gets the menu specified by index.
|
||||||
std::size_t length() const; ///< Number of menus.
|
std::size_t length() const; ///< Number of menus.
|
||||||
|
|
||||||
|
/// Deselects the menu
|
||||||
|
/**
|
||||||
|
* If a menu is popped up, the menu deselects the item and close the popuped menu.
|
||||||
|
* @return true if an item is deselected, false otherwise.
|
||||||
|
*/
|
||||||
|
bool cancel();
|
||||||
|
|
||||||
|
/// Determines the mouse is hovered on the menubar or its popped menu.
|
||||||
|
bool hovered() const;
|
||||||
private:
|
private:
|
||||||
::nana::event_handle evt_resized_{nullptr};
|
::nana::event_handle evt_resized_{nullptr};
|
||||||
};//end class menubar
|
};//end class menubar
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A Progress Indicator Implementation
|
* A Progress Indicator Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
||||||
*
|
*
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -20,42 +20,37 @@ namespace nana
|
|||||||
{
|
{
|
||||||
namespace progress
|
namespace progress
|
||||||
{
|
{
|
||||||
class trigger: public drawer_trigger
|
struct scheme
|
||||||
|
: public widget_geometrics
|
||||||
|
{
|
||||||
|
scheme();
|
||||||
|
|
||||||
|
color_proxy gradient_bgcolor{ colors::button_face_shadow_start };
|
||||||
|
color_proxy gradient_fgcolor{ static_cast<color_rgb>(0x6FFFA8) };
|
||||||
|
};
|
||||||
|
|
||||||
|
class substance;
|
||||||
|
|
||||||
|
class trigger
|
||||||
|
: public drawer_trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
unsigned value() const;
|
trigger();
|
||||||
unsigned value(unsigned);
|
~trigger();
|
||||||
unsigned inc();
|
|
||||||
unsigned Max() const;
|
substance* progress() const;
|
||||||
unsigned Max(unsigned);
|
|
||||||
void unknown(bool);
|
|
||||||
bool unknown() const;
|
|
||||||
bool stop(bool s = true);
|
|
||||||
bool stopped() const;
|
|
||||||
private:
|
private:
|
||||||
void attached(widget_reference, graph_reference) override;
|
void attached(widget_reference, graph_reference) override;
|
||||||
void refresh(graph_reference) override;
|
void refresh(graph_reference) override;
|
||||||
private:
|
private:
|
||||||
void _m_draw_box(graph_reference);
|
substance* const progress_;
|
||||||
void _m_draw_progress(graph_reference);
|
};
|
||||||
bool _m_check_changing(unsigned) const;
|
|
||||||
private:
|
|
||||||
static const unsigned border = 2;
|
|
||||||
|
|
||||||
widget * widget_{nullptr};
|
|
||||||
nana::paint::graphics* graph_{nullptr};
|
|
||||||
unsigned draw_width_{static_cast<unsigned>(-1)};
|
|
||||||
bool unknown_{false};
|
|
||||||
bool stop_{false};
|
|
||||||
unsigned max_{100};
|
|
||||||
unsigned value_{0};
|
|
||||||
}; //end class drawer
|
|
||||||
}
|
}
|
||||||
}//end namespace drawerbase
|
}//end namespace drawerbase
|
||||||
/// \brief A progressbar widget with two styles: know, and unknow amount value (goal).
|
/// \brief A progressbar widget with two styles: know, and unknow amount value (goal).
|
||||||
/// In unknow style the amount is ignored and the bar is scrolled when value change.
|
/// In unknow style the amount is ignored and the bar is scrolled when value change.
|
||||||
class progress
|
class progress
|
||||||
: public widget_object<category::widget_tag, drawerbase::progress::trigger>
|
: public widget_object<category::widget_tag, drawerbase::progress::trigger, ::nana::general_events, drawerbase::progress::scheme>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
progress();
|
progress();
|
||||||
@ -69,8 +64,6 @@ namespace nana
|
|||||||
unsigned amount(unsigned value);
|
unsigned amount(unsigned value);
|
||||||
void unknown(bool);
|
void unknown(bool);
|
||||||
bool unknown() const;
|
bool unknown() const;
|
||||||
bool stop(bool s=true); ///< request stop or cancel and return previus stop status
|
|
||||||
bool stopped() const;
|
|
||||||
};
|
};
|
||||||
}//end namespace nana
|
}//end namespace nana
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -227,6 +227,39 @@ namespace nana
|
|||||||
{
|
{
|
||||||
return *scheme_;
|
return *scheme_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// disables or re-enables internal handling of event within base-widget
|
||||||
|
void filter_event(const event_code evt_code, const bool bDisabled)
|
||||||
|
{
|
||||||
|
trigger_.filter_event(evt_code, bDisabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void filter_event(const std::vector<event_code> evt_codes, const bool bDisabled)
|
||||||
|
{
|
||||||
|
trigger_.filter_event(evt_codes, bDisabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void filter_event(const event_filter_status& evt_all_states)
|
||||||
|
{
|
||||||
|
trigger_.filter_event(evt_all_states);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_filter()
|
||||||
|
{
|
||||||
|
trigger_.clear_filter();
|
||||||
|
}
|
||||||
|
|
||||||
|
// reads status of if event is filtered
|
||||||
|
bool filter_event(const event_code evt_code)
|
||||||
|
{
|
||||||
|
return trigger_.filter_event(evt_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
event_filter_status filter_event()
|
||||||
|
{
|
||||||
|
return trigger_.filter_event();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DrawerTrigger& get_drawer_trigger()
|
DrawerTrigger& get_drawer_trigger()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -78,7 +78,7 @@ namespace nana{ namespace audio
|
|||||||
void buffer_preparation::revert(meta * m)
|
void buffer_preparation::revert(meta * m)
|
||||||
{
|
{
|
||||||
std::lock_guard<decltype(token_prepared_)> lock(token_prepared_);
|
std::lock_guard<decltype(token_prepared_)> lock(token_prepared_);
|
||||||
bool if_signal = prepared_.empty();
|
auto const if_signal = prepared_.empty();
|
||||||
prepared_.emplace_back(m);
|
prepared_.emplace_back(m);
|
||||||
if(if_signal)
|
if(if_signal)
|
||||||
cond_prepared_.notify_one();
|
cond_prepared_.notify_one();
|
||||||
|
|||||||
@ -100,37 +100,6 @@ namespace detail
|
|||||||
|
|
||||||
font_type font;
|
font_type font;
|
||||||
|
|
||||||
struct pen_spec
|
|
||||||
{
|
|
||||||
HPEN handle;
|
|
||||||
unsigned color;
|
|
||||||
int style;
|
|
||||||
int width;
|
|
||||||
|
|
||||||
void set(HDC context, int style, int width,unsigned color);
|
|
||||||
}pen;
|
|
||||||
|
|
||||||
struct brush_spec
|
|
||||||
{
|
|
||||||
enum t{Solid, HatchBDiagonal};
|
|
||||||
|
|
||||||
HBRUSH handle;
|
|
||||||
t style;
|
|
||||||
unsigned color;
|
|
||||||
|
|
||||||
void set(HDC context, t style, unsigned color);
|
|
||||||
}brush;
|
|
||||||
|
|
||||||
struct round_region_spec
|
|
||||||
{
|
|
||||||
HRGN handle;
|
|
||||||
nana::rectangle r;
|
|
||||||
unsigned radius_x;
|
|
||||||
unsigned radius_y;
|
|
||||||
|
|
||||||
void set(const nana::rectangle& r, unsigned radius_x, unsigned radius_y);
|
|
||||||
}round_region;
|
|
||||||
|
|
||||||
struct string_spec
|
struct string_spec
|
||||||
{
|
{
|
||||||
unsigned tab_length;
|
unsigned tab_length;
|
||||||
@ -148,9 +117,6 @@ namespace detail
|
|||||||
unsigned get_text_color() const;
|
unsigned get_text_color() const;
|
||||||
void set_color(const ::nana::color&);
|
void set_color(const ::nana::color&);
|
||||||
void set_text_color(const ::nana::color&);
|
void set_text_color(const ::nana::color&);
|
||||||
|
|
||||||
void update_pen();
|
|
||||||
void update_brush();
|
|
||||||
private:
|
private:
|
||||||
unsigned color_{ 0xffffffff };
|
unsigned color_{ 0xffffffff };
|
||||||
unsigned text_color_{0xffffffff};
|
unsigned text_color_{0xffffffff};
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Platform Specification Implementation
|
* Platform Specification Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* 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.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -31,18 +31,6 @@ namespace detail
|
|||||||
{
|
{
|
||||||
drawable_impl_type::drawable_impl_type()
|
drawable_impl_type::drawable_impl_type()
|
||||||
{
|
{
|
||||||
pen.handle = nullptr;
|
|
||||||
pen.color = 0xffffffff;
|
|
||||||
pen.style = -1;
|
|
||||||
pen.width = -1;
|
|
||||||
|
|
||||||
brush.handle = nullptr;
|
|
||||||
brush.style = brush_spec::Solid;
|
|
||||||
brush.color = 0xffffffff;
|
|
||||||
|
|
||||||
round_region.handle = nullptr;
|
|
||||||
round_region.radius_x = round_region.radius_y = 0;
|
|
||||||
|
|
||||||
string.tab_length = 4;
|
string.tab_length = 4;
|
||||||
string.tab_pixels = 0;
|
string.tab_pixels = 0;
|
||||||
string.whitespace_pixels = 0;
|
string.whitespace_pixels = 0;
|
||||||
@ -52,9 +40,6 @@ namespace detail
|
|||||||
{
|
{
|
||||||
::DeleteDC(context);
|
::DeleteDC(context);
|
||||||
::DeleteObject(pixmap);
|
::DeleteObject(pixmap);
|
||||||
::DeleteObject(pen.handle);
|
|
||||||
::DeleteObject(brush.handle);
|
|
||||||
::DeleteObject(round_region.handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned drawable_impl_type::get_color() const
|
unsigned drawable_impl_type::get_color() const
|
||||||
@ -82,68 +67,6 @@ namespace detail
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawable_impl_type::update_pen()
|
|
||||||
{
|
|
||||||
if (pen.color != color_)
|
|
||||||
{
|
|
||||||
pen.handle = ::CreatePen(PS_SOLID, 1, NANA_RGB(color_));
|
|
||||||
::DeleteObject(::SelectObject(context, pen.handle));
|
|
||||||
pen.color = color_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawable_impl_type::update_brush()
|
|
||||||
{
|
|
||||||
if (brush.color != color_)
|
|
||||||
brush.set(context, brush.style, color_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawable_impl_type::pen_spec::set(HDC context, int style, int width, unsigned clr)
|
|
||||||
{
|
|
||||||
if (this->color != clr || this->width != width || this->style != style)
|
|
||||||
{
|
|
||||||
this->color = clr;
|
|
||||||
this->width = width;
|
|
||||||
this->style = style;
|
|
||||||
this->handle = ::CreatePen(style, width, NANA_RGB(clr));
|
|
||||||
::DeleteObject(::SelectObject(context, this->handle));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawable_impl_type::brush_spec::set(HDC context, drawable_impl_type::brush_spec::t style, unsigned rgb)
|
|
||||||
{
|
|
||||||
if (this->color != rgb || this->style != style)
|
|
||||||
{
|
|
||||||
this->color = rgb;
|
|
||||||
this->style = style;
|
|
||||||
switch(style)
|
|
||||||
{
|
|
||||||
case brush_spec::HatchBDiagonal:
|
|
||||||
this->handle = ::CreateHatchBrush(HS_BDIAGONAL, NANA_RGB(rgb));
|
|
||||||
break;
|
|
||||||
case brush_spec::Solid:
|
|
||||||
default:
|
|
||||||
this->style = brush_spec::Solid;
|
|
||||||
this->handle = ::CreateSolidBrush(NANA_RGB(color));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
::DeleteObject(::SelectObject(context, this->handle));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawable_impl_type::round_region_spec::set(const nana::rectangle& r, unsigned radius_x, unsigned radius_y)
|
|
||||||
{
|
|
||||||
if(this->r != r || this->radius_x != radius_x || this->radius_y != radius_y)
|
|
||||||
{
|
|
||||||
if(handle)
|
|
||||||
::DeleteObject(this->handle);
|
|
||||||
this->r = r;
|
|
||||||
this->radius_x = radius_x;
|
|
||||||
this->radius_y = radius_y;
|
|
||||||
handle = ::CreateRoundRectRgn(r.x, r.y, r.x + static_cast<int>(r.width) + 1, r.y + static_cast<int>(r.height) + 1, static_cast<int>(radius_x + 1), static_cast<int>(radius_y + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//class platform_spec
|
//class platform_spec
|
||||||
platform_spec::co_initializer::co_initializer()
|
platform_spec::co_initializer::co_initializer()
|
||||||
: ole32_(::LoadLibrary(L"OLE32.DLL"))
|
: ole32_(::LoadLibrary(L"OLE32.DLL"))
|
||||||
|
|||||||
@ -379,11 +379,13 @@ namespace nana
|
|||||||
return pi_data_->scheme;
|
return pi_data_->scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bedrock::_m_emit_core(event_code evt_code, core_window_t* wd, bool draw_only, const ::nana::event_arg& event_arg)
|
void bedrock::_m_emit_core(event_code evt_code, core_window_t* wd, bool draw_only, const ::nana::event_arg& event_arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
auto retain = wd->annex.events_ptr;
|
auto retain = wd->annex.events_ptr;
|
||||||
auto evts_ptr = retain.get();
|
auto evts_ptr = retain.get();
|
||||||
|
|
||||||
|
// if 'bForce__EmitInternal', omit user defined events
|
||||||
|
const bool bProcess__External_event = !draw_only && !bForce__EmitInternal;
|
||||||
switch (evt_code)
|
switch (evt_code)
|
||||||
{
|
{
|
||||||
case event_code::click:
|
case event_code::click:
|
||||||
@ -394,9 +396,9 @@ namespace nana
|
|||||||
{
|
{
|
||||||
//enable refreshing flag, this is a RAII class for exception-safe
|
//enable refreshing flag, this is a RAII class for exception-safe
|
||||||
flag_guard fguard(this, wd);
|
flag_guard fguard(this, wd);
|
||||||
wd->drawer.click(*arg);
|
wd->drawer.click(*arg, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
if (!draw_only)
|
if (bProcess__External_event)
|
||||||
evts_ptr->click.emit(*arg, reinterpret_cast<window>(wd));
|
evts_ptr->click.emit(*arg, reinterpret_cast<window>(wd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,7 +414,7 @@ namespace nana
|
|||||||
if (nullptr == arg)
|
if (nullptr == arg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
void(::nana::detail::drawer::*drawer_event_fn)(const arg_mouse&);
|
void(::nana::detail::drawer::*drawer_event_fn)(const arg_mouse&, const bool);
|
||||||
::nana::basic_event<arg_mouse>* evt_addr;
|
::nana::basic_event<arg_mouse>* evt_addr;
|
||||||
|
|
||||||
switch (evt_code)
|
switch (evt_code)
|
||||||
@ -448,10 +450,10 @@ namespace nana
|
|||||||
{
|
{
|
||||||
//enable refreshing flag, this is a RAII class for exception-safe
|
//enable refreshing flag, this is a RAII class for exception-safe
|
||||||
flag_guard fguard(this, wd);
|
flag_guard fguard(this, wd);
|
||||||
(wd->drawer.*drawer_event_fn)(*arg);
|
(wd->drawer.*drawer_event_fn)(*arg, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!draw_only)
|
if (bProcess__External_event)
|
||||||
evt_addr->emit(*arg, reinterpret_cast<window>(wd));
|
evt_addr->emit(*arg, reinterpret_cast<window>(wd));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -463,10 +465,10 @@ namespace nana
|
|||||||
{
|
{
|
||||||
//enable refreshing flag, this is a RAII class for exception-safe
|
//enable refreshing flag, this is a RAII class for exception-safe
|
||||||
flag_guard fguard(this, wd);
|
flag_guard fguard(this, wd);
|
||||||
wd->drawer.mouse_wheel(*arg);
|
wd->drawer.mouse_wheel(*arg, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!draw_only)
|
if (bProcess__External_event)
|
||||||
evts_ptr->mouse_wheel.emit(*arg, reinterpret_cast<window>(wd));
|
evts_ptr->mouse_wheel.emit(*arg, reinterpret_cast<window>(wd));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -480,7 +482,7 @@ namespace nana
|
|||||||
if (nullptr == arg)
|
if (nullptr == arg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
void(::nana::detail::drawer::*drawer_event_fn)(const arg_keyboard&);
|
void(::nana::detail::drawer::*drawer_event_fn)(const arg_keyboard&, const bool);
|
||||||
::nana::basic_event<arg_keyboard>* evt_addr;
|
::nana::basic_event<arg_keyboard>* evt_addr;
|
||||||
|
|
||||||
switch (evt_code)
|
switch (evt_code)
|
||||||
@ -507,15 +509,15 @@ namespace nana
|
|||||||
{
|
{
|
||||||
//enable refreshing flag, this is a RAII class for exception-safe
|
//enable refreshing flag, this is a RAII class for exception-safe
|
||||||
flag_guard fguard(this, wd);
|
flag_guard fguard(this, wd);
|
||||||
(wd->drawer.*drawer_event_fn)(*arg);
|
(wd->drawer.*drawer_event_fn)(*arg, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!draw_only)
|
if (bProcess__External_event)
|
||||||
evt_addr->emit(*arg, reinterpret_cast<window>(wd));
|
evt_addr->emit(*arg, reinterpret_cast<window>(wd));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case event_code::expose:
|
case event_code::expose:
|
||||||
if (!draw_only)
|
if (bProcess__External_event)
|
||||||
{
|
{
|
||||||
auto arg = dynamic_cast<const arg_expose*>(&event_arg);
|
auto arg = dynamic_cast<const arg_expose*>(&event_arg);
|
||||||
if (arg)
|
if (arg)
|
||||||
@ -530,9 +532,9 @@ namespace nana
|
|||||||
{
|
{
|
||||||
//enable refreshing flag, this is a RAII class for exception-safe
|
//enable refreshing flag, this is a RAII class for exception-safe
|
||||||
flag_guard fguard(this, wd);
|
flag_guard fguard(this, wd);
|
||||||
wd->drawer.focus(*arg);
|
wd->drawer.focus(*arg, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
if (!draw_only)
|
if (bProcess__External_event)
|
||||||
evts_ptr->focus.emit(*arg, reinterpret_cast<window>(wd));
|
evts_ptr->focus.emit(*arg, reinterpret_cast<window>(wd));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -545,9 +547,9 @@ namespace nana
|
|||||||
{
|
{
|
||||||
//enable refreshing flag, this is a RAII class for exception-safe
|
//enable refreshing flag, this is a RAII class for exception-safe
|
||||||
flag_guard fguard(this, wd);
|
flag_guard fguard(this, wd);
|
||||||
wd->drawer.move(*arg);
|
wd->drawer.move(*arg, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
if (!draw_only)
|
if (bProcess__External_event)
|
||||||
evts_ptr->move.emit(*arg, reinterpret_cast<window>(wd));
|
evts_ptr->move.emit(*arg, reinterpret_cast<window>(wd));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -560,9 +562,9 @@ namespace nana
|
|||||||
{
|
{
|
||||||
//enable refreshing flag, this is a RAII class for exception-safe
|
//enable refreshing flag, this is a RAII class for exception-safe
|
||||||
flag_guard fguard(this, wd);
|
flag_guard fguard(this, wd);
|
||||||
wd->drawer.resizing(*arg);
|
wd->drawer.resizing(*arg, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
if (!draw_only)
|
if (bProcess__External_event)
|
||||||
evts_ptr->resizing.emit(*arg, reinterpret_cast<window>(wd));
|
evts_ptr->resizing.emit(*arg, reinterpret_cast<window>(wd));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -575,15 +577,15 @@ namespace nana
|
|||||||
{
|
{
|
||||||
//enable refreshing flag, this is a RAII class for exception-safe
|
//enable refreshing flag, this is a RAII class for exception-safe
|
||||||
flag_guard fguard(this, wd);
|
flag_guard fguard(this, wd);
|
||||||
wd->drawer.resized(*arg);
|
wd->drawer.resized(*arg, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
if (!draw_only)
|
if (bProcess__External_event)
|
||||||
evts_ptr->resized.emit(*arg, reinterpret_cast<window>(wd));
|
evts_ptr->resized.emit(*arg, reinterpret_cast<window>(wd));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case event_code::unload:
|
case event_code::unload:
|
||||||
if (!draw_only)
|
if (bProcess__External_event)
|
||||||
{
|
{
|
||||||
auto arg = dynamic_cast<const arg_unload*>(&event_arg);
|
auto arg = dynamic_cast<const arg_unload*>(&event_arg);
|
||||||
if (arg && (wd->other.category == category::flags::root))
|
if (arg && (wd->other.category == category::flags::root))
|
||||||
@ -595,7 +597,7 @@ namespace nana
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case event_code::destroy:
|
case event_code::destroy:
|
||||||
if (!draw_only)
|
if (bProcess__External_event)
|
||||||
{
|
{
|
||||||
auto arg = dynamic_cast<const arg_destroy*>(&event_arg);
|
auto arg = dynamic_cast<const arg_destroy*>(&event_arg);
|
||||||
if (arg)
|
if (arg)
|
||||||
|
|||||||
@ -232,7 +232,7 @@ namespace detail
|
|||||||
//No implementation for Linux
|
//No implementation for Linux
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bedrock::emit(event_code evt_code, core_window_t* wd, const ::nana::event_arg& arg, bool ask_update, thread_context* thrd)
|
bool bedrock::emit(event_code evt_code, core_window_t* wd, const ::nana::event_arg& arg, bool ask_update, thread_context* thrd, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
if(wd_manager().available(wd) == false)
|
if(wd_manager().available(wd) == false)
|
||||||
return false;
|
return false;
|
||||||
@ -248,7 +248,7 @@ namespace detail
|
|||||||
if(wd->other.upd_state == core_window_t::update_state::none)
|
if(wd->other.upd_state == core_window_t::update_state::none)
|
||||||
wd->other.upd_state = core_window_t::update_state::lazy;
|
wd->other.upd_state = core_window_t::update_state::lazy;
|
||||||
|
|
||||||
_m_emit_core(evt_code, wd, false, arg);
|
_m_emit_core(evt_code, wd, false, arg, bForce__EmitInternal);
|
||||||
|
|
||||||
//A child of wd may not be drawn if it was out of wd's range before wd resized,
|
//A child of wd may not be drawn if it was out of wd's range before wd resized,
|
||||||
//so refresh all children of wd when a resized occurs.
|
//so refresh all children of wd when a resized occurs.
|
||||||
@ -396,7 +396,7 @@ namespace detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Arg>
|
template<typename Arg>
|
||||||
void draw_invoker(void(::nana::detail::drawer::*event_ptr)(const Arg&), basic_window* wd, const Arg& arg, bedrock::thread_context* thrd)
|
void draw_invoker(void(::nana::detail::drawer::*event_ptr)(const Arg&, const bool), basic_window* wd, const Arg& arg, bedrock::thread_context* thrd)
|
||||||
{
|
{
|
||||||
if(bedrock::instance().wd_manager().available(wd) == false)
|
if(bedrock::instance().wd_manager().available(wd) == false)
|
||||||
return;
|
return;
|
||||||
@ -410,7 +410,7 @@ namespace detail
|
|||||||
if(wd->other.upd_state == basic_window::update_state::none)
|
if(wd->other.upd_state == basic_window::update_state::none)
|
||||||
wd->other.upd_state = basic_window::update_state::lazy;
|
wd->other.upd_state = basic_window::update_state::lazy;
|
||||||
|
|
||||||
(wd->drawer.*event_ptr)(arg);
|
(wd->drawer.*event_ptr)(arg, false);
|
||||||
if(thrd) thrd->event_window = pre_wd;
|
if(thrd) thrd->event_window = pre_wd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -755,7 +755,7 @@ namespace detail
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Arg>
|
template<typename Arg>
|
||||||
void draw_invoker(void (::nana::detail::drawer::*event_ptr)(const Arg&), basic_window* wd, const Arg& arg, bedrock::thread_context* thrd)
|
void draw_invoker(void (::nana::detail::drawer::*event_ptr)(const Arg&, const bool), basic_window* wd, const Arg& arg, bedrock::thread_context* thrd)
|
||||||
{
|
{
|
||||||
if (bedrock::instance().wd_manager().available(wd) == false)
|
if (bedrock::instance().wd_manager().available(wd) == false)
|
||||||
return;
|
return;
|
||||||
@ -770,7 +770,7 @@ namespace detail
|
|||||||
if (wd->other.upd_state == basic_window::update_state::none)
|
if (wd->other.upd_state == basic_window::update_state::none)
|
||||||
wd->other.upd_state = basic_window::update_state::lazy;
|
wd->other.upd_state = basic_window::update_state::lazy;
|
||||||
|
|
||||||
(wd->drawer.*event_ptr)(arg);
|
(wd->drawer.*event_ptr)(arg, false);
|
||||||
|
|
||||||
if (thrd) thrd->event_window = prev_event_wd;
|
if (thrd) thrd->event_window = prev_event_wd;
|
||||||
}
|
}
|
||||||
@ -1626,7 +1626,7 @@ namespace detail
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bedrock::emit(event_code evt_code, core_window_t* wd, const ::nana::event_arg& arg, bool ask_update, thread_context* thrd)
|
bool bedrock::emit(event_code evt_code, core_window_t* wd, const ::nana::event_arg& arg, bool ask_update, thread_context* thrd, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
if (wd_manager().available(wd) == false)
|
if (wd_manager().available(wd) == false)
|
||||||
return false;
|
return false;
|
||||||
@ -1642,7 +1642,7 @@ namespace detail
|
|||||||
if (wd->other.upd_state == core_window_t::update_state::none)
|
if (wd->other.upd_state == core_window_t::update_state::none)
|
||||||
wd->other.upd_state = core_window_t::update_state::lazy;
|
wd->other.upd_state = core_window_t::update_state::lazy;
|
||||||
|
|
||||||
_m_emit_core(evt_code, wd, false, arg);
|
_m_emit_core(evt_code, wd, false, arg, bForce__EmitInternal);
|
||||||
|
|
||||||
bool good_wd = false;
|
bool good_wd = false;
|
||||||
if (wd_manager().available(wd))
|
if (wd_manager().available(wd))
|
||||||
|
|||||||
@ -128,8 +128,88 @@ namespace nana
|
|||||||
return 0 != (overrided_ & (1 << static_cast<int>(evt_code)));
|
return 0 != (overrided_ & (1 << static_cast<int>(evt_code)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawer_trigger::filter_event(const event_code evt_code, const bool bDisabled)
|
||||||
|
{
|
||||||
|
if (bDisabled)
|
||||||
|
evt_disabled_ |= 1 << static_cast<int>(evt_code); // set
|
||||||
|
else
|
||||||
|
evt_disabled_ &= ~(1 << static_cast<int>(evt_code)); // clear
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawer_trigger::filter_event(const std::vector<event_code> evt_codes, const bool bDisabled)
|
||||||
|
{
|
||||||
|
const auto it_end = evt_codes.end();
|
||||||
|
for (auto it = evt_codes.begin(); it != it_end; it++)
|
||||||
|
filter_event(*it, bDisabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawer_trigger::filter_event(const event_filter_status& evt_all_states)
|
||||||
|
{
|
||||||
|
evt_disabled_ = evt_all_states.evt_disabled_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool drawer_trigger::filter_event(const event_code evt_code)
|
||||||
|
{
|
||||||
|
return static_cast<bool>((evt_disabled_ >> static_cast<int>(evt_code)) & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
event_filter_status drawer_trigger::filter_event()
|
||||||
|
{
|
||||||
|
return event_filter_status(evt_disabled_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawer_trigger::clear_filter()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < static_cast<int>(nana::event_code::end); i++)
|
||||||
|
filter_event(static_cast<nana::event_code>(i), false);
|
||||||
|
}
|
||||||
|
|
||||||
//end class drawer_trigger
|
//end class drawer_trigger
|
||||||
|
|
||||||
|
//class event_filter_status
|
||||||
|
event_filter_status::event_filter_status()
|
||||||
|
{
|
||||||
|
evt_disabled_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_filter_status::event_filter_status(const event_filter_status& rOther)
|
||||||
|
{
|
||||||
|
this->evt_disabled_ = rOther.evt_disabled_;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_filter_status::event_filter_status(const unsigned evt_disabled_)
|
||||||
|
{
|
||||||
|
this->evt_disabled_ = evt_disabled_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool event_filter_status::operator[](const nana::event_code evt_code) const
|
||||||
|
{
|
||||||
|
return static_cast<bool>((evt_disabled_ >> static_cast<int>(evt_code)) & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool event_filter_status::operator==(const event_filter_status& rOther) const
|
||||||
|
{
|
||||||
|
return evt_disabled_ == rOther.evt_disabled_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool event_filter_status::operator!=(const event_filter_status& rOther) const
|
||||||
|
{
|
||||||
|
return evt_disabled_ != rOther.evt_disabled_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const event_filter_status& event_filter_status::operator=(const event_filter_status& rOther)
|
||||||
|
{
|
||||||
|
evt_disabled_ = rOther.evt_disabled_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const event_filter_status& event_filter_status::operator=(const unsigned evt_disabled_)
|
||||||
|
{
|
||||||
|
this->evt_disabled_ = evt_disabled_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
//end of class event_filter_status
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
typedef bedrock bedrock_type;
|
typedef bedrock bedrock_type;
|
||||||
@ -174,89 +254,89 @@ namespace nana
|
|||||||
data_impl_->realizer->typeface_changed(graphics);
|
data_impl_->realizer->typeface_changed(graphics);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::click(const arg_click& arg)
|
void drawer::click(const arg_click& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::click, arg, &drawer_trigger::click);
|
_m_emit(event_code::click, arg, &drawer_trigger::click, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::dbl_click(const arg_mouse& arg)
|
void drawer::dbl_click(const arg_mouse& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::dbl_click, arg, &drawer_trigger::dbl_click);
|
_m_emit(event_code::dbl_click, arg, &drawer_trigger::dbl_click, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::mouse_enter(const arg_mouse& arg)
|
void drawer::mouse_enter(const arg_mouse& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::mouse_enter, arg, &drawer_trigger::mouse_enter);
|
_m_emit(event_code::mouse_enter, arg, &drawer_trigger::mouse_enter, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::mouse_move(const arg_mouse& arg)
|
void drawer::mouse_move(const arg_mouse& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::mouse_move, arg, &drawer_trigger::mouse_move);
|
_m_emit(event_code::mouse_move, arg, &drawer_trigger::mouse_move, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::mouse_leave(const arg_mouse& arg)
|
void drawer::mouse_leave(const arg_mouse& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::mouse_leave, arg, &drawer_trigger::mouse_leave);
|
_m_emit(event_code::mouse_leave, arg, &drawer_trigger::mouse_leave, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::mouse_down(const arg_mouse& arg)
|
void drawer::mouse_down(const arg_mouse& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::mouse_down, arg, &drawer_trigger::mouse_down);
|
_m_emit(event_code::mouse_down, arg, &drawer_trigger::mouse_down, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::mouse_up(const arg_mouse& arg)
|
void drawer::mouse_up(const arg_mouse& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::mouse_up, arg, &drawer_trigger::mouse_up);
|
_m_emit(event_code::mouse_up, arg, &drawer_trigger::mouse_up, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::mouse_wheel(const arg_wheel& arg)
|
void drawer::mouse_wheel(const arg_wheel& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::mouse_wheel, arg, &drawer_trigger::mouse_wheel);
|
_m_emit(event_code::mouse_wheel, arg, &drawer_trigger::mouse_wheel, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::mouse_dropfiles(const arg_dropfiles& arg)
|
void drawer::mouse_dropfiles(const arg_dropfiles& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::mouse_drop, arg, &drawer_trigger::mouse_dropfiles);
|
_m_emit(event_code::mouse_drop, arg, &drawer_trigger::mouse_dropfiles, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::resizing(const arg_resizing& arg)
|
void drawer::resizing(const arg_resizing& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::resizing, arg, &drawer_trigger::resizing);
|
_m_emit(event_code::resizing, arg, &drawer_trigger::resizing, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::resized(const arg_resized& arg)
|
void drawer::resized(const arg_resized& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::resized, arg, &drawer_trigger::resized);
|
_m_emit(event_code::resized, arg, &drawer_trigger::resized, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::move(const arg_move& arg)
|
void drawer::move(const arg_move& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::move, arg, &drawer_trigger::move);
|
_m_emit(event_code::move, arg, &drawer_trigger::move, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::focus(const arg_focus& arg)
|
void drawer::focus(const arg_focus& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::focus, arg, &drawer_trigger::focus);
|
_m_emit(event_code::focus, arg, &drawer_trigger::focus, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::key_press(const arg_keyboard& arg)
|
void drawer::key_press(const arg_keyboard& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::key_press, arg, &drawer_trigger::key_press);
|
_m_emit(event_code::key_press, arg, &drawer_trigger::key_press, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::key_char(const arg_keyboard& arg)
|
void drawer::key_char(const arg_keyboard& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::key_char, arg, &drawer_trigger::key_char);
|
_m_emit(event_code::key_char, arg, &drawer_trigger::key_char, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::key_release(const arg_keyboard& arg)
|
void drawer::key_release(const arg_keyboard& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::key_release, arg, &drawer_trigger::key_release);
|
_m_emit(event_code::key_release, arg, &drawer_trigger::key_release, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::shortkey(const arg_keyboard& arg)
|
void drawer::shortkey(const arg_keyboard& arg, const bool bForce__EmitInternal)
|
||||||
{
|
{
|
||||||
_m_emit(event_code::shortkey, arg, &drawer_trigger::shortkey);
|
_m_emit(event_code::shortkey, arg, &drawer_trigger::shortkey, bForce__EmitInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::map(window wd, bool forced, const rectangle* update_area) //Copy the root buffer to screen
|
void drawer::map(window wd, bool forced, const rectangle* update_area) //Copy the root buffer to screen
|
||||||
|
|||||||
@ -114,8 +114,30 @@ namespace nana
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto* parent = wd->parent; parent; parent = parent->parent)
|
for (auto parent = wd->parent; parent; parent = parent->parent)
|
||||||
{
|
{
|
||||||
|
if (category::flags::root == parent->other.category)
|
||||||
|
{
|
||||||
|
//visual rectangle of wd's parent
|
||||||
|
rectangle vrt_parent{parent->pos_root, parent->dimension};
|
||||||
|
|
||||||
|
point pos_root;
|
||||||
|
while (parent->parent)
|
||||||
|
{
|
||||||
|
pos_root -= native_interface::window_position(parent->root);
|
||||||
|
|
||||||
|
if (!overlap(rectangle{ pos_root, parent->parent->root_widget->dimension }, vrt_parent, vrt_parent))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
parent = parent->parent->root_widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!overlap(vrt_parent, visual, visual))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!overlap(rectangle{ parent->pos_root, parent->dimension }, visual, visual))
|
if (!overlap(rectangle{ parent->pos_root, parent->dimension }, visual, visual))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -733,30 +733,6 @@ namespace detail
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sync_child_root_display(window_manager::core_window_t* wd)
|
|
||||||
{
|
|
||||||
for (auto & child : wd->children)
|
|
||||||
{
|
|
||||||
if (category::flags::root != child->other.category)
|
|
||||||
{
|
|
||||||
sync_child_root_display(child);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto const vs_parents = child->visible_parents();
|
|
||||||
|
|
||||||
if (vs_parents != child->visible)
|
|
||||||
{
|
|
||||||
native_interface::show_window(child->root, vs_parents, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (child->visible != native_interface::is_window_visible(child->root))
|
|
||||||
native_interface::show_window(child->root, child->visible, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//show
|
//show
|
||||||
//@brief: show or hide a window
|
//@brief: show or hide a window
|
||||||
bool window_manager::show(core_window_t* wd, bool visible)
|
bool window_manager::show(core_window_t* wd, bool visible)
|
||||||
@ -792,15 +768,8 @@ namespace detail
|
|||||||
bedrock::instance().event_expose(wd, visible);
|
bedrock::instance().event_expose(wd, visible);
|
||||||
|
|
||||||
if (nv)
|
if (nv)
|
||||||
{
|
|
||||||
if (visible && !wd->visible_parents())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
native_interface::show_window(nv, visible, wd->flags.take_active);
|
native_interface::show_window(nv, visible, wd->flags.take_active);
|
||||||
}
|
}
|
||||||
|
|
||||||
sync_child_root_display(wd);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1851,6 +1820,9 @@ namespace detail
|
|||||||
|
|
||||||
if(wd->other.category != category::flags::root) //Not a root window
|
if(wd->other.category != category::flags::root) //Not a root window
|
||||||
impl_->wd_register.remove(wd);
|
impl_->wd_register.remove(wd);
|
||||||
|
|
||||||
|
//Release graphics immediately.
|
||||||
|
wd->drawer.graphics.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_manager::_m_move_core(core_window_t* wd, const point& delta)
|
void window_manager::_m_move_core(core_window_t* wd, const point& delta)
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
* http://www.boost.org/LICENSE_1_0.txt)
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
*
|
*
|
||||||
* @file: nana/gui/msgbox.hpp
|
* @file: nana/gui/msgbox.hpp
|
||||||
|
* @Contributors
|
||||||
|
* James Bremner
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nana/gui.hpp>
|
#include <nana/gui.hpp>
|
||||||
@ -1258,7 +1260,8 @@ namespace nana
|
|||||||
inputbox::inputbox(window owner, ::std::string desc, ::std::string title)
|
inputbox::inputbox(window owner, ::std::string desc, ::std::string title)
|
||||||
: owner_{ owner },
|
: owner_{ owner },
|
||||||
description_(std::move(desc)),
|
description_(std::move(desc)),
|
||||||
title_(std::move(title))
|
title_(std::move(title)),
|
||||||
|
min_width_entry_field_pixels_( 100 )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void inputbox::image(::nana::paint::image img, bool is_left, const rectangle& valid_area)
|
void inputbox::image(::nana::paint::image img, bool is_left, const rectangle& valid_area)
|
||||||
@ -1280,6 +1283,17 @@ namespace nana
|
|||||||
verifier_ = std::move(verifier);
|
verifier_ = std::move(verifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Inputbox set minimum width entry field(https://github.com/cnjinhao/nana/pull/234)
|
||||||
|
//Contributed by James Bremner
|
||||||
|
void inputbox::min_width_entry_field( unsigned pixels )
|
||||||
|
{
|
||||||
|
// don't let the entry fields vanish entirely
|
||||||
|
if( pixels < 10 )
|
||||||
|
pixels = 10;
|
||||||
|
|
||||||
|
min_width_entry_field_pixels_ = pixels;
|
||||||
|
}
|
||||||
|
|
||||||
void inputbox::_m_fetch_args(std::vector<abstract_content*>&)
|
void inputbox::_m_fetch_args(std::vector<abstract_content*>&)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -1304,9 +1318,9 @@ namespace nana
|
|||||||
each_pixels.push_back(px.height);
|
each_pixels.push_back(px.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Adjust the fixed_px for good looking
|
//Ensure that the entry fields are at least as wide as the minimum
|
||||||
if (has_0_fixed_px && (fixed_px < 100))
|
if (has_0_fixed_px && (fixed_px < min_width_entry_field_pixels_ ))
|
||||||
fixed_px = 100;
|
fixed_px = min_width_entry_field_pixels_;
|
||||||
|
|
||||||
inputbox_window input_wd(owner_, images_, valid_areas_, description_, title_, contents.size(), label_px + 10 + fixed_px, each_pixels);
|
inputbox_window input_wd(owner_, images_, valid_areas_, description_, title_, contents.size(), label_px + 10 + fixed_px, each_pixels);
|
||||||
|
|
||||||
|
|||||||
@ -3058,7 +3058,7 @@ namespace nana
|
|||||||
throw std::runtime_error("place.bind: it has already bound to a window.");
|
throw std::runtime_error("place.bind: it has already bound to a window.");
|
||||||
|
|
||||||
impl_->window_handle = wd;
|
impl_->window_handle = wd;
|
||||||
impl_->event_size_handle = API::events(wd).resized.connect([this](const arg_resized& arg)
|
impl_->event_size_handle = API::events(wd).resized.connect_unignorable([this](const arg_resized& arg)
|
||||||
{
|
{
|
||||||
if (impl_->root_division)
|
if (impl_->root_division)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -260,7 +260,7 @@ namespace nana
|
|||||||
notifier_->request_close();
|
notifier_->request_close();
|
||||||
});
|
});
|
||||||
|
|
||||||
this->events().resized.connect([this](const arg_resized& arg)
|
this->events().resized.connect_unignorable([this](const arg_resized& arg)
|
||||||
{
|
{
|
||||||
rectangle r{ 0, 0, arg.width, 20 };
|
rectangle r{ 0, 0, arg.width, 20 };
|
||||||
caption_.move(r);
|
caption_.move(r);
|
||||||
@ -360,7 +360,7 @@ namespace nana
|
|||||||
API::set_parent_window(handle(), container_->handle());
|
API::set_parent_window(handle(), container_->handle());
|
||||||
this->move({ 1, 1 });
|
this->move({ 1, 1 });
|
||||||
|
|
||||||
container_->events().resized.connect([this](const arg_resized& arg)
|
container_->events().resized.connect_unignorable([this](const arg_resized& arg)
|
||||||
{
|
{
|
||||||
this->size({arg.width - 2, arg.height - 2});
|
this->size({arg.width - 2, arg.height - 2});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -62,7 +62,12 @@ namespace API
|
|||||||
|
|
||||||
bool emit_event(event_code evt_code, window wd, const ::nana::event_arg& arg)
|
bool emit_event(event_code evt_code, window wd, const ::nana::event_arg& arg)
|
||||||
{
|
{
|
||||||
return restrict::bedrock.emit(evt_code, reinterpret_cast<::nana::detail::basic_window*>(wd), arg, true, restrict::bedrock.get_thread_context());
|
return restrict::bedrock.emit(evt_code, reinterpret_cast<::nana::detail::basic_window*>(wd), arg, true, restrict::bedrock.get_thread_context(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool emit_internal_event(event_code evt_code, window wd, const ::nana::event_arg& arg)
|
||||||
|
{
|
||||||
|
return restrict::bedrock.emit(evt_code, reinterpret_cast<::nana::detail::basic_window*>(wd), arg, true, restrict::bedrock.get_thread_context(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enum_widgets_function_base::enum_widgets(window wd, bool recursive)
|
void enum_widgets_function_base::enum_widgets(window wd, bool recursive)
|
||||||
@ -365,6 +370,24 @@ namespace API
|
|||||||
{
|
{
|
||||||
restrict::bedrock.thread_context_lazy_refresh();
|
restrict::bedrock.thread_context_lazy_refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void draw_shortkey_underline(paint::graphics& graph, const std::string& text, wchar_t shortkey, std::size_t shortkey_position, const point& text_pos, const color& line_color)
|
||||||
|
{
|
||||||
|
if (shortkey)
|
||||||
|
{
|
||||||
|
auto off_x = (shortkey_position ? graph.text_extent_size(text.c_str(), shortkey_position).width : 0);
|
||||||
|
auto key_px = static_cast<int>(graph.text_extent_size(&shortkey, 1).width);
|
||||||
|
|
||||||
|
unsigned ascent, descent, inleading;
|
||||||
|
graph.text_metrics(ascent, descent, inleading);
|
||||||
|
|
||||||
|
int x = text_pos.x + static_cast<int>(off_x);
|
||||||
|
int y = text_pos.y + static_cast<int>(ascent + 2);
|
||||||
|
|
||||||
|
graph.line({ x, y }, {x + key_px - 1, y}, line_color);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}//end namespace dev
|
}//end namespace dev
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -34,12 +34,7 @@ namespace nana{ namespace drawerbase
|
|||||||
return{};
|
return{};
|
||||||
|
|
||||||
wchar_t shortkey;
|
wchar_t shortkey;
|
||||||
std::string::size_type shortkey_pos;
|
return graph.text_extent_size(API::transform_shortkey_text(trigger_->wdg_->caption(), shortkey, nullptr));
|
||||||
|
|
||||||
auto str = to_wstring(API::transform_shortkey_text(trigger_->wdg_->caption(), shortkey, &shortkey_pos));
|
|
||||||
auto text_sz = graph.text_extent_size(str);
|
|
||||||
|
|
||||||
return size{ text_sz.width, text_sz.height };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size extension() const override
|
size extension() const override
|
||||||
@ -261,28 +256,15 @@ namespace nana{ namespace drawerbase
|
|||||||
++pos.y;
|
++pos.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
graph.palette(true, attr_.focus_color && attr_.focused ? ::nana::color(colors::blue) : attr_.fgcolor);
|
auto text_color = (attr_.focus_color && attr_.focused ? ::nana::color(colors::blue) : attr_.fgcolor);
|
||||||
|
graph.palette(true, text_color);
|
||||||
|
|
||||||
if (attr_.omitted)
|
if (attr_.omitted)
|
||||||
tr.render(pos, txtptr, txtlen, omitted_pixels, true);
|
tr.render(pos, txtptr, txtlen, omitted_pixels, true);
|
||||||
else
|
else
|
||||||
graph.bidi_string(pos, txtptr, txtlen);
|
graph.bidi_string(pos, txtptr, txtlen);
|
||||||
|
|
||||||
if(shortkey)
|
API::dev::draw_shortkey_underline(graph, mbstr, shortkey, shortkey_pos, pos, text_color);
|
||||||
{
|
|
||||||
unsigned off_w = (shortkey_pos ? graph.text_extent_size(mbstr.c_str(), shortkey_pos).width : 0);
|
|
||||||
|
|
||||||
wchar_t keystr[2] = {nana::utf::char_at(mbstr.c_str() + shortkey_pos, 0, 0), 0};
|
|
||||||
auto shortkey_size = graph.text_extent_size(keystr, 1);
|
|
||||||
|
|
||||||
unsigned ascent, descent, inleading;
|
|
||||||
graph.text_metrics(ascent, descent, inleading);
|
|
||||||
|
|
||||||
pos.x += off_w;
|
|
||||||
pos.y += static_cast<int>(ascent + 2);
|
|
||||||
|
|
||||||
graph.line(pos, point{ pos.x + static_cast<int>(shortkey_size.width) - 1, pos.y }, colors::black);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -143,6 +143,7 @@ namespace nana
|
|||||||
|
|
||||||
auto scheme = dynamic_cast< ::nana::widgets::skeletons::text_editor_scheme*>(API::dev::get_scheme(wd));
|
auto scheme = dynamic_cast< ::nana::widgets::skeletons::text_editor_scheme*>(API::dev::get_scheme(wd));
|
||||||
editor_ = new widgets::skeletons::text_editor(widget_->handle(), graph, scheme);
|
editor_ = new widgets::skeletons::text_editor(widget_->handle(), graph, scheme);
|
||||||
|
_m_text_area(graph.size());
|
||||||
editor_->multi_lines(false);
|
editor_->multi_lines(false);
|
||||||
editable(false);
|
editable(false);
|
||||||
graph_ = &graph;
|
graph_ = &graph;
|
||||||
@ -177,21 +178,6 @@ namespace nana
|
|||||||
return any_ptr.get();
|
return any_ptr.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void text_area(const nana::size& s)
|
|
||||||
{
|
|
||||||
auto extension = measurer_->extension();
|
|
||||||
|
|
||||||
nana::rectangle r(2, 2, s.width > extension.width ? s.width - extension.width : 0, s.height > extension.height ? s.height - extension.height : 0);
|
|
||||||
if(image_enabled_)
|
|
||||||
{
|
|
||||||
unsigned place = image_pixels_ + 2;
|
|
||||||
r.x += place;
|
|
||||||
if(r.width > place) r.width -= place;
|
|
||||||
}
|
|
||||||
editor_->text_area(r);
|
|
||||||
editor_->render(state_.focused);
|
|
||||||
}
|
|
||||||
|
|
||||||
widgets::skeletons::text_editor * editor() const
|
widgets::skeletons::text_editor * editor() const
|
||||||
{
|
{
|
||||||
return editor_;
|
return editor_;
|
||||||
@ -364,12 +350,13 @@ namespace nana
|
|||||||
void draw()
|
void draw()
|
||||||
{
|
{
|
||||||
bool enb = widget_->enabled();
|
bool enb = widget_->enabled();
|
||||||
if(editor_)
|
|
||||||
{
|
_m_text_area(widget_->size());
|
||||||
text_area(widget_->size());
|
editor_->render(state_.focused);
|
||||||
}
|
|
||||||
_m_draw_push_button(enb);
|
_m_draw_push_button(enb);
|
||||||
_m_draw_image();
|
_m_draw_image();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t the_number_of_options() const
|
std::size_t the_number_of_options() const
|
||||||
@ -496,6 +483,20 @@ namespace nana
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
void _m_text_area(const nana::size& s)
|
||||||
|
{
|
||||||
|
auto extension = measurer_->extension();
|
||||||
|
|
||||||
|
nana::rectangle r(2, 2, s.width > extension.width ? s.width - extension.width : 0, s.height > extension.height ? s.height - extension.height : 0);
|
||||||
|
if (image_enabled_)
|
||||||
|
{
|
||||||
|
unsigned place = image_pixels_ + 2;
|
||||||
|
r.x += place;
|
||||||
|
if (r.width > place) r.width -= place;
|
||||||
|
}
|
||||||
|
editor_->text_area(r);
|
||||||
|
}
|
||||||
|
|
||||||
void _m_draw_push_button(bool enabled)
|
void _m_draw_push_button(bool enabled)
|
||||||
{
|
{
|
||||||
::nana::rectangle r{graph_->size()};
|
::nana::rectangle r{graph_->size()};
|
||||||
|
|||||||
@ -433,8 +433,16 @@ namespace nana
|
|||||||
{
|
{
|
||||||
check_range(pos, cont_.size());
|
check_range(pos, cont_.size());
|
||||||
|
|
||||||
|
//The order of cont_'s elements is the display order.
|
||||||
if (!disp_order)
|
if (!disp_order)
|
||||||
pos = this->cast(pos, false);
|
{
|
||||||
|
/// It always match the item with pos, otherwise a bug occurs.
|
||||||
|
for (auto & m : cont_)
|
||||||
|
{
|
||||||
|
if (m.index == pos)
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return cont_[pos];
|
return cont_[pos];
|
||||||
}
|
}
|
||||||
@ -963,7 +971,7 @@ namespace nana
|
|||||||
return prstatus;
|
return prstatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll(const index_pair& pos, bool to_bottom);
|
void scroll(const index_pair& abs_pos, bool to_bottom);
|
||||||
|
|
||||||
/// Append a new category with a specified name and return a pointer to it.
|
/// Append a new category with a specified name and return a pointer to it.
|
||||||
category_t* create_cat(native_string_type&& text)
|
category_t* create_cat(native_string_type&& text)
|
||||||
@ -2840,16 +2848,16 @@ namespace nana
|
|||||||
std::vector<std::pair<index_type, inline_pane*>> panes_;
|
std::vector<std::pair<index_type, inline_pane*>> panes_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void es_lister::scroll(const index_pair& pos, bool to_bottom)
|
void es_lister::scroll(const index_pair& abs_pos, bool to_bottom)
|
||||||
{
|
{
|
||||||
auto& cat = *get(pos.cat);
|
auto& cat = *get(abs_pos.cat);
|
||||||
|
|
||||||
if ((pos.item != nana::npos) && (pos.item >= cat.items.size()))
|
if ((abs_pos.item != nana::npos) && (abs_pos.item >= cat.items.size()))
|
||||||
throw std::invalid_argument("listbox: invalid pos to scroll");
|
throw std::invalid_argument("listbox: invalid pos to scroll");
|
||||||
|
|
||||||
if (!cat.expand)
|
if (!cat.expand)
|
||||||
{
|
{
|
||||||
this->expand(pos.cat, true);
|
this->expand(abs_pos.cat, true);
|
||||||
ess_->calc_content_size();
|
ess_->calc_content_size();
|
||||||
}
|
}
|
||||||
else if (!ess_->auto_draw)
|
else if (!ess_->auto_draw)
|
||||||
@ -2862,7 +2870,7 @@ namespace nana
|
|||||||
auto origin = ess_->content_view->origin();
|
auto origin = ess_->content_view->origin();
|
||||||
origin.y = 0;
|
origin.y = 0;
|
||||||
|
|
||||||
auto off = this->distance(this->first(), pos) * ess_->item_height();
|
auto off = this->distance(this->first(), this->index_cast(abs_pos, false)) * ess_->item_height();
|
||||||
|
|
||||||
auto screen_px = ess_->content_view->view_area().height;
|
auto screen_px = ess_->content_view->view_area().height;
|
||||||
|
|
||||||
@ -3661,6 +3669,7 @@ namespace nana
|
|||||||
rectangle bground_r{ content_r.x + static_cast<int>(essence_->header.margin()), coord.y, show_w, essence_->item_height() };
|
rectangle bground_r{ content_r.x + static_cast<int>(essence_->header.margin()), coord.y, show_w, essence_->item_height() };
|
||||||
auto const state_bgcolor = this->_m_draw_item_bground(bground_r, bgcolor, {}, state, item);
|
auto const state_bgcolor = this->_m_draw_item_bground(bground_r, bgcolor, {}, state, item);
|
||||||
|
|
||||||
|
//The position of column in x-axis.
|
||||||
int column_x = coord.x;
|
int column_x = coord.x;
|
||||||
|
|
||||||
for (size_type display_order{ 0 }; display_order < seqs.size(); ++display_order) // get the cell (column) index in the order headers are displayed
|
for (size_type display_order{ 0 }; display_order < seqs.size(); ++display_order) // get the cell (column) index in the order headers are displayed
|
||||||
@ -3670,7 +3679,9 @@ namespace nana
|
|||||||
|
|
||||||
if (col.width_px > essence_->scheme_ptr->text_margin)
|
if (col.width_px > essence_->scheme_ptr->text_margin)
|
||||||
{
|
{
|
||||||
|
//The column text position, it is a offset to column_x.
|
||||||
int content_pos = 0;
|
int content_pos = 0;
|
||||||
|
|
||||||
element_state estate = element_state::normal;
|
element_state estate = element_state::normal;
|
||||||
nana::rectangle img_r;
|
nana::rectangle img_r;
|
||||||
|
|
||||||
@ -3721,7 +3732,7 @@ namespace nana
|
|||||||
//Make sure the user-define inline widgets is in the right visible rectangle.
|
//Make sure the user-define inline widgets is in the right visible rectangle.
|
||||||
rectangle pane_r;
|
rectangle pane_r;
|
||||||
|
|
||||||
const auto wdg_x = coord.x + content_pos;
|
const auto wdg_x = column_x + content_pos;
|
||||||
const auto wdg_w = col.width_px - static_cast<unsigned>(content_pos);
|
const auto wdg_w = col.width_px - static_cast<unsigned>(content_pos);
|
||||||
|
|
||||||
bool visible_state = true;
|
bool visible_state = true;
|
||||||
@ -5219,9 +5230,9 @@ namespace nana
|
|||||||
ess.update();
|
ess.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void listbox::scroll(bool to_bottom, const index_pair& pos)
|
void listbox::scroll(bool to_bottom, const index_pair& abs_pos)
|
||||||
{
|
{
|
||||||
_m_ess().lister.scroll(pos, to_bottom);
|
_m_ess().lister.scroll(abs_pos, to_bottom);
|
||||||
_m_ess().update();
|
_m_ess().update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -441,23 +441,9 @@ namespace nana
|
|||||||
|
|
||||||
renderer->item_text(graph, nana::point(item_r.x + 40, item_r.y + text_top_off), text, strpixels, attr);
|
renderer->item_text(graph, nana::point(item_r.x + 40, item_r.y + text_top_off), text, strpixels, attr);
|
||||||
|
|
||||||
if (hotkey)
|
|
||||||
{
|
|
||||||
item_ptr->hotkey = hotkey;
|
item_ptr->hotkey = hotkey;
|
||||||
if (item_ptr->flags.enabled)
|
if (hotkey && item_ptr->flags.enabled)
|
||||||
{
|
API::dev::draw_shortkey_underline(*graph_, text, hotkey, hotkey_pos, {item_r.x + 40, item_r.y + text_top_off}, colors::black);
|
||||||
auto off_px = (hotkey_pos ? graph.text_extent_size(text.c_str(), hotkey_pos).width : 0);
|
|
||||||
auto hotkey_px = graph.text_extent_size(text.c_str() + hotkey_pos, 1).width;
|
|
||||||
|
|
||||||
unsigned ascent, descent, inleading;
|
|
||||||
graph.text_metrics(ascent, descent, inleading);
|
|
||||||
|
|
||||||
int x = item_r.x + 40 + off_px;
|
|
||||||
int y = item_r.y + text_top_off + ascent + 1;
|
|
||||||
|
|
||||||
graph_->line({ x, y }, { x + static_cast<int>(hotkey_px)-1, y }, colors::black);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item_ptr->linked.menu_ptr)
|
if (item_ptr->linked.menu_ptr)
|
||||||
renderer->sub_arrow(graph, nana::point(graph_->width() - 20, item_r.y), item_h_px, attr);
|
renderer->sub_arrow(graph, nana::point(graph_->width() - 20, item_r.y), item_h_px, attr);
|
||||||
@ -624,10 +610,14 @@ namespace nana
|
|||||||
}
|
}
|
||||||
else if (item_ptr->flags.enabled)
|
else if (item_ptr->flags.enabled)
|
||||||
{
|
{
|
||||||
|
//A pointer refers to a menu object which owns the menu window.
|
||||||
|
//After fn_close_tree_(), *this is an invalid object.
|
||||||
|
auto owner = menu_->owner;
|
||||||
|
|
||||||
fn_close_tree_();
|
fn_close_tree_();
|
||||||
if (item_ptr->event_handler)
|
if (item_ptr->event_handler)
|
||||||
{
|
{
|
||||||
item_proxy ip{ index, menu_->owner };
|
item_proxy ip{ index, owner };
|
||||||
item_ptr->event_handler.operator()(ip);
|
item_ptr->event_handler.operator()(ip);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -1019,13 +1009,18 @@ namespace nana
|
|||||||
close();
|
close();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (2 != send_shortkey(arg.key))
|
switch (send_shortkey(arg.key))
|
||||||
{
|
{
|
||||||
if (API::empty_window(*this) == false)
|
case 0:
|
||||||
|
if (this->empty() == false)
|
||||||
close();
|
close();
|
||||||
}
|
break;
|
||||||
else
|
case 1: //The menu has been closed
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
this->submenu(true);
|
this->submenu(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1360,6 +1355,11 @@ namespace nana
|
|||||||
impl_->mbuilder.renderer(rd);
|
impl_->mbuilder.renderer(rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window menu::handle() const
|
||||||
|
{
|
||||||
|
return (impl_->window_ptr ? impl_->window_ptr->handle() : nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void menu::_m_popup(window wd, const point& pos, bool called_by_menubar)
|
void menu::_m_popup(window wd, const point& pos, bool called_by_menubar)
|
||||||
{
|
{
|
||||||
if (impl_->mbuilder.data().items.size())
|
if (impl_->mbuilder.data().items.size())
|
||||||
|
|||||||
@ -30,44 +30,155 @@ namespace nana
|
|||||||
{
|
{
|
||||||
struct item_type
|
struct item_type
|
||||||
{
|
{
|
||||||
item_type(const native_string_type text, unsigned long shortkey)
|
item_type(std::string&& text, wchar_t shortkey, std::size_t shortkey_pos):
|
||||||
: text(text), shortkey(shortkey)
|
text(std::move(text)),
|
||||||
|
shortkey(shortkey),
|
||||||
|
shortkey_pos(shortkey_pos)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
native_string_type text;
|
std::string text; ///< Transformed text, the shortkey charactor has been proccessed.
|
||||||
unsigned long shortkey;
|
wchar_t shortkey;
|
||||||
|
std::size_t shortkey_pos;
|
||||||
::nana::menu menu_obj;
|
::nana::menu menu_obj;
|
||||||
::nana::point pos;
|
::nana::point pos;
|
||||||
::nana::size size;
|
::nana::size size;
|
||||||
};
|
};
|
||||||
|
|
||||||
class trigger::itembase
|
struct trigger::essence
|
||||||
{
|
{
|
||||||
public:
|
enum class behavior
|
||||||
using container = std::vector<item_type*>;
|
{
|
||||||
|
none, focus, menu,
|
||||||
|
};
|
||||||
|
|
||||||
~itembase()
|
|
||||||
|
widget *widget_ptr{ nullptr };
|
||||||
|
std::vector<item_type*> items;
|
||||||
|
|
||||||
|
struct state_type
|
||||||
{
|
{
|
||||||
for(auto i : cont_)
|
std::size_t active{ nana::npos };
|
||||||
delete i;
|
behavior behave{ behavior::none };
|
||||||
|
|
||||||
|
bool menu_active{ false };
|
||||||
|
bool passive_close{ true };
|
||||||
|
|
||||||
|
bool nullify_mouse{ false };
|
||||||
|
|
||||||
|
nana::menu *menu{ nullptr };
|
||||||
|
nana::point mouse_pos;
|
||||||
|
}state;
|
||||||
|
|
||||||
|
//functions
|
||||||
|
|
||||||
|
~essence()
|
||||||
|
{
|
||||||
|
for (auto p : items)
|
||||||
|
delete p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void append(const native_string_type& text, unsigned long shortkey)
|
nana::menu& push_back(const std::string& text)
|
||||||
{
|
{
|
||||||
if(shortkey && shortkey < 0x61) shortkey += (0x61 - 0x41);
|
wchar_t shortkey;
|
||||||
cont_.emplace_back(new item_type(text, shortkey));
|
std::size_t shortkey_pos;
|
||||||
|
auto transformed_text = API::transform_shortkey_text(text, shortkey, &shortkey_pos);
|
||||||
|
|
||||||
|
if (shortkey)
|
||||||
|
API::register_shortkey(*widget_ptr, shortkey);
|
||||||
|
|
||||||
|
|
||||||
|
if (shortkey && shortkey < 0x61)
|
||||||
|
shortkey += (0x61 - 0x41);
|
||||||
|
items.emplace_back(new item_type{ std::move(transformed_text), shortkey, shortkey_pos });
|
||||||
|
|
||||||
|
API::refresh_window(*widget_ptr);
|
||||||
|
|
||||||
|
return this->items.back()->menu_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t find(unsigned long shortkey) const
|
bool cancel()
|
||||||
|
{
|
||||||
|
if (nana::npos == state.active)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
this->close_menu();
|
||||||
|
state.behave = behavior::none;
|
||||||
|
|
||||||
|
auto pos = API::cursor_position();
|
||||||
|
API::calc_window_point(widget_ptr->handle(), pos);
|
||||||
|
state.active = find(pos);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool open_menu(bool activate_menu = false)
|
||||||
|
{
|
||||||
|
if (activate_menu)
|
||||||
|
state.menu_active = true;
|
||||||
|
|
||||||
|
auto pos = state.active;
|
||||||
|
|
||||||
|
if (pos >= items.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto item_ptr = items[pos];
|
||||||
|
|
||||||
|
if (state.menu_active && (state.menu != &(item_ptr->menu_obj)))
|
||||||
|
{
|
||||||
|
API::dev::delay_restore(true);
|
||||||
|
this->close_menu();
|
||||||
|
API::dev::delay_restore(false);
|
||||||
|
state.active = pos;
|
||||||
|
|
||||||
|
//Resets this flag, because close_menu() deactivates the menu
|
||||||
|
state.menu_active = true;
|
||||||
|
|
||||||
|
state.menu = &(item_ptr->menu_obj);
|
||||||
|
state.menu->destroy_answer([this]
|
||||||
|
{
|
||||||
|
state.menu = nullptr;
|
||||||
|
if (state.passive_close)
|
||||||
|
{
|
||||||
|
cancel();
|
||||||
|
API::refresh_window(*widget_ptr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (API::focus_window() != this->widget_ptr->handle())
|
||||||
|
API::focus_window(widget_ptr->handle());
|
||||||
|
menu_accessor::popup(*state.menu, *widget_ptr, item_ptr->pos.x, item_ptr->pos.y + static_cast<int>(item_ptr->size.height));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool close_menu()
|
||||||
|
{
|
||||||
|
state.menu_active = false;
|
||||||
|
|
||||||
|
if (state.menu)
|
||||||
|
{
|
||||||
|
state.passive_close = false;
|
||||||
|
state.menu->close();
|
||||||
|
state.passive_close = true;
|
||||||
|
state.menu = nullptr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t find(wchar_t shortkey) const
|
||||||
{
|
{
|
||||||
if (shortkey)
|
if (shortkey)
|
||||||
{
|
{
|
||||||
if (shortkey < 0x61) shortkey += (0x61 - 0x41);
|
if (shortkey < 0x61) shortkey += (0x61 - 0x41);
|
||||||
|
|
||||||
std::size_t index = 0;
|
std::size_t index = 0;
|
||||||
for(auto i : cont_)
|
for (auto item_ptr : items)
|
||||||
{
|
{
|
||||||
if(i->shortkey == shortkey)
|
if (item_ptr->shortkey == shortkey)
|
||||||
return index;
|
return index;
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
@ -75,12 +186,25 @@ namespace nana
|
|||||||
return npos;
|
return npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
const container& cont() const
|
std::size_t find(const ::nana::point& pos)
|
||||||
{
|
{
|
||||||
return cont_;
|
if ((2 <= pos.x) && (2 <= pos.y) && (pos.y < 25))
|
||||||
|
{
|
||||||
|
int item_x = 2;
|
||||||
|
std::size_t index = 0;
|
||||||
|
|
||||||
|
for (auto item_ptr : items)
|
||||||
|
{
|
||||||
|
if ((item_x <= pos.x) && (pos.x < item_x + static_cast<int>(item_ptr->size.width)))
|
||||||
|
return index;
|
||||||
|
|
||||||
|
item_x += static_cast<int>(item_ptr->size.width);
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return npos;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
container cont_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//class item_renderer
|
//class item_renderer
|
||||||
@ -91,19 +215,17 @@ namespace nana
|
|||||||
void item_renderer::background(const nana::point& pos, const nana::size& size, state item_state)
|
void item_renderer::background(const nana::point& pos, const nana::size& size, state item_state)
|
||||||
{
|
{
|
||||||
auto bground = scheme_ptr_->text_fgcolor;
|
auto bground = scheme_ptr_->text_fgcolor;
|
||||||
::nana::color border, body, corner;
|
::nana::color border, body;
|
||||||
|
|
||||||
switch (item_state)
|
switch (item_state)
|
||||||
{
|
{
|
||||||
case state::highlighted:
|
case state::highlighted:
|
||||||
border = scheme_ptr_->border_highlight;
|
border = scheme_ptr_->border_highlight;
|
||||||
body = scheme_ptr_->body_highlight;
|
body = scheme_ptr_->body_highlight;
|
||||||
corner = body.blend(bground, 0.5);
|
|
||||||
break;
|
break;
|
||||||
case state::selected:
|
case state::selected:
|
||||||
border = scheme_ptr_->border_selected;
|
border = scheme_ptr_->border_selected;
|
||||||
body = scheme_ptr_->body_selected;
|
body = scheme_ptr_->body_selected;
|
||||||
corner = body.blend(bground, 0.5);
|
|
||||||
break;
|
break;
|
||||||
default: //Don't process other states.
|
default: //Don't process other states.
|
||||||
return;
|
return;
|
||||||
@ -112,7 +234,7 @@ namespace nana
|
|||||||
nana::rectangle r(pos, size);
|
nana::rectangle r(pos, size);
|
||||||
graph_.rectangle(r, false, border);
|
graph_.rectangle(r, false, border);
|
||||||
|
|
||||||
graph_.palette(false, corner);
|
graph_.palette(false, body.blend(bground, 0.5));
|
||||||
|
|
||||||
paint::draw{ graph_ }.corner(r, 1);
|
paint::draw{ graph_ }.corner(r, 1);
|
||||||
graph_.rectangle(r.pare_off(1), true, body);
|
graph_.rectangle(r.pare_off(1), true, body);
|
||||||
@ -127,77 +249,47 @@ namespace nana
|
|||||||
|
|
||||||
//class trigger
|
//class trigger
|
||||||
trigger::trigger()
|
trigger::trigger()
|
||||||
: widget_(nullptr)
|
: ess_(new essence)
|
||||||
, graph_(nullptr)
|
{}
|
||||||
, items_(new itembase) {}
|
|
||||||
|
|
||||||
trigger::~trigger()
|
trigger::~trigger()
|
||||||
{
|
{
|
||||||
delete items_;
|
delete ess_;
|
||||||
}
|
}
|
||||||
|
|
||||||
nana::menu* trigger::push_back(const std::string& text)
|
auto trigger::ess() const -> essence&
|
||||||
{
|
{
|
||||||
wchar_t shkey;
|
return *ess_;
|
||||||
API::transform_shortkey_text(text, shkey, nullptr);
|
|
||||||
|
|
||||||
if(shkey)
|
|
||||||
API::register_shortkey(widget_->handle(), shkey);
|
|
||||||
|
|
||||||
auto pos = items_->cont().size();
|
|
||||||
items_->append(to_nstring(text), shkey);
|
|
||||||
refresh(*graph_);
|
|
||||||
API::update_window(*widget_);
|
|
||||||
|
|
||||||
return at(pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nana::menu* trigger::at(std::size_t pos) const
|
void trigger::attached(widget_reference widget, graph_reference)
|
||||||
{
|
{
|
||||||
if (pos < items_->cont().size())
|
ess_->widget_ptr = &widget;
|
||||||
return &(items_->cont()[pos]->menu_obj);
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t trigger::size() const
|
|
||||||
{
|
|
||||||
return items_->cont().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::attached(widget_reference widget, graph_reference graph)
|
|
||||||
{
|
|
||||||
graph_ = &graph;
|
|
||||||
widget_ = &widget;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::refresh(graph_reference graph)
|
void trigger::refresh(graph_reference graph)
|
||||||
{
|
{
|
||||||
auto bgcolor = API::bgcolor(*widget_);
|
auto bgcolor = API::bgcolor(*ess_->widget_ptr);
|
||||||
graph_->rectangle(true, bgcolor);
|
|
||||||
|
|
||||||
item_renderer ird(*widget_, graph);
|
graph.rectangle(true, bgcolor);
|
||||||
|
|
||||||
|
item_renderer ird{ *ess_->widget_ptr, graph };
|
||||||
|
|
||||||
nana::point item_pos(2, 2);
|
nana::point item_pos(2, 2);
|
||||||
nana::size item_s(0, 23);
|
nana::size item_s(0, 23);
|
||||||
|
|
||||||
unsigned long index = 0;
|
unsigned long index = 0;
|
||||||
for (auto i : items_->cont())
|
|
||||||
|
for (auto pm : ess_->items)
|
||||||
{
|
{
|
||||||
//Transform the text if it contains the hotkey character
|
auto text_s = graph.text_extent_size(pm->text);
|
||||||
wchar_t hotkey;
|
|
||||||
::std::wstring::size_type hotkey_pos;
|
|
||||||
auto text = API::transform_shortkey_text(to_utf8(i->text), hotkey, &hotkey_pos);
|
|
||||||
|
|
||||||
nana::size text_s = graph.text_extent_size(text);
|
|
||||||
|
|
||||||
item_s.width = text_s.width + 16;
|
item_s.width = text_s.width + 16;
|
||||||
|
|
||||||
i->pos = item_pos;
|
pm->pos = item_pos;
|
||||||
i->size = item_s;
|
pm->size = item_s;
|
||||||
|
|
||||||
using state = item_renderer::state;
|
using state = item_renderer::state;
|
||||||
state item_state = (index != state_.active ? state::normal : (state_.menu_active ? state::selected : state::highlighted));
|
state item_state = (index != ess_->state.active ? state::normal : (ess_->state.menu_active ? state::selected : state::highlighted));
|
||||||
ird.background(item_pos, item_s, item_state);
|
ird.background(item_pos, item_s, item_state);
|
||||||
|
|
||||||
if (state::selected == item_state)
|
if (state::selected == item_state)
|
||||||
@ -210,73 +302,66 @@ namespace nana
|
|||||||
|
|
||||||
//Draw text, the text is transformed from orignal for hotkey character
|
//Draw text, the text is transformed from orignal for hotkey character
|
||||||
int text_top_off = (item_s.height - text_s.height) / 2;
|
int text_top_off = (item_s.height - text_s.height) / 2;
|
||||||
ird.caption({ item_pos.x + 8, item_pos.y + text_top_off }, to_nstring(text));
|
ird.caption({ item_pos.x + 8, item_pos.y + text_top_off }, to_nstring(pm->text));
|
||||||
|
|
||||||
if (hotkey)
|
API::dev::draw_shortkey_underline(graph, pm->text, pm->shortkey, pm->shortkey_pos, { item_pos.x + 8, item_pos.y + text_top_off }, ird.scheme_ptr()->text_fgcolor);
|
||||||
{
|
|
||||||
unsigned off_w = (hotkey_pos ? graph.text_extent_size(text.c_str(), hotkey_pos).width : 0);
|
|
||||||
auto hotkey_size = graph.text_extent_size(text.c_str() + hotkey_pos, 1);
|
|
||||||
|
|
||||||
unsigned ascent, descent, inleading;
|
item_pos.x += pm->size.width;
|
||||||
graph.text_metrics(ascent, descent, inleading);
|
|
||||||
int x = item_pos.x + 8 + off_w;
|
|
||||||
int y = item_pos.y + text_top_off + ascent + 1;
|
|
||||||
graph.line({ x, y }, { x + static_cast<int>(hotkey_size.width) - 1, y }, ird.scheme_ptr()->text_fgcolor);
|
|
||||||
}
|
|
||||||
|
|
||||||
item_pos.x += i->size.width;
|
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::mouse_move(graph_reference graph, const arg_mouse& arg)
|
void trigger::mouse_move(graph_reference graph, const arg_mouse& arg)
|
||||||
{
|
{
|
||||||
if (arg.pos != state_.mouse_pos)
|
|
||||||
state_.nullify_mouse = false;
|
if (arg.pos != ess_->state.mouse_pos)
|
||||||
|
ess_->state.nullify_mouse = false;
|
||||||
|
|
||||||
bool popup = false;
|
bool popup = false;
|
||||||
if(state_.behavior == state_type::behavior_focus)
|
if(essence::behavior::focus == ess_->state.behave)
|
||||||
{
|
{
|
||||||
auto index = _m_item_by_pos(arg.pos);
|
auto index = ess_->find(arg.pos);
|
||||||
if(index != npos && state_.active != index)
|
if(index != npos && ess_->state.active != index)
|
||||||
{
|
{
|
||||||
state_.active = index;
|
ess_->state.active = index;
|
||||||
|
popup = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!ess_->state.nullify_mouse)
|
||||||
|
{
|
||||||
|
auto which = ess_->find(arg.pos);
|
||||||
|
if ((which != ess_->state.active) && (which != npos || (false == ess_->state.menu_active)))
|
||||||
|
{
|
||||||
|
ess_->state.active = which;
|
||||||
popup = true;
|
popup = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
popup = _m_track_mouse(arg.pos);
|
|
||||||
|
|
||||||
if(popup)
|
if(popup)
|
||||||
{
|
{
|
||||||
_m_popup_menu();
|
ess_->open_menu();
|
||||||
refresh(graph);
|
refresh(graph);
|
||||||
API::dev::lazy_refresh();
|
API::dev::lazy_refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
state_.mouse_pos = arg.pos;
|
ess_->state.mouse_pos = arg.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::mouse_leave(graph_reference graph, const arg_mouse& arg)
|
void trigger::mouse_leave(graph_reference graph, const arg_mouse& arg)
|
||||||
{
|
{
|
||||||
state_.nullify_mouse = false;
|
ess_->state.nullify_mouse = false;
|
||||||
mouse_move(graph, arg);
|
mouse_move(graph, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::mouse_down(graph_reference graph, const arg_mouse& arg)
|
void trigger::mouse_down(graph_reference graph, const arg_mouse& arg)
|
||||||
{
|
{
|
||||||
state_.nullify_mouse = false;
|
ess_->state.nullify_mouse = false;
|
||||||
state_.active = _m_item_by_pos(arg.pos);
|
ess_->state.active = ess_->find(arg.pos);
|
||||||
|
|
||||||
if (npos != state_.active)
|
if (npos != ess_->state.active)
|
||||||
{
|
ess_->open_menu(true);
|
||||||
if (!state_.menu_active)
|
|
||||||
state_.menu_active = true;
|
|
||||||
|
|
||||||
_m_popup_menu();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
_m_total_close();
|
ess_->cancel();
|
||||||
|
|
||||||
refresh(graph);
|
refresh(graph);
|
||||||
API::dev::lazy_refresh();
|
API::dev::lazy_refresh();
|
||||||
@ -284,17 +369,17 @@ namespace nana
|
|||||||
|
|
||||||
void trigger::mouse_up(graph_reference graph, const arg_mouse&)
|
void trigger::mouse_up(graph_reference graph, const arg_mouse&)
|
||||||
{
|
{
|
||||||
state_.nullify_mouse = false;
|
ess_->state.nullify_mouse = false;
|
||||||
|
|
||||||
if(state_.behavior != state_.behavior_menu)
|
if(ess_->state.behave != essence::behavior::menu)
|
||||||
{
|
{
|
||||||
if(state_.menu_active)
|
if(ess_->state.menu_active)
|
||||||
state_.behavior = state_.behavior_menu;
|
ess_->state.behave = essence::behavior::menu;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state_.behavior = state_.behavior_none;
|
ess_->state.behave = essence::behavior::none;
|
||||||
_m_total_close();
|
ess_->cancel();
|
||||||
refresh(graph);
|
refresh(graph);
|
||||||
API::dev::lazy_refresh();
|
API::dev::lazy_refresh();
|
||||||
}
|
}
|
||||||
@ -302,13 +387,12 @@ namespace nana
|
|||||||
|
|
||||||
void trigger::focus(graph_reference graph, const arg_focus& arg)
|
void trigger::focus(graph_reference graph, const arg_focus& arg)
|
||||||
{
|
{
|
||||||
if((arg.getting == false) && (state_.active != npos))
|
if((arg.getting == false) && (ess_->state.active != npos))
|
||||||
{
|
{
|
||||||
state_.behavior = state_type::behavior_none;
|
ess_->state.behave = essence::behavior::none;
|
||||||
state_.nullify_mouse = true;
|
ess_->state.nullify_mouse = true;
|
||||||
state_.menu_active = false;
|
ess_->close_menu();
|
||||||
_m_close_menu();
|
ess_->state.active = npos;
|
||||||
state_.active = npos;
|
|
||||||
refresh(graph);
|
refresh(graph);
|
||||||
API::dev::lazy_refresh();
|
API::dev::lazy_refresh();
|
||||||
}
|
}
|
||||||
@ -316,53 +400,54 @@ namespace nana
|
|||||||
|
|
||||||
void trigger::key_press(graph_reference graph, const arg_keyboard& arg)
|
void trigger::key_press(graph_reference graph, const arg_keyboard& arg)
|
||||||
{
|
{
|
||||||
state_.nullify_mouse = true;
|
ess_->state.nullify_mouse = true;
|
||||||
if(state_.menu)
|
|
||||||
|
auto & menu_ptr = ess_->state.menu;
|
||||||
|
if(ess_->state.menu)
|
||||||
{
|
{
|
||||||
switch(arg.key)
|
switch(arg.key)
|
||||||
{
|
{
|
||||||
case keyboard::os_arrow_down:
|
case keyboard::os_arrow_down:
|
||||||
case keyboard::backspace:
|
case keyboard::backspace:
|
||||||
case keyboard::os_arrow_up:
|
case keyboard::os_arrow_up:
|
||||||
state_.menu->goto_next(keyboard::os_arrow_down == arg.key);
|
menu_ptr->goto_next(keyboard::os_arrow_down == arg.key);
|
||||||
break;
|
break;
|
||||||
case keyboard::os_arrow_right:
|
case keyboard::os_arrow_right:
|
||||||
if(state_.menu->goto_submen() == false)
|
if(menu_ptr->goto_submen() == false)
|
||||||
_m_move(false);
|
_m_move(graph, false);
|
||||||
break;
|
break;
|
||||||
case keyboard::os_arrow_left:
|
case keyboard::os_arrow_left:
|
||||||
if(state_.menu->exit_submenu() == false)
|
if(menu_ptr->exit_submenu() == false)
|
||||||
_m_move(true);
|
_m_move(graph, true);
|
||||||
break;
|
break;
|
||||||
case keyboard::escape:
|
case keyboard::escape:
|
||||||
if(state_.menu->exit_submenu() == false)
|
if(menu_ptr->exit_submenu() == false)
|
||||||
{
|
{
|
||||||
_m_close_menu();
|
ess_->close_menu();
|
||||||
state_.behavior = state_.behavior_focus;
|
ess_->state.behave = essence::behavior::focus;
|
||||||
state_.menu_active = false;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case keyboard::enter:
|
case keyboard::enter:
|
||||||
state_.menu->pick();
|
menu_ptr->pick();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//Katsuhisa Yuasa: menubar key_press improvements
|
//Katsuhisa Yuasa: menubar key_press improvements
|
||||||
//send_shortkey has 3 states, 0 = UNKNOWN KEY, 1 = ITEM, 2 = GOTO SUBMENU
|
//send_shortkey has 3 states, 0 = UNKNOWN KEY, 1 = ITEM, 2 = GOTO SUBMENU
|
||||||
int sk_state = state_.menu->send_shortkey(arg.key);
|
int sk_state = menu_ptr->send_shortkey(arg.key);
|
||||||
switch(sk_state)
|
switch(sk_state)
|
||||||
{
|
{
|
||||||
case 0: //UNKNOWN KEY
|
case 0: //UNKNOWN KEY
|
||||||
break;
|
break;
|
||||||
case 1: //ITEM
|
case 1: //ITEM
|
||||||
if (state_.active != npos)
|
if (ess_->state.active != npos)
|
||||||
{
|
{
|
||||||
_m_total_close();
|
ess_->cancel();
|
||||||
if (arg.key == 18) //ALT
|
if (arg.key == 18) //ALT
|
||||||
state_.behavior = state_.behavior_focus;
|
ess_->state.behave = essence::behavior::focus;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: //GOTO SUBMENU
|
case 2: //GOTO SUBMENU
|
||||||
state_.menu->goto_submen();
|
menu_ptr->goto_submen();
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
@ -376,30 +461,28 @@ namespace nana
|
|||||||
case keyboard::os_arrow_right:
|
case keyboard::os_arrow_right:
|
||||||
case keyboard::backspace:
|
case keyboard::backspace:
|
||||||
case keyboard::os_arrow_left:
|
case keyboard::os_arrow_left:
|
||||||
_m_move(keyboard::os_arrow_right != arg.key);
|
_m_move(graph, keyboard::os_arrow_right != arg.key);
|
||||||
break;
|
break;
|
||||||
case keyboard::os_arrow_up:
|
case keyboard::os_arrow_up:
|
||||||
case keyboard::os_arrow_down:
|
case keyboard::os_arrow_down:
|
||||||
case keyboard::enter:
|
case keyboard::enter:
|
||||||
state_.menu_active = true;
|
if(ess_->open_menu(true))
|
||||||
if(_m_popup_menu())
|
menu_ptr->goto_next(true);
|
||||||
state_.menu->goto_next(true);
|
|
||||||
break;
|
break;
|
||||||
case keyboard::escape:
|
case keyboard::escape:
|
||||||
if(state_.behavior == state_.behavior_focus)
|
if(essence::behavior::focus == ess_->state.behave)
|
||||||
{
|
{
|
||||||
state_.active= npos;
|
ess_->state.active= npos;
|
||||||
state_.behavior = state_.behavior_none;
|
ess_->state.behave = essence::behavior::none;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
auto index = items_->find(arg.key);
|
auto index = ess_->find(arg.key);
|
||||||
if(index != npos)
|
if(index != npos)
|
||||||
{
|
{
|
||||||
state_.active = index;
|
ess_->state.active = index;
|
||||||
state_.menu_active = true;
|
if(ess_->open_menu(true))
|
||||||
if(_m_popup_menu())
|
menu_ptr->goto_next(true);
|
||||||
state_.menu->goto_next(true);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -413,20 +496,20 @@ namespace nana
|
|||||||
{
|
{
|
||||||
if(arg.key == 18)
|
if(arg.key == 18)
|
||||||
{
|
{
|
||||||
if(state_.behavior == state_type::behavior_none)
|
if(essence::behavior::none == ess_->state.behave)
|
||||||
{
|
{
|
||||||
state_.behavior = state_type::behavior_focus;
|
ess_->state.behave = essence::behavior::focus;
|
||||||
state_.active = 0;
|
ess_->state.active = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state_.behavior = state_type::behavior_none;
|
ess_->state.behave = essence::behavior::none;
|
||||||
auto pos = API::cursor_position();
|
auto pos = API::cursor_position();
|
||||||
API::calc_window_point(widget_->handle(), pos);
|
API::calc_window_point(ess_->widget_ptr->handle(), pos);
|
||||||
state_.active = _m_item_by_pos(pos);
|
ess_->state.active = ess_->find(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
state_.menu_active = false;
|
ess_->state.menu_active = false;
|
||||||
refresh(graph);
|
refresh(graph);
|
||||||
API::dev::lazy_refresh();
|
API::dev::lazy_refresh();
|
||||||
}
|
}
|
||||||
@ -434,31 +517,31 @@ namespace nana
|
|||||||
|
|
||||||
void trigger::shortkey(graph_reference graph, const arg_keyboard& arg)
|
void trigger::shortkey(graph_reference graph, const arg_keyboard& arg)
|
||||||
{
|
{
|
||||||
API::focus_window(widget_->handle());
|
API::focus_window(ess_->widget_ptr->handle());
|
||||||
|
|
||||||
auto index = items_->find(arg.key);
|
auto index = ess_->find(arg.key);
|
||||||
if(index != npos && (index != state_.active || nullptr == state_.menu))
|
if(index != npos && (index != ess_->state.active || nullptr == ess_->state.menu))
|
||||||
{
|
{
|
||||||
_m_close_menu();
|
ess_->close_menu();
|
||||||
state_.menu_active = true;
|
ess_->state.nullify_mouse = true;
|
||||||
state_.nullify_mouse = true;
|
ess_->state.active = index;
|
||||||
state_.active = index;
|
|
||||||
|
|
||||||
if(_m_popup_menu())
|
if(ess_->open_menu(true))
|
||||||
state_.menu->goto_next(true);
|
ess_->state.menu->goto_next(true);
|
||||||
|
|
||||||
refresh(graph);
|
refresh(graph);
|
||||||
API::dev::lazy_refresh();
|
API::dev::lazy_refresh();
|
||||||
state_.behavior = state_.behavior_menu;
|
ess_->state.behave = essence::behavior::menu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::_m_move(bool to_left)
|
void trigger::_m_move(graph_reference graph, bool to_left)
|
||||||
{
|
{
|
||||||
if(items_->cont().empty()) return;
|
if (ess_->items.empty()) return;
|
||||||
|
|
||||||
const std::size_t last_pos = items_->cont().size() - 1;
|
const std::size_t last_pos = ess_->items.size() - 1;
|
||||||
auto index = state_.active;
|
|
||||||
|
auto index = ess_->state.active;
|
||||||
if(to_left)
|
if(to_left)
|
||||||
{
|
{
|
||||||
--index;
|
--index;
|
||||||
@ -472,121 +555,16 @@ namespace nana
|
|||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(index != state_.active)
|
if(index != ess_->state.active)
|
||||||
{
|
{
|
||||||
state_.active = index;
|
ess_->state.active = index;
|
||||||
refresh(*graph_);
|
refresh(graph);
|
||||||
API::dev::lazy_refresh();
|
API::dev::lazy_refresh();
|
||||||
|
|
||||||
if(_m_popup_menu())
|
if(ess_->open_menu())
|
||||||
state_.menu->goto_next(true);
|
ess_->state.menu->goto_next(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool trigger::_m_popup_menu()
|
|
||||||
{
|
|
||||||
auto& items = items_->cont();
|
|
||||||
|
|
||||||
auto pos = state_.active;
|
|
||||||
if (pos >= items.size())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(state_.menu_active && (state_.menu != &(items[pos]->menu_obj)))
|
|
||||||
{
|
|
||||||
API::dev::delay_restore(true);
|
|
||||||
_m_close_menu();
|
|
||||||
API::dev::delay_restore(false);
|
|
||||||
state_.active = pos;
|
|
||||||
|
|
||||||
auto & m = items[pos];
|
|
||||||
state_.menu = &(m->menu_obj);
|
|
||||||
state_.menu->destroy_answer([this]
|
|
||||||
{
|
|
||||||
state_.menu = nullptr;
|
|
||||||
if (state_.passive_close)
|
|
||||||
{
|
|
||||||
_m_total_close();
|
|
||||||
|
|
||||||
refresh(*graph_);
|
|
||||||
API::update_window(widget_->handle());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (API::focus_window() != this->widget_->handle())
|
|
||||||
API::focus_window(widget_->handle());
|
|
||||||
menu_accessor::popup(*state_.menu, *widget_, m->pos.x, m->pos.y + static_cast<int>(m->size.height));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::_m_total_close()
|
|
||||||
{
|
|
||||||
_m_close_menu();
|
|
||||||
state_.menu_active = false;
|
|
||||||
state_.behavior = state_.behavior_none;
|
|
||||||
|
|
||||||
auto pos = API::cursor_position();
|
|
||||||
API::calc_window_point(widget_->handle(), pos);
|
|
||||||
state_.active = _m_item_by_pos(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool trigger::_m_close_menu()
|
|
||||||
{
|
|
||||||
if(state_.menu)
|
|
||||||
{
|
|
||||||
state_.passive_close = false;
|
|
||||||
state_.menu->close();
|
|
||||||
state_.passive_close = true;
|
|
||||||
state_.menu = nullptr;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t trigger::_m_item_by_pos(const ::nana::point& pos)
|
|
||||||
{
|
|
||||||
if((2 <= pos.x) && (2 <= pos.y) && (pos.y < 25))
|
|
||||||
{
|
|
||||||
int item_x = 2;
|
|
||||||
std::size_t index = 0;
|
|
||||||
for(auto i : items_->cont())
|
|
||||||
{
|
|
||||||
if(item_x <= pos.x && pos.x < item_x + static_cast<int>(i->size.width))
|
|
||||||
return index;
|
|
||||||
|
|
||||||
item_x += i->size.width;
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return npos;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool trigger::_m_track_mouse(const ::nana::point& pos)
|
|
||||||
{
|
|
||||||
if(state_.nullify_mouse == false)
|
|
||||||
{
|
|
||||||
auto which = _m_item_by_pos(pos);
|
|
||||||
if((which != state_.active) && (which != npos || (false == state_.menu_active)))
|
|
||||||
{
|
|
||||||
state_.active = which;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//struct state_type
|
|
||||||
trigger::state_type::state_type()
|
|
||||||
: active(npos),
|
|
||||||
behavior(behavior_none),
|
|
||||||
menu_active(false),
|
|
||||||
passive_close(true),
|
|
||||||
nullify_mouse(false),
|
|
||||||
menu(nullptr)
|
|
||||||
{}
|
|
||||||
//end struct state_type
|
|
||||||
//end class trigger
|
//end class trigger
|
||||||
}//end namespace menubar
|
}//end namespace menubar
|
||||||
}//end namespace drawerbase
|
}//end namespace drawerbase
|
||||||
@ -609,7 +587,7 @@ namespace nana
|
|||||||
::create(wd, rectangle(nana::size(API::window_size(wd).width, 28)));
|
::create(wd, rectangle(nana::size(API::window_size(wd).width, 28)));
|
||||||
|
|
||||||
API::dev::set_menubar(handle(), true);
|
API::dev::set_menubar(handle(), true);
|
||||||
evt_resized_ = API::events(wd).resized.connect([this](const ::nana::arg_resized& arg)
|
evt_resized_ = API::events(wd).resized.connect_unignorable([this](const ::nana::arg_resized& arg)
|
||||||
{
|
{
|
||||||
auto sz = this->size();
|
auto sz = this->size();
|
||||||
sz.width = arg.width;
|
sz.width = arg.width;
|
||||||
@ -619,20 +597,49 @@ namespace nana
|
|||||||
|
|
||||||
menu& menubar::push_back(const std::string& text)
|
menu& menubar::push_back(const std::string& text)
|
||||||
{
|
{
|
||||||
return *(get_drawer_trigger().push_back(text));
|
return get_drawer_trigger().ess().push_back(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
menu& menubar::at(std::size_t index) const
|
menu& menubar::at(std::size_t pos) const
|
||||||
{
|
{
|
||||||
auto p = get_drawer_trigger().at(index);
|
return get_drawer_trigger().ess().items.at(pos)->menu_obj;
|
||||||
if(nullptr == p)
|
|
||||||
throw std::out_of_range("menubar::at, out of range");
|
|
||||||
return *p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t menubar::length() const
|
std::size_t menubar::length() const
|
||||||
{
|
{
|
||||||
return get_drawer_trigger().size();
|
return get_drawer_trigger().ess().items.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool menubar::cancel()
|
||||||
|
{
|
||||||
|
return get_drawer_trigger().ess().cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool menubar::hovered() const
|
||||||
|
{
|
||||||
|
auto const native_handle = API::root(this->handle());
|
||||||
|
if (native_handle)
|
||||||
|
{
|
||||||
|
auto wd = API::find_window(API::cursor_position());
|
||||||
|
if (wd == this->handle())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto & items = get_drawer_trigger().ess().items;
|
||||||
|
while (wd)
|
||||||
|
{
|
||||||
|
auto owner = API::get_owner_window(wd);
|
||||||
|
if (API::root(owner) == native_handle)
|
||||||
|
{
|
||||||
|
for (auto p : items)
|
||||||
|
{
|
||||||
|
if (p->menu_obj.handle() == wd)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wd = owner;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
//end class menubar
|
//end class menubar
|
||||||
}//end namespace nana
|
}//end namespace nana
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* A Progress Indicator Implementation
|
* A Progress Indicator 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.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -17,136 +17,185 @@ namespace nana
|
|||||||
{
|
{
|
||||||
namespace progress
|
namespace progress
|
||||||
{
|
{
|
||||||
//class trigger
|
scheme::scheme()
|
||||||
void trigger::attached(widget_reference wd, graph_reference graph)
|
|
||||||
{
|
{
|
||||||
widget_ = &wd;
|
foreground = static_cast<color_rgb>(0x107515);
|
||||||
graph_ = &graph;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned trigger::value() const
|
class substance
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
static const unsigned border_px = 1;
|
||||||
|
|
||||||
|
void set_widget(widget& wdg)
|
||||||
|
{
|
||||||
|
widget_ = static_cast<nana::progress*>(&wdg);
|
||||||
|
}
|
||||||
|
|
||||||
|
nana::progress* widget_ptr() const
|
||||||
|
{
|
||||||
|
return widget_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned inc()
|
||||||
|
{
|
||||||
|
auto val = value(nullptr) + 1;
|
||||||
|
return value(&val);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned value(const unsigned* value_ptr)
|
||||||
|
{
|
||||||
|
//Sets new value if value_ptr is not a nullptr
|
||||||
|
if (value_ptr)
|
||||||
|
{
|
||||||
|
if (unknown_)
|
||||||
|
value_ += (*value_ptr ? 5 : 0);
|
||||||
|
else
|
||||||
|
value_ = (std::min)(max_, *value_ptr);
|
||||||
|
|
||||||
|
_m_try_refresh();
|
||||||
|
}
|
||||||
return value_;
|
return value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned trigger::value(unsigned v)
|
void reset_value()
|
||||||
{
|
{
|
||||||
internal_scope_guard isg;
|
value_ = 0;
|
||||||
if(false == unknown_)
|
|
||||||
{
|
|
||||||
if(value_ != v)
|
|
||||||
value_ = v > max_?max_:v;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
value_ += (v?10:v);
|
|
||||||
|
|
||||||
if(_m_check_changing(value_))
|
|
||||||
{
|
|
||||||
refresh(*graph_);
|
|
||||||
API::update_window(widget_->handle());
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned trigger::inc()
|
unsigned maximum(const unsigned * value_ptr)
|
||||||
{
|
{
|
||||||
internal_scope_guard isg;
|
//Sets new maximum if value_ptr is not a nullptr
|
||||||
if(false == unknown_)
|
if (value_ptr)
|
||||||
{
|
{
|
||||||
if(value_ < max_)
|
max_ = (*value_ptr > 0 ? *value_ptr : 1);
|
||||||
++value_;
|
_m_try_refresh();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
value_ += 5;
|
|
||||||
|
|
||||||
if(_m_check_changing(value_))
|
|
||||||
API::refresh_window(widget_->handle());
|
|
||||||
return value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned trigger::Max() const
|
|
||||||
{
|
|
||||||
return max_;
|
return max_;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned trigger::Max(unsigned value)
|
bool unknown(const bool* state_ptr)
|
||||||
{
|
{
|
||||||
max_ = value;
|
if (state_ptr)
|
||||||
if(max_ == 0) ++max_;
|
{
|
||||||
|
unknown_ = *state_ptr;
|
||||||
API::refresh_window(widget_->handle());
|
if (unknown_)
|
||||||
return max_;
|
value_px_ = 0;
|
||||||
|
else
|
||||||
|
value_ = (std::min)(value_, max_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::unknown(bool enb)
|
|
||||||
{
|
|
||||||
unknown_ = enb;
|
|
||||||
if(enb)
|
|
||||||
draw_width_ = static_cast<unsigned>(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool trigger::unknown() const
|
|
||||||
{
|
|
||||||
return unknown_;
|
return unknown_;
|
||||||
}
|
}
|
||||||
bool trigger::stopped() const
|
|
||||||
|
unsigned value_px() const
|
||||||
{
|
{
|
||||||
return stop_;
|
return value_px_;
|
||||||
}
|
}
|
||||||
bool trigger::stop(bool s)
|
private:
|
||||||
|
void _m_try_refresh()
|
||||||
{
|
{
|
||||||
std::swap(s,stop_);
|
if (nullptr == widget_)
|
||||||
return s;
|
return;
|
||||||
|
|
||||||
|
auto value_px = (widget_->size().width - border_px * 2) * value_ / max_;
|
||||||
|
|
||||||
|
if (value_px != value_px_)
|
||||||
|
{
|
||||||
|
value_px_ = value_px;
|
||||||
|
API::refresh_window(*widget_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
nana::progress * widget_{ nullptr };
|
||||||
|
unsigned max_{ 100 };
|
||||||
|
unsigned value_{ 0 };
|
||||||
|
unsigned value_px_{ 0 };
|
||||||
|
bool unknown_{ false };
|
||||||
|
};
|
||||||
|
|
||||||
|
trigger::trigger()
|
||||||
|
: progress_(new substance)
|
||||||
|
{}
|
||||||
|
|
||||||
|
trigger::~trigger()
|
||||||
|
{
|
||||||
|
delete progress_;
|
||||||
|
}
|
||||||
|
|
||||||
|
substance* trigger::progress() const
|
||||||
|
{
|
||||||
|
return progress_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger::attached(widget_reference wdg, graph_reference)
|
||||||
|
{
|
||||||
|
progress_->set_widget(wdg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::refresh(graph_reference graph)
|
void trigger::refresh(graph_reference graph)
|
||||||
{
|
{
|
||||||
if (false == unknown_)
|
const unsigned border_px = substance::border_px;
|
||||||
draw_width_ = static_cast<unsigned>((graph.width() - border * 2) * (double(value_) / max_));
|
|
||||||
|
|
||||||
_m_draw_box(graph);
|
rectangle rt_val{ graph.size() };
|
||||||
_m_draw_progress(graph);
|
auto const width = rt_val.width - border_px * 2;
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::_m_draw_box(graph_reference graph)
|
rt_val.pare_off(static_cast<int>(border_px));
|
||||||
|
|
||||||
|
auto rt_bground = rt_val;
|
||||||
|
if (false == progress_->unknown(nullptr))
|
||||||
{
|
{
|
||||||
rectangle r{ graph.size() };
|
rt_bground.x = static_cast<int>(progress_->value_px()) + static_cast<int>(border_px);
|
||||||
graph.gradual_rectangle(r, colors::button_face_shadow_end, colors::button_face_shadow_start, true);
|
rt_bground.width -= progress_->value_px();
|
||||||
::nana::color lt{ colors::gray }, rb{colors::white};
|
|
||||||
graph.frame_rectangle(r, lt, lt, rb, rb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::_m_draw_progress(graph_reference graph)
|
rt_val.width = progress_->value_px();
|
||||||
{
|
|
||||||
unsigned width = graph.width() - border * 2;
|
|
||||||
unsigned height = graph.height() - border * 2;
|
|
||||||
|
|
||||||
if(false == unknown_)
|
|
||||||
{
|
|
||||||
if(draw_width_)
|
|
||||||
graph.gradual_rectangle({ static_cast<int>(border), static_cast<int>(border), draw_width_, height }, { 0x6F, 0xFF, 0xA8 }, { 0x10, 0x75, 0x15 }, true);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned block = width / 3;
|
auto const block = width / 3;
|
||||||
|
|
||||||
int left = (value_ < block ? 0 : value_ - block) + border;
|
auto const value = progress_->value(nullptr);
|
||||||
int right = (value_ >= width - 1 + border? width - 1 + border: value_);
|
|
||||||
|
|
||||||
if(right >= left)
|
auto left = (std::max)(0, static_cast<int>(value - block)) + static_cast<int>(border_px);
|
||||||
graph.gradual_rectangle({ left, static_cast<int>(border), static_cast<unsigned>(right - left + 1), height }, { 0x6F, 0xFF, 0xA8 }, { 0x10, 0x75, 0x15 }, true);
|
auto right = static_cast<int>((std::min)(value, width + border_px -1));
|
||||||
|
|
||||||
if(value_ >= width + block) value_ = 0;
|
if (right > left)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool trigger::_m_check_changing(unsigned newvalue) const
|
|
||||||
{
|
{
|
||||||
if(graph_)
|
rt_val.x = left;
|
||||||
return (((graph_->width() - border * 2) * newvalue / max_) != draw_width_);
|
rt_val.width = static_cast<unsigned>(right - left + 1);
|
||||||
return false;
|
}
|
||||||
|
else
|
||||||
|
rt_val.width = 0;
|
||||||
|
|
||||||
|
if (value >= width + block)
|
||||||
|
progress_->reset_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto & sch = progress_->widget_ptr()->scheme();
|
||||||
|
|
||||||
|
//Draw the gradient background if gradient_bgcolor is available.
|
||||||
|
|
||||||
|
auto bgcolor = sch.background.get_color();
|
||||||
|
if (bgcolor.invisible())
|
||||||
|
bgcolor = colors::button_face;
|
||||||
|
|
||||||
|
if (sch.gradient_bgcolor.get_color().invisible())
|
||||||
|
graph.rectangle(rt_bground, true, bgcolor);
|
||||||
|
else
|
||||||
|
graph.gradual_rectangle(rt_bground, bgcolor, sch.gradient_bgcolor.get_color(), true);
|
||||||
|
|
||||||
|
//Draw the gradient fgcolor if gradient_fgcolor is available.
|
||||||
|
|
||||||
|
auto fgcolor = sch.foreground.get_color();
|
||||||
|
if (fgcolor.invisible())
|
||||||
|
fgcolor = static_cast<color_rgb>(0x107515);
|
||||||
|
|
||||||
|
if (sch.gradient_fgcolor.get_color().invisible())
|
||||||
|
graph.rectangle(rt_val, true, fgcolor);
|
||||||
|
else
|
||||||
|
graph.gradual_rectangle(rt_val, sch.gradient_fgcolor.get_color(), fgcolor, true);
|
||||||
|
|
||||||
|
graph.frame_rectangle(rectangle{ graph.size() }, colors::gray, colors::gray, colors::white, colors::white);
|
||||||
}
|
}
|
||||||
//end class drawer
|
|
||||||
}//end namespace progress
|
}//end namespace progress
|
||||||
}//end namespace drawerbase
|
}//end namespace drawerbase
|
||||||
|
|
||||||
@ -165,49 +214,42 @@ namespace nana
|
|||||||
|
|
||||||
unsigned progress::value() const
|
unsigned progress::value() const
|
||||||
{
|
{
|
||||||
return get_drawer_trigger().value();
|
return get_drawer_trigger().progress()->value(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned progress::value(unsigned val)
|
unsigned progress::value(unsigned val)
|
||||||
{
|
{
|
||||||
internal_scope_guard isg;
|
internal_scope_guard lock;
|
||||||
if(API::empty_window(this->handle()) == false)
|
if(API::empty_window(this->handle()) == false)
|
||||||
return get_drawer_trigger().value(val);
|
return get_drawer_trigger().progress()->value(&val);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned progress::inc()
|
unsigned progress::inc()
|
||||||
{
|
{
|
||||||
internal_scope_guard isg;
|
internal_scope_guard lock;
|
||||||
return get_drawer_trigger().inc();
|
return get_drawer_trigger().progress()->inc();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned progress::amount() const
|
unsigned progress::amount() const
|
||||||
{
|
{
|
||||||
return get_drawer_trigger().Max();
|
return get_drawer_trigger().progress()->maximum(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned progress::amount(unsigned value)
|
unsigned progress::amount(unsigned value)
|
||||||
{
|
{
|
||||||
return get_drawer_trigger().Max(value);
|
return get_drawer_trigger().progress()->maximum(&value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void progress::unknown(bool enb)
|
void progress::unknown(bool enb)
|
||||||
{
|
{
|
||||||
get_drawer_trigger().unknown(enb);
|
internal_scope_guard lock;
|
||||||
|
get_drawer_trigger().progress()->unknown(&enb);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool progress::unknown() const
|
bool progress::unknown() const
|
||||||
{
|
{
|
||||||
return get_drawer_trigger().unknown();
|
return get_drawer_trigger().progress()->unknown(nullptr);
|
||||||
}
|
|
||||||
bool progress::stop(bool s)
|
|
||||||
{
|
|
||||||
return get_drawer_trigger().stop(s);
|
|
||||||
}
|
|
||||||
bool progress::stopped() const
|
|
||||||
{
|
|
||||||
return get_drawer_trigger().stopped();
|
|
||||||
}
|
}
|
||||||
//end class progress
|
//end class progress
|
||||||
}//end namespace nana
|
}//end namespace nana
|
||||||
|
|||||||
@ -887,6 +887,7 @@ namespace nana{ namespace widgets
|
|||||||
return (pos < linemtr_.size() ? linemtr_[pos].take_lines : 0);
|
return (pos < linemtr_.size() ? linemtr_[pos].take_lines : 0);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
/// Split a text into multiple sections, a section indicates an english word or a CKJ character
|
||||||
void _m_text_section(const std::wstring& str, std::vector<text_section>& tsec)
|
void _m_text_section(const std::wstring& str, std::vector<text_section>& tsec)
|
||||||
{
|
{
|
||||||
if (str.empty())
|
if (str.empty())
|
||||||
@ -947,11 +948,13 @@ namespace nana{ namespace widgets
|
|||||||
class text_editor::keyword_parser
|
class text_editor::keyword_parser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void parse(const std::wstring& text, const implementation::inner_keywords& keywords)
|
void parse(const wchar_t* c_str, std::size_t len, implementation::inner_keywords& keywords) //need string_view
|
||||||
{
|
{
|
||||||
if ( keywords.base.empty() || text.empty() )
|
if ( keywords.base.empty() || (0 == len) || (*c_str == 0) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
std::wstring text{ c_str, len };
|
||||||
|
|
||||||
using index = std::wstring::size_type;
|
using index = std::wstring::size_type;
|
||||||
|
|
||||||
std::vector<entity> entities;
|
std::vector<entity> entities;
|
||||||
@ -986,7 +989,7 @@ namespace nana{ namespace widgets
|
|||||||
{
|
{
|
||||||
entities.emplace_back();
|
entities.emplace_back();
|
||||||
auto & last = entities.back();
|
auto & last = entities.back();
|
||||||
last.begin = text.c_str() + pos;
|
last.begin = c_str + pos;
|
||||||
last.end = last.begin + ds.text.size();
|
last.end = last.begin + ds.text.size();
|
||||||
last.scheme = ki->second.get();
|
last.scheme = ki->second.get();
|
||||||
}
|
}
|
||||||
@ -1025,14 +1028,14 @@ namespace nana{ namespace widgets
|
|||||||
if (pos)
|
if (pos)
|
||||||
{
|
{
|
||||||
auto chr = text[pos - 1];
|
auto chr = text[pos - 1];
|
||||||
if ((std::iswalpha(chr) && !std::isspace(chr)) || chr == '_')
|
if ((std::iswalpha(chr) && !std::iswspace(chr)) || chr == '_')
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos + len < text.size())
|
if (pos + len < text.size())
|
||||||
{
|
{
|
||||||
auto chr = text[pos + len];
|
auto chr = text[pos + len];
|
||||||
if ((std::iswalpha(chr) && !std::isspace(chr)) || chr == '_')
|
if ((std::iswalpha(chr) && !std::iswspace(chr)) || chr == '_')
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1596,18 +1599,6 @@ namespace nana{ namespace widgets
|
|||||||
if(!attributes_.enable_caret)
|
if(!attributes_.enable_caret)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto is_whitespace = [](wchar_t c) {
|
|
||||||
switch (c) {
|
|
||||||
case L' ':
|
|
||||||
case L'\t':
|
|
||||||
case L'\n':
|
|
||||||
case L'\r':
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set caret pos by screen point and get the caret pos.
|
// Set caret pos by screen point and get the caret pos.
|
||||||
mouse_caret(arg.pos, true);
|
mouse_caret(arg.pos, true);
|
||||||
|
|
||||||
@ -1616,11 +1607,11 @@ namespace nana{ namespace widgets
|
|||||||
const auto& line = impl_->textbase.getline(select_.b.y);
|
const auto& line = impl_->textbase.getline(select_.b.y);
|
||||||
|
|
||||||
// Expand the selection forward to the word's end.
|
// Expand the selection forward to the word's end.
|
||||||
while (select_.b.x < line.size() && !is_whitespace(line[select_.b.x]))
|
while (select_.b.x < line.size() && !std::iswspace(line[select_.b.x]))
|
||||||
++select_.b.x;
|
++select_.b.x;
|
||||||
|
|
||||||
// Expand the selection backward to the word's start.
|
// Expand the selection backward to the word's start.
|
||||||
while (select_.a.x > 0 && !is_whitespace(line[select_.a.x - 1]))
|
while (select_.a.x > 0 && !std::iswspace(line[select_.a.x - 1]))
|
||||||
--select_.a.x;
|
--select_.a.x;
|
||||||
|
|
||||||
select_.mode_selection = selection::mode::method_selected;
|
select_.mode_selection = selection::mode::method_selected;
|
||||||
@ -2876,7 +2867,6 @@ namespace nana{ namespace widgets
|
|||||||
return ('0' <= ch && ch <= '9');
|
return ('0' <= ch && ch <= '9');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
::nana::color text_editor::_m_bgcolor() const
|
::nana::color text_editor::_m_bgcolor() const
|
||||||
{
|
{
|
||||||
return (!API::window_enabled(window_) ? static_cast<color_rgb>(0xE0E0E0) : API::bgcolor(window_));
|
return (!API::window_enabled(window_) ? static_cast<color_rgb>(0xE0E0E0) : API::bgcolor(window_));
|
||||||
@ -3423,7 +3413,7 @@ namespace nana{ namespace widgets
|
|||||||
|
|
||||||
//Parse highlight keywords
|
//Parse highlight keywords
|
||||||
keyword_parser parser;
|
keyword_parser parser;
|
||||||
parser.parse({ text_ptr, text_len }, impl_->keywords);
|
parser.parse(text_ptr, text_len, impl_->keywords);
|
||||||
|
|
||||||
const auto line_h_pixels = line_height();
|
const auto line_h_pixels = line_height();
|
||||||
|
|
||||||
|
|||||||
@ -524,14 +524,16 @@ namespace nana
|
|||||||
if((::nana::mouse_action::pressed == slider_state_.mouse_state) && (API::capture_window() == this->other_.wd))
|
if((::nana::mouse_action::pressed == slider_state_.mouse_state) && (API::capture_window() == this->other_.wd))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
auto state_changed = ((slider_state_.mouse_state != ::nana::mouse_action::normal)
|
||||||
|
|| (attr_.adorn_pos != attr_.slider.pos));
|
||||||
|
|
||||||
slider_state_.mouse_state = ::nana::mouse_action::normal;
|
slider_state_.mouse_state = ::nana::mouse_action::normal;
|
||||||
attr_.is_draw_adorn = false;
|
attr_.is_draw_adorn = false;
|
||||||
if(attr_.adorn_pos != attr_.slider.pos)
|
|
||||||
{
|
|
||||||
attr_.adorn_pos = attr_.slider.pos;
|
attr_.adorn_pos = attr_.slider.pos;
|
||||||
return true;
|
slider_state_.mouse_state = ::nana::mouse_action::normal;
|
||||||
}
|
|
||||||
return false;
|
return state_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -332,7 +332,6 @@ namespace paint
|
|||||||
dw->context = cdc;
|
dw->context = cdc;
|
||||||
dw->pixmap = bmp;
|
dw->pixmap = bmp;
|
||||||
::SetBkMode(cdc, TRANSPARENT);
|
::SetBkMode(cdc, TRANSPARENT);
|
||||||
dw->brush.set(cdc, dw->brush.Solid, 0xFFFFFF);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1075,13 +1074,16 @@ namespace paint
|
|||||||
{
|
{
|
||||||
if (!impl_->handle) return;
|
if (!impl_->handle) return;
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
impl_->handle->update_pen();
|
|
||||||
if (pos1 != pos2)
|
if (pos1 != pos2)
|
||||||
{
|
{
|
||||||
|
auto prv_pen = ::SelectObject(impl_->handle->context, ::CreatePen(PS_SOLID, 1, NANA_RGB(impl_->handle->get_color())));
|
||||||
|
|
||||||
::MoveToEx(impl_->handle->context, pos1.x, pos1.y, 0);
|
::MoveToEx(impl_->handle->context, pos1.x, pos1.y, 0);
|
||||||
::LineTo(impl_->handle->context, pos2.x, pos2.y);
|
::LineTo(impl_->handle->context, pos2.x, pos2.y);
|
||||||
|
|
||||||
|
::DeleteObject(::SelectObject(impl_->handle->context, prv_pen));
|
||||||
}
|
}
|
||||||
::SetPixel(impl_->handle->context, pos2.x, pos2.y, NANA_RGB(impl_->handle->pen.color));
|
::SetPixel(impl_->handle->context, pos2.x, pos2.y, NANA_RGB(impl_->handle->get_color()));
|
||||||
#elif defined(NANA_X11)
|
#elif defined(NANA_X11)
|
||||||
Display* disp = nana::detail::platform_spec::instance().open_display();
|
Display* disp = nana::detail::platform_spec::instance().open_display();
|
||||||
impl_->handle->update_color();
|
impl_->handle->update_color();
|
||||||
@ -1107,8 +1109,11 @@ namespace paint
|
|||||||
{
|
{
|
||||||
if (!impl_->handle) return;
|
if (!impl_->handle) return;
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
impl_->handle->update_pen();
|
auto prv_pen = ::SelectObject(impl_->handle->context, ::CreatePen(PS_SOLID, 1, NANA_RGB(impl_->handle->get_color())));
|
||||||
|
|
||||||
::LineTo(impl_->handle->context, pos.x, pos.y);
|
::LineTo(impl_->handle->context, pos.x, pos.y);
|
||||||
|
|
||||||
|
::DeleteObject(::SelectObject(impl_->handle->context, prv_pen));
|
||||||
#elif defined(NANA_X11)
|
#elif defined(NANA_X11)
|
||||||
Display* disp = nana::detail::platform_spec::instance().open_display();
|
Display* disp = nana::detail::platform_spec::instance().open_display();
|
||||||
impl_->handle->update_color();
|
impl_->handle->update_color();
|
||||||
@ -1136,9 +1141,14 @@ namespace paint
|
|||||||
if (r.width && r.height && impl_->handle && r.right() > 0 && r.bottom() > 0)
|
if (r.width && r.height && impl_->handle && r.right() > 0 && r.bottom() > 0)
|
||||||
{
|
{
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
|
|
||||||
|
auto brush = ::CreateSolidBrush(NANA_RGB(impl_->handle->get_color()));
|
||||||
|
|
||||||
::RECT native_r = { r.x, r.y, r.right(), r.bottom()};
|
::RECT native_r = { r.x, r.y, r.right(), r.bottom()};
|
||||||
impl_->handle->update_brush();
|
|
||||||
(solid ? ::FillRect : ::FrameRect)(impl_->handle->context, &native_r, impl_->handle->brush.handle);
|
(solid ? ::FillRect : ::FrameRect)(impl_->handle->context, &native_r, brush);
|
||||||
|
|
||||||
|
::DeleteObject(brush);
|
||||||
#elif defined(NANA_X11)
|
#elif defined(NANA_X11)
|
||||||
Display* disp = nana::detail::platform_spec::instance().open_display();
|
Display* disp = nana::detail::platform_spec::instance().open_display();
|
||||||
impl_->handle->update_color();
|
impl_->handle->update_color();
|
||||||
@ -1263,17 +1273,27 @@ namespace paint
|
|||||||
{
|
{
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
impl_->handle->set_color(clr);
|
impl_->handle->set_color(clr);
|
||||||
|
|
||||||
if (solid)
|
if (solid)
|
||||||
{
|
{
|
||||||
impl_->handle->update_pen();
|
auto prv_pen = ::SelectObject(impl_->handle->context, ::CreatePen(PS_SOLID, 1, NANA_RGB(impl_->handle->get_color())));
|
||||||
impl_->handle->brush.set(impl_->handle->context, impl_->handle->brush.Solid, solid_clr.px_color().value);
|
auto prv_brush = ::SelectObject(impl_->handle->context, ::CreateSolidBrush(NANA_RGB(solid_clr.px_color().value)));
|
||||||
|
|
||||||
::RoundRect(impl_->handle->context, r.x, r.y, r.right(), r.bottom(), static_cast<int>(radius_x * 2), static_cast<int>(radius_y * 2));
|
::RoundRect(impl_->handle->context, r.x, r.y, r.right(), r.bottom(), static_cast<int>(radius_x * 2), static_cast<int>(radius_y * 2));
|
||||||
|
|
||||||
|
::DeleteObject(::SelectObject(impl_->handle->context, prv_brush));
|
||||||
|
::DeleteObject(::SelectObject(impl_->handle->context, prv_pen));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
impl_->handle->update_brush();
|
auto brush = ::CreateSolidBrush(NANA_RGB(impl_->handle->get_color()));
|
||||||
impl_->handle->round_region.set(r, radius_x, radius_y);
|
|
||||||
::FrameRgn(impl_->handle->context, impl_->handle->round_region.handle, impl_->handle->brush.handle, 1, 1);
|
auto region = ::CreateRoundRectRgn(r.x, r.y, r.x + static_cast<int>(r.width) + 1, r.y + static_cast<int>(r.height) + 1, static_cast<int>(radius_x + 1), static_cast<int>(radius_y + 1));
|
||||||
|
|
||||||
|
::FrameRgn(impl_->handle->context, region, brush, 1, 1);
|
||||||
|
|
||||||
|
::DeleteObject(region);
|
||||||
|
::DeleteObject(brush);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (impl_->changed == false) impl_->changed = true;
|
if (impl_->changed == false) impl_->changed = true;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user