Merge branch 'feature-keyboard-accelerator' into develop
This commit is contained in:
commit
90b5f17169
@ -131,7 +131,7 @@ endif(APPLE)
|
|||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
list(APPEND NANA_LINKS -lX11)
|
list(APPEND NANA_LINKS -lX11)
|
||||||
find_package(Freetype)
|
include(FindFreetype)
|
||||||
if (FREETYPE_FOUND)
|
if (FREETYPE_FOUND)
|
||||||
include_directories( ${FREETYPE_INCLUDE_DIRS})
|
include_directories( ${FREETYPE_INCLUDE_DIRS})
|
||||||
list(APPEND NANA_LINKS -lXft)
|
list(APPEND NANA_LINKS -lXft)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Predefined Symbols for C++
|
* Predefined Symbols for C++
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2016-2017 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2016-2018 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
|
||||||
@ -171,9 +171,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Assume the std::thread is not implement on MinGW
|
//Assume the std::thread is not implemented on MinGW,
|
||||||
|
//unless it was compiled with POSIX threading support.
|
||||||
//But some toolchains may implement std::thread.
|
//But some toolchains may implement std::thread.
|
||||||
// it seems that MinGW 6.3 and 7.1 have std::thread
|
|
||||||
#ifdef NANA_MINGW
|
#ifdef NANA_MINGW
|
||||||
# ifndef STD_THREAD_NOT_SUPPORTED
|
# ifndef STD_THREAD_NOT_SUPPORTED
|
||||||
# define STD_THREAD_NOT_SUPPORTED
|
# define STD_THREAD_NOT_SUPPORTED
|
||||||
@ -221,8 +221,11 @@
|
|||||||
# if __has_include(<filesystem>)
|
# if __has_include(<filesystem>)
|
||||||
# undef STD_FILESYSTEM_NOT_SUPPORTED
|
# undef STD_FILESYSTEM_NOT_SUPPORTED
|
||||||
# endif
|
# endif
|
||||||
# if __has_include(<mutex>)
|
# if __has_include(<mutex>)
|
||||||
# undef STD_THREAD_NOT_SUPPORTED
|
# if !(defined(NANA_MINGW) && !defined(_GLIBCXX_HAS_GTHREADS))
|
||||||
|
//See the comment above regarding MinGW's threading support
|
||||||
|
# undef STD_THREAD_NOT_SUPPORTED
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A ISO C++ filesystem Implementation
|
* A ISO C++ filesystem 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-2018 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
|
||||||
@ -72,13 +72,12 @@ namespace boost
|
|||||||
// begin() and end() are only used by a range-based for statement in the context of
|
// begin() and end() are only used by a range-based for statement in the context of
|
||||||
// auto - thus the top-level const is stripped - so returning const is harmless and
|
// auto - thus the top-level const is stripped - so returning const is harmless and
|
||||||
// emphasizes begin() is just a pass through.
|
// emphasizes begin() is just a pass through.
|
||||||
inline
|
inline const directory_iterator& begin(const directory_iterator& iter) BOOST_NOEXCEPT
|
||||||
const directory_iterator& begin(const directory_iterator& iter) BOOST_NOEXCEPT
|
|
||||||
{
|
{
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
inline
|
|
||||||
directory_iterator end(const directory_iterator&) BOOST_NOEXCEPT
|
inline directory_iterator end(const directory_iterator&) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
return directory_iterator();
|
return directory_iterator();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 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
|
||||||
@ -18,7 +18,6 @@
|
|||||||
#include <nana/filesystem/filesystem.hpp>
|
#include <nana/filesystem/filesystem.hpp>
|
||||||
#include <nana/deploy.hpp>
|
#include <nana/deploy.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
namespace filesystem_ext
|
namespace filesystem_ext
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Basis Implementation
|
* Basis 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-2018 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
|
||||||
@ -30,6 +30,15 @@ namespace nana
|
|||||||
struct native_drawable_impl{};
|
struct native_drawable_impl{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct accel_key
|
||||||
|
{
|
||||||
|
char key;
|
||||||
|
bool case_sensitive{ false };
|
||||||
|
bool alt{ false };
|
||||||
|
bool ctrl{ false };
|
||||||
|
bool shift{ false };
|
||||||
|
};
|
||||||
|
|
||||||
enum class checkstate
|
enum class checkstate
|
||||||
{
|
{
|
||||||
unchecked, checked, partial
|
unchecked, checked, partial
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A Bedrock Implementation
|
* A Bedrock Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 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
|
||||||
@ -27,6 +27,7 @@ namespace detail
|
|||||||
struct basic_window;
|
struct basic_window;
|
||||||
class window_manager;
|
class window_manager;
|
||||||
|
|
||||||
|
struct window_platform_assoc;
|
||||||
|
|
||||||
/// @brief fundamental core component, it provides an abstraction to the OS platform and some basic functions.
|
/// @brief fundamental core component, it provides an abstraction to the OS platform and some basic functions.
|
||||||
class bedrock
|
class bedrock
|
||||||
@ -73,6 +74,11 @@ namespace detail
|
|||||||
|
|
||||||
//Closes the windows which are associated with the specified thread. If the given thread_id is 0, it closes all windows
|
//Closes the windows which are associated with the specified thread. If the given thread_id is 0, it closes all windows
|
||||||
void close_thread_window(unsigned thread_id);
|
void close_thread_window(unsigned thread_id);
|
||||||
|
|
||||||
|
public:
|
||||||
|
//Platform-dependent functions
|
||||||
|
static void delete_platform_assoc(window_platform_assoc*);
|
||||||
|
void keyboard_accelerator(native_window_type, const accel_key&, const std::function<void()>&);
|
||||||
public:
|
public:
|
||||||
void event_expose(core_window_t *, bool exposed);
|
void event_expose(core_window_t *, bool exposed);
|
||||||
void event_move(core_window_t*, int x, int y);
|
void event_move(core_window_t*, int x, int y);
|
||||||
|
|||||||
@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Effects Renderer
|
||||||
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
|
* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*
|
||||||
|
* @file: nana/gui/detail/effects_renderer.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
|
#ifndef NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
|
||||||
#define NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
|
#define NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
|
||||||
#include <nana/gui/effects.hpp>
|
#include <nana/gui/effects.hpp>
|
||||||
@ -76,7 +88,7 @@ namespace nana{
|
|||||||
nana::rectangle r;
|
nana::rectangle r;
|
||||||
for(auto & action : nimbus)
|
for(auto & action : nimbus)
|
||||||
{
|
{
|
||||||
if(_m_edge_nimbus(focused, action.window) && window_layer::read_visual_rectangle(action.window, r))
|
if(_m_edge_nimbus(action.window, focused) && window_layer::read_visual_rectangle(action.window, r))
|
||||||
{
|
{
|
||||||
if (action.window == wd)
|
if (action.window == wd)
|
||||||
{
|
{
|
||||||
@ -140,12 +152,17 @@ namespace nana{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
static bool _m_edge_nimbus(core_window_t * focused_wd, core_window_t * wd)
|
/// Determines whether the effect will be rendered for the given window.
|
||||||
|
static bool _m_edge_nimbus(core_window_t * const wd, core_window_t * const focused_wd)
|
||||||
{
|
{
|
||||||
if((focused_wd == wd) && (static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::active)))
|
// Don't render the effect if the window is disabled.
|
||||||
return true;
|
if (wd->flags.enabled)
|
||||||
else if((static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::over)) && (wd->flags.action == mouse_action::hovered))
|
{
|
||||||
return true;
|
if ((focused_wd == wd) && (static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::active)))
|
||||||
|
return true;
|
||||||
|
else if ((static_cast<unsigned>(wd->effect.edge_nimbus) & static_cast<unsigned>(effects::edge_nimbus::over)) && (wd->flags.action == mouse_action::hovered))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Definition of General Events
|
* Definition of General Events
|
||||||
* 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-2018 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
|
||||||
@ -460,8 +460,9 @@ namespace nana
|
|||||||
::nana::window window_handle; ///< A handle to the event window
|
::nana::window window_handle; ///< A handle to the event window
|
||||||
mutable wchar_t key; ///< the key corresponding to the key pressed
|
mutable wchar_t key; ///< the key corresponding to the key pressed
|
||||||
mutable bool ignore; ///< this member is only available for key_char event, set 'true' to ignore the input.
|
mutable bool ignore; ///< this member is only available for key_char event, set 'true' to ignore the input.
|
||||||
bool ctrl; ///< keyboard Ctrl is pressed?
|
bool alt; ///< it is set to indicate the modifier key Alt just prior to the event.
|
||||||
bool shift; ///< keyboard Shift is pressed
|
bool ctrl; ///< it is set to indicate the modifier key Ctrl just prior to the event.
|
||||||
|
bool shift; ///< it is set to indicate the modifier key Shift just prior to the event.
|
||||||
};
|
};
|
||||||
|
|
||||||
struct arg_move : public event_arg
|
struct arg_move : public event_arg
|
||||||
|
|||||||
@ -301,6 +301,8 @@ namespace API
|
|||||||
void window_size(window, const size&);
|
void window_size(window, const size&);
|
||||||
size window_outline_size(window);
|
size window_outline_size(window);
|
||||||
void window_outline_size(window, const size&);
|
void window_outline_size(window, const size&);
|
||||||
|
|
||||||
|
nana::optional<rectangle> window_rectangle(window);
|
||||||
bool get_window_rectangle(window, rectangle&);
|
bool get_window_rectangle(window, rectangle&);
|
||||||
bool track_window_size(window, const size&, bool true_for_max); ///< Sets the minimum or maximum tracking size of a window.
|
bool track_window_size(window, const size&, bool true_for_max); ///< Sets the minimum or maximum tracking size of a window.
|
||||||
void window_enabled(window, bool);
|
void window_enabled(window, bool);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A Form Implementation
|
* A Form 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-2018 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
|
||||||
@ -68,6 +68,8 @@ namespace nana
|
|||||||
|
|
||||||
void modality() const;
|
void modality() const;
|
||||||
void wait_for_this();
|
void wait_for_this();
|
||||||
|
|
||||||
|
void keyboard_accelerator(const accel_key&, const std::function<void()>& fn);
|
||||||
};
|
};
|
||||||
|
|
||||||
class nested_form
|
class nested_form
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A List Box Implementation
|
* A List Box Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 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
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A Scroll Implementation
|
* A Scroll 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-2018 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
|
||||||
@ -147,7 +147,7 @@ namespace nana
|
|||||||
|
|
||||||
void step(size_type s)
|
void step(size_type s)
|
||||||
{
|
{
|
||||||
metrics_.step = s;
|
metrics_.step = (s ? s : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool make_step(bool forward, unsigned multiple)
|
bool make_step(bool forward, unsigned multiple)
|
||||||
@ -398,7 +398,7 @@ namespace nana
|
|||||||
/// \brief The construct that creates a widget.
|
/// \brief The construct that creates a widget.
|
||||||
/// @param wd A handle to the parent window of the widget being created.
|
/// @param wd A handle to the parent window of the widget being created.
|
||||||
/// @param visible specify the visibility after creation.
|
/// @param visible specify the visibility after creation.
|
||||||
scroll(window wd, bool visible)
|
scroll(window wd, bool visible = true)
|
||||||
{
|
{
|
||||||
this->create(wd, rectangle(), visible); // add a widget scheme? and take some colors from these wd?
|
this->create(wd, rectangle(), visible); // add a widget scheme? and take some colors from these wd?
|
||||||
}
|
}
|
||||||
@ -501,7 +501,8 @@ namespace nana
|
|||||||
/// @return true if the vlaue is changed.
|
/// @return true if the vlaue is changed.
|
||||||
bool make_page_scroll(bool forward)
|
bool make_page_scroll(bool forward)
|
||||||
{
|
{
|
||||||
return this->make_step(forward, static_cast<unsigned>(range() - 1));
|
auto const count = range() / step();
|
||||||
|
return this->make_step(forward, (count > 2 ? count - 1 : 1));
|
||||||
}
|
}
|
||||||
};//end class scroll
|
};//end class scroll
|
||||||
}//end namespace nana
|
}//end namespace nana
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A Tabbar implementation
|
* A Tabbar 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-2018 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
|
||||||
@ -42,9 +42,8 @@ namespace nana
|
|||||||
: arg_tabbar<T>({wdg, v})
|
: arg_tabbar<T>({wdg, v})
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool remove = true; ///< determines whether to remove the item
|
mutable bool remove = true; ///< determines whether to remove the item
|
||||||
bool close_attach_window = true; ///< determines whether to close the attached window. It is ignored if remove is false
|
mutable bool close_attach_window = true; ///< determines whether to close the attached window. It is ignored if remove is false
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace drawerbase
|
namespace drawerbase
|
||||||
@ -293,7 +292,7 @@ namespace nana
|
|||||||
if (pos > length())
|
if (pos > length())
|
||||||
throw std::out_of_range("tabbar::insert invalid position");
|
throw std::out_of_range("tabbar::insert invalid position");
|
||||||
|
|
||||||
this->get_drawer_trigger().insert(pos, to_nstring(text), std::move(value));
|
this->get_drawer_trigger().insert(pos, to_nstring(std::move(text)), std::move(value));
|
||||||
API::update_window(*this);
|
API::update_window(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* A Bedrock Implementation
|
* A Bedrock Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 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
|
||||||
@ -15,10 +15,10 @@
|
|||||||
#include <nana/gui/detail/bedrock_pi_data.hpp>
|
#include <nana/gui/detail/bedrock_pi_data.hpp>
|
||||||
#include <nana/gui/detail/event_code.hpp>
|
#include <nana/gui/detail/event_code.hpp>
|
||||||
#include <nana/system/platform.hpp>
|
#include <nana/system/platform.hpp>
|
||||||
#include <nana/gui/detail/inner_fwd_implement.hpp>
|
|
||||||
#include <nana/gui/detail/native_window_interface.hpp>
|
#include <nana/gui/detail/native_window_interface.hpp>
|
||||||
#include <nana/gui/layout_utility.hpp>
|
#include <nana/gui/layout_utility.hpp>
|
||||||
#include <nana/gui/detail/element_store.hpp>
|
#include <nana/gui/detail/element_store.hpp>
|
||||||
|
#include "inner_fwd_implement.hpp"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -104,6 +104,42 @@ namespace detail
|
|||||||
void window_proc_for_packet(Display *, nana::detail::msg_packet_tag&);
|
void window_proc_for_packet(Display *, nana::detail::msg_packet_tag&);
|
||||||
void window_proc_for_xevent(Display*, XEvent&);
|
void window_proc_for_xevent(Display*, XEvent&);
|
||||||
|
|
||||||
|
class accel_key_comparer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool operator()(const accel_key& a, const accel_key& b) const
|
||||||
|
{
|
||||||
|
auto va = a.case_sensitive ? a.key : std::tolower(a.key);
|
||||||
|
auto vb = b.case_sensitive ? b.key : std::tolower(b.key);
|
||||||
|
|
||||||
|
if(va < vb)
|
||||||
|
return true;
|
||||||
|
else if(va > vb)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (a.case_sensitive != b.case_sensitive)
|
||||||
|
return b.case_sensitive;
|
||||||
|
|
||||||
|
if (a.alt != b.alt)
|
||||||
|
return b.alt;
|
||||||
|
|
||||||
|
if (a.ctrl != b.ctrl)
|
||||||
|
return b.ctrl;
|
||||||
|
|
||||||
|
return ((a.shift != b.shift) && b.shift);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct accel_key_value
|
||||||
|
{
|
||||||
|
std::function<void()> command;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct window_platform_assoc
|
||||||
|
{
|
||||||
|
std::map<accel_key, accel_key_value, accel_key_comparer> accel_commands;
|
||||||
|
};
|
||||||
|
|
||||||
//class bedrock defines a static object itself to implement a static singleton
|
//class bedrock defines a static object itself to implement a static singleton
|
||||||
//here is the definition of this object
|
//here is the definition of this object
|
||||||
bedrock bedrock::bedrock_object;
|
bedrock bedrock::bedrock_object;
|
||||||
@ -218,10 +254,28 @@ namespace detail
|
|||||||
{
|
{
|
||||||
XKeyEvent xkey;
|
XKeyEvent xkey;
|
||||||
nana::detail::platform_spec::instance().read_keystate(xkey);
|
nana::detail::platform_spec::instance().read_keystate(xkey);
|
||||||
|
arg.alt = (xkey.state & Mod1Mask);
|
||||||
arg.ctrl = (xkey.state & ControlMask);
|
arg.ctrl = (xkey.state & ControlMask);
|
||||||
arg.shift = (xkey.state & ShiftMask);
|
arg.shift = (xkey.state & ShiftMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bedrock::delete_platform_assoc(window_platform_assoc* passoc)
|
||||||
|
{
|
||||||
|
delete passoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bedrock::keyboard_accelerator(native_window_type wd, const accel_key& ackey, const std::function<void()>& fn)
|
||||||
|
{
|
||||||
|
auto misc = wd_manager().root_runtime(wd);
|
||||||
|
if (nullptr == misc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!misc->wpassoc)
|
||||||
|
misc->wpassoc = new window_platform_assoc;
|
||||||
|
|
||||||
|
misc->wpassoc->accel_commands[ackey].command = fn;
|
||||||
|
}
|
||||||
|
|
||||||
element_store& bedrock::get_element_store() const
|
element_store& bedrock::get_element_store() const
|
||||||
{
|
{
|
||||||
return impl_->estore;
|
return impl_->estore;
|
||||||
@ -490,6 +544,34 @@ namespace detail
|
|||||||
return wchar_t(keysym);
|
return wchar_t(keysym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool translate_keyboard_accelerator(root_misc* misc, char os_code, const arg_keyboard& modifiers)
|
||||||
|
{
|
||||||
|
if(!misc->wpassoc)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto lower_oc = std::tolower(os_code);
|
||||||
|
|
||||||
|
std::function<void()> command;
|
||||||
|
|
||||||
|
for(auto & accel : misc->wpassoc->accel_commands)
|
||||||
|
{
|
||||||
|
if(accel.first.key != (accel.first.case_sensitive ? os_code : lower_oc))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(accel.first.alt == modifiers.alt && accel.first.ctrl == modifiers.ctrl && accel.first.shift == modifiers.shift)
|
||||||
|
{
|
||||||
|
command = accel.second.command;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!command)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
command();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void window_proc_for_xevent(Display* /*display*/, XEvent& xevent)
|
void window_proc_for_xevent(Display* /*display*/, XEvent& xevent)
|
||||||
{
|
{
|
||||||
typedef detail::bedrock::core_window_t core_window_t;
|
typedef detail::bedrock::core_window_t core_window_t;
|
||||||
@ -849,6 +931,9 @@ namespace detail
|
|||||||
|
|
||||||
if(msgwnd)
|
if(msgwnd)
|
||||||
{
|
{
|
||||||
|
arg_keyboard modifiers_status;
|
||||||
|
brock.get_key_state(modifiers_status);
|
||||||
|
|
||||||
KeySym keysym;
|
KeySym keysym;
|
||||||
Status status;
|
Status status;
|
||||||
char fixbuf[33];
|
char fixbuf[33];
|
||||||
@ -883,16 +968,20 @@ namespace detail
|
|||||||
|
|
||||||
keybuf[len] = 0;
|
keybuf[len] = 0;
|
||||||
wchar_t os_code = 0;
|
wchar_t os_code = 0;
|
||||||
|
bool accel_translated = false;
|
||||||
|
|
||||||
switch(status)
|
switch(status)
|
||||||
{
|
{
|
||||||
case XLookupKeySym:
|
case XLookupKeySym:
|
||||||
case XLookupBoth:
|
case XLookupBoth:
|
||||||
os_code = os_code_from_keysym(keysym);
|
os_code = os_code_from_keysym(keysym);
|
||||||
|
accel_translated = translate_keyboard_accelerator(root_runtime, os_code, modifiers_status);
|
||||||
|
if(accel_translated)
|
||||||
|
break;
|
||||||
|
|
||||||
if(os_code == keyboard::tab && (false == (msgwnd->flags.tab & detail::tab_type::eating))) //Tab
|
if(os_code == keyboard::tab && (false == (msgwnd->flags.tab & detail::tab_type::eating))) //Tab
|
||||||
{
|
{
|
||||||
arg_keyboard argkey;
|
auto tstop_wd = wd_manager.tabstop(msgwnd, !modifiers_status.shift);
|
||||||
brock.get_key_state(argkey);
|
|
||||||
auto tstop_wd = wd_manager.tabstop(msgwnd, !argkey.shift);
|
|
||||||
if (tstop_wd)
|
if (tstop_wd)
|
||||||
{
|
{
|
||||||
root_runtime->condition.ignore_tab = true;
|
root_runtime->condition.ignore_tab = true;
|
||||||
@ -907,9 +996,9 @@ namespace detail
|
|||||||
if((nullptr == pressed_wd) && (nullptr == pressed_wd_space))
|
if((nullptr == pressed_wd) && (nullptr == pressed_wd_space))
|
||||||
{
|
{
|
||||||
arg_mouse arg;
|
arg_mouse arg;
|
||||||
arg.alt = false;
|
arg.alt = modifiers_status.alt;
|
||||||
arg.button = ::nana::mouse::left_button;
|
arg.button = ::nana::mouse::left_button;
|
||||||
arg.ctrl = false;
|
arg.ctrl = modifiers_status.ctrl;
|
||||||
arg.evt_code = event_code::mouse_down;
|
arg.evt_code = event_code::mouse_down;
|
||||||
arg.left_button = true;
|
arg.left_button = true;
|
||||||
arg.mid_button = false;
|
arg.mid_button = false;
|
||||||
@ -955,11 +1044,10 @@ namespace detail
|
|||||||
if(keyboard::os_ctrl == os_code)
|
if(keyboard::os_ctrl == os_code)
|
||||||
context.is_ctrl_pressed = true;
|
context.is_ctrl_pressed = true;
|
||||||
|
|
||||||
arg_keyboard arg;
|
arg_keyboard arg = modifiers_status;
|
||||||
arg.ignore = false;
|
arg.ignore = false;
|
||||||
arg.key = os_code;
|
arg.key = os_code;
|
||||||
arg.evt_code = event_code::key_press;
|
arg.evt_code = event_code::key_press;
|
||||||
brock.get_key_state(arg);
|
|
||||||
arg.window_handle = reinterpret_cast<window>(msgwnd);
|
arg.window_handle = reinterpret_cast<window>(msgwnd);
|
||||||
|
|
||||||
brock.emit(event_code::key_press, msgwnd, arg, true, &context);
|
brock.emit(event_code::key_press, msgwnd, arg, true, &context);
|
||||||
@ -988,7 +1076,7 @@ namespace detail
|
|||||||
|
|
||||||
for(int i = 0; i < len; ++i)
|
for(int i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
arg_keyboard arg;
|
arg_keyboard arg = modifiers_status;
|
||||||
arg.ignore = false;
|
arg.ignore = false;
|
||||||
arg.key = charbuf[i];
|
arg.key = charbuf[i];
|
||||||
|
|
||||||
@ -1011,7 +1099,6 @@ namespace detail
|
|||||||
}
|
}
|
||||||
arg.evt_code = event_code::key_char;
|
arg.evt_code = event_code::key_char;
|
||||||
arg.window_handle = reinterpret_cast<window>(msgwnd);
|
arg.window_handle = reinterpret_cast<window>(msgwnd);
|
||||||
brock.get_key_state(arg);
|
|
||||||
msgwnd->annex.events_ptr->key_char.emit(arg, reinterpret_cast<window>(msgwnd));
|
msgwnd->annex.events_ptr->key_char.emit(arg, reinterpret_cast<window>(msgwnd));
|
||||||
if(arg.ignore == false && wd_manager.available(msgwnd))
|
if(arg.ignore == false && wd_manager.available(msgwnd))
|
||||||
draw_invoker(&drawer::key_char, msgwnd, arg, &context);
|
draw_invoker(&drawer::key_char, msgwnd, arg, &context);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A Bedrock Implementation
|
* A Bedrock Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 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,11 +20,11 @@
|
|||||||
#include <nana/system/platform.hpp>
|
#include <nana/system/platform.hpp>
|
||||||
#include <nana/system/timepiece.hpp>
|
#include <nana/system/timepiece.hpp>
|
||||||
#include <nana/gui.hpp>
|
#include <nana/gui.hpp>
|
||||||
#include <nana/gui/detail/inner_fwd_implement.hpp>
|
|
||||||
#include <nana/gui/detail/native_window_interface.hpp>
|
#include <nana/gui/detail/native_window_interface.hpp>
|
||||||
#include <nana/gui/layout_utility.hpp>
|
#include <nana/gui/layout_utility.hpp>
|
||||||
#include <nana/gui/detail/element_store.hpp>
|
#include <nana/gui/detail/element_store.hpp>
|
||||||
#include <nana/gui/detail/color_schemes.hpp>
|
#include <nana/gui/detail/color_schemes.hpp>
|
||||||
|
#include "inner_fwd_implement.hpp"
|
||||||
|
|
||||||
#include <iostream> //use std::cerr
|
#include <iostream> //use std::cerr
|
||||||
|
|
||||||
@ -182,6 +182,12 @@ namespace detail
|
|||||||
}cache;
|
}cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct window_platform_assoc
|
||||||
|
{
|
||||||
|
HACCEL accel{ nullptr }; ///< A handle to a Windows keyboard accelerator object.
|
||||||
|
std::map<int, std::function<void()>> accel_commands;
|
||||||
|
};
|
||||||
|
|
||||||
//class bedrock defines a static object itself to implement a static singleton
|
//class bedrock defines a static object itself to implement a static singleton
|
||||||
//here is the definition of this object
|
//here is the definition of this object
|
||||||
bedrock bedrock::bedrock_object;
|
bedrock bedrock::bedrock_object;
|
||||||
@ -345,6 +351,25 @@ namespace detail
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void process_msg(bedrock* brock, MSG& msg)
|
||||||
|
{
|
||||||
|
if (WM_KEYFIRST <= msg.message && msg.message <= WM_KEYLAST)
|
||||||
|
{
|
||||||
|
auto misc = brock->wd_manager().root_runtime(reinterpret_cast<native_window_type>(msg.hwnd));
|
||||||
|
if (misc && misc->wpassoc && misc->wpassoc->accel)
|
||||||
|
{
|
||||||
|
if (::TranslateAccelerator(msg.hwnd, misc->wpassoc->accel, &msg))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto menu_wd = brock->get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
|
||||||
|
if (menu_wd) interior_helper_for_menu(msg, menu_wd);
|
||||||
|
|
||||||
|
::TranslateMessage(&msg);
|
||||||
|
::DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
void bedrock::pump_event(window condition_wd, bool is_modal)
|
void bedrock::pump_event(window condition_wd, bool is_modal)
|
||||||
{
|
{
|
||||||
const unsigned tid = ::GetCurrentThreadId();
|
const unsigned tid = ::GetCurrentThreadId();
|
||||||
@ -383,11 +408,15 @@ namespace detail
|
|||||||
if (msg.message == WM_QUIT) break;
|
if (msg.message == WM_QUIT) break;
|
||||||
if ((WM_KEYFIRST <= msg.message && msg.message <= WM_KEYLAST) || !::IsDialogMessage(native_handle, &msg))
|
if ((WM_KEYFIRST <= msg.message && msg.message <= WM_KEYLAST) || !::IsDialogMessage(native_handle, &msg))
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
|
auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
|
||||||
if (menu_wd) interior_helper_for_menu(msg, menu_wd);
|
if (menu_wd) interior_helper_for_menu(msg, menu_wd);
|
||||||
|
|
||||||
::TranslateMessage(&msg);
|
::TranslateMessage(&msg); //deprecated
|
||||||
::DispatchMessage(&msg);
|
::DispatchMessage(&msg);
|
||||||
|
#else
|
||||||
|
process_msg(this, msg);
|
||||||
|
#endif
|
||||||
|
|
||||||
wd_manager().remove_trash_handle(tid);
|
wd_manager().remove_trash_handle(tid);
|
||||||
}
|
}
|
||||||
@ -400,11 +429,15 @@ namespace detail
|
|||||||
{
|
{
|
||||||
if (-1 != ::GetMessage(&msg, 0, 0, 0))
|
if (-1 != ::GetMessage(&msg, 0, 0, 0))
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
|
auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
|
||||||
if (menu_wd) interior_helper_for_menu(msg, menu_wd);
|
if (menu_wd) interior_helper_for_menu(msg, menu_wd);
|
||||||
|
|
||||||
::TranslateMessage(&msg);
|
::TranslateMessage(&msg);
|
||||||
::DispatchMessage(&msg);
|
::DispatchMessage(&msg);
|
||||||
|
#else
|
||||||
|
process_msg(this, msg);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
wd_manager().call_safe_place(tid);
|
wd_manager().call_safe_place(tid);
|
||||||
@ -420,11 +453,15 @@ namespace detail
|
|||||||
{
|
{
|
||||||
if(-1 != ::GetMessage(&msg, 0, 0, 0))
|
if(-1 != ::GetMessage(&msg, 0, 0, 0))
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
|
auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
|
||||||
if(menu_wd) interior_helper_for_menu(msg, menu_wd);
|
if(menu_wd) interior_helper_for_menu(msg, menu_wd);
|
||||||
|
|
||||||
::TranslateMessage(&msg);
|
::TranslateMessage(&msg);
|
||||||
::DispatchMessage(&msg);
|
::DispatchMessage(&msg);
|
||||||
|
#else
|
||||||
|
process_msg(this, msg);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
wd_manager().call_safe_place(tid);
|
wd_manager().call_safe_place(tid);
|
||||||
@ -635,6 +672,7 @@ namespace detail
|
|||||||
|
|
||||||
switch(msg)
|
switch(msg)
|
||||||
{
|
{
|
||||||
|
case WM_COMMAND:
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
case WM_SHOWWINDOW:
|
case WM_SHOWWINDOW:
|
||||||
case WM_SIZING:
|
case WM_SIZING:
|
||||||
@ -786,6 +824,17 @@ namespace detail
|
|||||||
|
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
|
case WM_COMMAND:
|
||||||
|
if ((1 == HIWORD(wParam)) && root_runtime->wpassoc)
|
||||||
|
{
|
||||||
|
auto i = root_runtime->wpassoc->accel_commands.find(LOWORD(wParam));
|
||||||
|
if (i != root_runtime->wpassoc->accel_commands.end())
|
||||||
|
{
|
||||||
|
auto fn = i->second;
|
||||||
|
fn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case WM_IME_STARTCOMPOSITION:
|
case WM_IME_STARTCOMPOSITION:
|
||||||
if (msgwnd->other.attribute.root->ime_enabled)
|
if (msgwnd->other.attribute.root->ime_enabled)
|
||||||
{
|
{
|
||||||
@ -1578,10 +1627,58 @@ namespace detail
|
|||||||
|
|
||||||
void bedrock::get_key_state(arg_keyboard& kb)
|
void bedrock::get_key_state(arg_keyboard& kb)
|
||||||
{
|
{
|
||||||
|
kb.alt = (0 != (::GetKeyState(VK_MENU) & 0x80));
|
||||||
kb.ctrl = (0 != (::GetKeyState(VK_CONTROL) & 0x80));
|
kb.ctrl = (0 != (::GetKeyState(VK_CONTROL) & 0x80));
|
||||||
kb.shift = (0 != (::GetKeyState(VK_SHIFT) & 0x80));
|
kb.shift = (0 != (::GetKeyState(VK_SHIFT) & 0x80));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bedrock::delete_platform_assoc(window_platform_assoc* passoc)
|
||||||
|
{
|
||||||
|
delete passoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Generates an identitifer for an accel key.
|
||||||
|
std::pair<int, WORD> id_accel_key(const accel_key& key)
|
||||||
|
{
|
||||||
|
std::pair<int, WORD> ret;
|
||||||
|
|
||||||
|
//Use virt-key for non-case sensitive
|
||||||
|
if (!key.case_sensitive)
|
||||||
|
ret.second = static_cast<WORD>(std::tolower(key.key) - 'a' + 0x41);
|
||||||
|
|
||||||
|
ret.first = ret.second | int(key.case_sensitive ? (1 << 8) : 0) | int(key.alt ? (1 << 9) : 0) | int(key.ctrl ? (1 << 10) : 0) | int(key.shift ? (1 << 11) : 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bedrock::keyboard_accelerator(native_window_type wd, const accel_key& key, const std::function<void()>& fn)
|
||||||
|
{
|
||||||
|
auto misc = wd_manager().root_runtime(wd);
|
||||||
|
if (nullptr == misc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!misc->wpassoc)
|
||||||
|
misc->wpassoc = new window_platform_assoc;
|
||||||
|
|
||||||
|
auto idkey = id_accel_key(key);
|
||||||
|
|
||||||
|
misc->wpassoc->accel_commands[idkey.first] = fn;
|
||||||
|
|
||||||
|
auto accel_size = ::CopyAcceleratorTable(misc->wpassoc->accel, nullptr, 0);
|
||||||
|
|
||||||
|
std::unique_ptr<ACCEL[]> accels(new ACCEL[accel_size + 1]);
|
||||||
|
|
||||||
|
if (accel_size)
|
||||||
|
::CopyAcceleratorTable(misc->wpassoc->accel, accels.get(), accel_size);
|
||||||
|
|
||||||
|
auto p = accels.get() + accel_size;
|
||||||
|
p->cmd = idkey.first;
|
||||||
|
p->fVirt = (key.case_sensitive ? 0 : FVIRTKEY) | (key.alt ? FALT : 0) | (key.ctrl ? FCONTROL : 0) | (key.shift ? FSHIFT : 0);
|
||||||
|
p->key = idkey.second;
|
||||||
|
|
||||||
|
::DestroyAcceleratorTable(misc->wpassoc->accel);
|
||||||
|
misc->wpassoc->accel = ::CreateAcceleratorTable(accels.get(), accel_size + 1);
|
||||||
|
}
|
||||||
|
|
||||||
element_store& bedrock::get_element_store() const
|
element_store& bedrock::get_element_store() const
|
||||||
{
|
{
|
||||||
return impl_->estore;
|
return impl_->estore;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Implementations of Inner Forward Declaration
|
* Implementations of Inner Forward Declaration
|
||||||
* 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-2018 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
|
||||||
@ -15,9 +15,9 @@
|
|||||||
#define NANA_GUI_INNER_FWD_IMPLEMENT_HPP
|
#define NANA_GUI_INNER_FWD_IMPLEMENT_HPP
|
||||||
|
|
||||||
#include <nana/push_ignore_diagnostic>
|
#include <nana/push_ignore_diagnostic>
|
||||||
#include "inner_fwd.hpp"
|
#include <nana/gui/detail/inner_fwd.hpp>
|
||||||
#include "basic_window.hpp"
|
#include <nana/gui/detail/basic_window.hpp>
|
||||||
#include "../../paint/graphics.hpp"
|
#include <nana/paint/graphics.hpp>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@ -54,10 +54,13 @@ namespace nana{
|
|||||||
implementation * impl_;
|
implementation * impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct window_platform_assoc;
|
||||||
|
|
||||||
struct root_misc
|
struct root_misc
|
||||||
{
|
{
|
||||||
basic_window * window;
|
basic_window * window;
|
||||||
|
window_platform_assoc * wpassoc{ nullptr };
|
||||||
|
|
||||||
nana::paint::graphics root_graph;
|
nana::paint::graphics root_graph;
|
||||||
shortkey_container shortkeys;
|
shortkey_container shortkeys;
|
||||||
|
|
||||||
@ -71,6 +74,10 @@ namespace nana{
|
|||||||
|
|
||||||
root_misc(root_misc&&);
|
root_misc(root_misc&&);
|
||||||
root_misc(basic_window * wd, unsigned width, unsigned height);
|
root_misc(basic_window * wd, unsigned width, unsigned height);
|
||||||
|
~root_misc();
|
||||||
|
private:
|
||||||
|
root_misc(const root_misc&) = delete;
|
||||||
|
root_misc& operator=(const root_misc&) = delete;
|
||||||
};//end struct root_misc
|
};//end struct root_misc
|
||||||
|
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Window Layout Implementation
|
* Window Layout Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 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
|
||||||
@ -106,43 +106,46 @@ namespace nana
|
|||||||
|
|
||||||
visual = rectangle{ wd->pos_root, wd->dimension };
|
visual = rectangle{ wd->pos_root, wd->dimension };
|
||||||
|
|
||||||
if (wd->root_widget != wd)
|
if (category::flags::root != wd->other.category)
|
||||||
{
|
{
|
||||||
//Test if the root widget is overlapped the specified widget
|
//Test if the root widget is overlapped the specified widget
|
||||||
//the pos of root widget is (0, 0)
|
//the pos of root widget is (0, 0)
|
||||||
if (overlapped(visual, rectangle{ wd->root_widget->pos_owner, wd->root_widget->dimension }) == false)
|
if (overlapped(visual, rectangle{ wd->root_widget->pos_owner, wd->root_widget->dimension }) == false)
|
||||||
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
|
if (category::flags::root == parent->other.category)
|
||||||
rectangle vrt_parent{parent->pos_root, parent->dimension};
|
|
||||||
|
|
||||||
point pos_root;
|
|
||||||
while (parent->parent)
|
|
||||||
{
|
{
|
||||||
pos_root -= native_interface::window_position(parent->root);
|
wd = parent;
|
||||||
|
break;
|
||||||
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))
|
if (!overlap(rectangle{ parent->pos_root, parent->dimension }, visual, visual))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!overlap(rectangle{ parent->pos_root, parent->dimension }, visual, visual))
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
//Now, wd actually is the root widget of original parameter wd
|
||||||
|
if (nullptr == wd->parent)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto parent_rw = wd->parent->root_widget;
|
||||||
|
//visual rectangle of wd's parent
|
||||||
|
rectangle vrt_parent{ parent_rw->pos_root, parent_rw->dimension };
|
||||||
|
|
||||||
|
point pos_root;
|
||||||
|
while (parent_rw->parent)
|
||||||
|
{
|
||||||
|
pos_root -= native_interface::window_position(parent_rw->root);
|
||||||
|
|
||||||
|
if (!overlap(rectangle{ pos_root, parent_rw->parent->root_widget->dimension }, vrt_parent, vrt_parent))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
parent_rw = parent_rw->parent->root_widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
return overlap(vrt_parent, visual, visual);
|
||||||
}
|
}
|
||||||
|
|
||||||
//read_overlaps
|
//read_overlaps
|
||||||
@ -386,6 +389,13 @@ namespace nana
|
|||||||
nana::rectangle r_of_sigwd(sigwd->pos_root, sigwd->dimension);
|
nana::rectangle r_of_sigwd(sigwd->pos_root, sigwd->dimension);
|
||||||
for (auto wd : data_sect.effects_bground_windows)
|
for (auto wd : data_sect.effects_bground_windows)
|
||||||
{
|
{
|
||||||
|
//Don't notify the window if both native root windows are not same(e.g. wd and sigwd have
|
||||||
|
//a some parent). Otherwise, _m_paint_glass_window() recursively paints sigwd to make stack overflow.
|
||||||
|
//On the other hand, a nested root window is always floating on its parent's child widgets, it's unnecessary to
|
||||||
|
//notify the wd if they haven't a same native root window.
|
||||||
|
if (sigwd->root != wd->root)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (wd == sigwd || !wd->displayed() ||
|
if (wd == sigwd || !wd->displayed() ||
|
||||||
(false == overlapped(nana::rectangle{ wd->pos_root, wd->dimension }, r_of_sigwd)))
|
(false == overlapped(nana::rectangle{ wd->pos_root, wd->dimension }, r_of_sigwd)))
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Window Manager Implementation
|
* Window Manager Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 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
|
||||||
@ -16,11 +16,11 @@
|
|||||||
#include <nana/gui/detail/events_operation.hpp>
|
#include <nana/gui/detail/events_operation.hpp>
|
||||||
#include <nana/gui/detail/window_manager.hpp>
|
#include <nana/gui/detail/window_manager.hpp>
|
||||||
#include <nana/gui/detail/window_layout.hpp>
|
#include <nana/gui/detail/window_layout.hpp>
|
||||||
#include "window_register.hpp"
|
|
||||||
#include <nana/gui/detail/native_window_interface.hpp>
|
#include <nana/gui/detail/native_window_interface.hpp>
|
||||||
#include <nana/gui/detail/inner_fwd_implement.hpp>
|
|
||||||
#include <nana/gui/layout_utility.hpp>
|
#include <nana/gui/layout_utility.hpp>
|
||||||
#include <nana/gui/detail/effects_renderer.hpp>
|
#include <nana/gui/detail/effects_renderer.hpp>
|
||||||
|
#include "window_register.hpp"
|
||||||
|
#include "inner_fwd_implement.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -140,10 +140,12 @@ namespace nana
|
|||||||
//struct root_misc
|
//struct root_misc
|
||||||
root_misc::root_misc(root_misc&& other):
|
root_misc::root_misc(root_misc&& other):
|
||||||
window(other.window),
|
window(other.window),
|
||||||
|
wpassoc(other.wpassoc),
|
||||||
root_graph(std::move(other.root_graph)),
|
root_graph(std::move(other.root_graph)),
|
||||||
shortkeys(std::move(other.shortkeys)),
|
shortkeys(std::move(other.shortkeys)),
|
||||||
condition(std::move(other.condition))
|
condition(std::move(other.condition))
|
||||||
{
|
{
|
||||||
|
other.wpassoc = nullptr; //moved-from
|
||||||
}
|
}
|
||||||
|
|
||||||
root_misc::root_misc(basic_window * wd, unsigned width, unsigned height)
|
root_misc::root_misc(basic_window * wd, unsigned width, unsigned height)
|
||||||
@ -155,6 +157,11 @@ namespace nana
|
|||||||
condition.pressed_by_space = nullptr;
|
condition.pressed_by_space = nullptr;
|
||||||
condition.hovered = nullptr;
|
condition.hovered = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
root_misc::~root_misc()
|
||||||
|
{
|
||||||
|
bedrock::delete_platform_assoc(wpassoc);
|
||||||
|
}
|
||||||
//end struct root_misc
|
//end struct root_misc
|
||||||
|
|
||||||
//class root_register
|
//class root_register
|
||||||
|
|||||||
@ -1041,7 +1041,8 @@ namespace nana
|
|||||||
bool filebox::show() const
|
bool filebox::show() const
|
||||||
{
|
{
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
std::wstring wfile;
|
auto winitfile = to_wstring(impl_->file);
|
||||||
|
std::wstring wfile(winitfile);
|
||||||
wfile.resize(520);
|
wfile.resize(520);
|
||||||
|
|
||||||
OPENFILENAME ofn;
|
OPENFILENAME ofn;
|
||||||
|
|||||||
@ -821,6 +821,15 @@ namespace API
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nana::optional<rectangle> window_rectangle(window wd)
|
||||||
|
{
|
||||||
|
auto iwd = reinterpret_cast<basic_window*>(wd);
|
||||||
|
internal_scope_guard lock;
|
||||||
|
if (restrict::wd_manager().available(iwd))
|
||||||
|
return rectangle(iwd->pos_owner, iwd->dimension);
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
|
||||||
bool get_window_rectangle(window wd, rectangle& r)
|
bool get_window_rectangle(window wd, rectangle& r)
|
||||||
{
|
{
|
||||||
auto iwd = reinterpret_cast<basic_window*>(wd);
|
auto iwd = reinterpret_cast<basic_window*>(wd);
|
||||||
|
|||||||
@ -379,7 +379,7 @@ namespace nana{ namespace drawerbase
|
|||||||
}//end namespace drawerbase
|
}//end namespace drawerbase
|
||||||
|
|
||||||
//button
|
//button
|
||||||
//@brief: Defaine a button widget and it provides the interfaces to be operational
|
//@brief: Define a button widget and it provides the interfaces to be operational
|
||||||
button::button(){}
|
button::button(){}
|
||||||
|
|
||||||
button::button(window wd, bool visible)
|
button::button(window wd, bool visible)
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* A Form Implementation
|
* A Form Implementation
|
||||||
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 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
|
||||||
@ -10,6 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nana/gui/widgets/form.hpp>
|
#include <nana/gui/widgets/form.hpp>
|
||||||
|
#include <nana/gui/detail/bedrock.hpp>
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@ -94,6 +95,11 @@ namespace nana
|
|||||||
{
|
{
|
||||||
API::wait_for(handle());
|
API::wait_for(handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void form::keyboard_accelerator(const accel_key& key, const std::function<void()>& fn)
|
||||||
|
{
|
||||||
|
nana::detail::bedrock::instance().keyboard_accelerator(this->native_handle(), key, fn);
|
||||||
|
}
|
||||||
//end class form
|
//end class form
|
||||||
|
|
||||||
//class nested_form
|
//class nested_form
|
||||||
|
|||||||
@ -208,8 +208,8 @@ namespace nana{
|
|||||||
outter[field_title] << impl_->caption;
|
outter[field_title] << impl_->caption;
|
||||||
outter.collocate();
|
outter.collocate();
|
||||||
|
|
||||||
|
impl_->caption.transparent(true);
|
||||||
color pbg = API::bgcolor(this->parent());
|
color pbg = API::bgcolor(this->parent());
|
||||||
|
|
||||||
impl_->caption.bgcolor(pbg.blend(colors::black, 0.025));
|
impl_->caption.bgcolor(pbg.blend(colors::black, 0.025));
|
||||||
|
|
||||||
this->bgcolor(pbg.blend(colors::black, 0.05));
|
this->bgcolor(pbg.blend(colors::black, 0.05));
|
||||||
@ -222,10 +222,27 @@ namespace nana{
|
|||||||
auto gap_px = impl_->gap - 1;
|
auto gap_px = impl_->gap - 1;
|
||||||
|
|
||||||
graph.rectangle(true, API::bgcolor(this->parent()));
|
graph.rectangle(true, API::bgcolor(this->parent()));
|
||||||
graph.round_rectangle(rectangle(point(gap_px, impl_->caption_dimension.height / 2),
|
|
||||||
nana::size(graph.width() - 2 * gap_px, graph.height() - impl_->caption_dimension.height / 2 - gap_px)
|
auto const top_round_line = static_cast<int>(impl_->caption_dimension.height) / 2;
|
||||||
|
|
||||||
|
graph.round_rectangle(rectangle(point(gap_px, top_round_line),
|
||||||
|
nana::size(graph.width() - 2 * gap_px, graph.height() - top_round_line - gap_px)
|
||||||
),
|
),
|
||||||
3, 3, colors::gray_border, true, this->bgcolor());
|
3, 3, colors::gray_border, true, this->bgcolor());
|
||||||
|
|
||||||
|
auto opt_r = API::window_rectangle(impl_->caption);
|
||||||
|
if (opt_r)
|
||||||
|
{
|
||||||
|
rectangle grad_r{ opt_r->position(), nana::size{ opt_r->width, static_cast<unsigned>(top_round_line - opt_r->y) } };
|
||||||
|
|
||||||
|
grad_r.y += top_round_line*2 / 3;
|
||||||
|
grad_r.x -= 2;
|
||||||
|
grad_r.width += 4;
|
||||||
|
|
||||||
|
graph.gradual_rectangle(grad_r,
|
||||||
|
API::bgcolor(this->parent()), this->bgcolor(), true
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* A List Box Implementation
|
* A List Box Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 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
|
||||||
@ -1273,6 +1273,7 @@ namespace nana
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Backward
|
//Backward
|
||||||
|
n = -n;
|
||||||
dpos = pos;
|
dpos = pos;
|
||||||
if (good(dpos.cat))
|
if (good(dpos.cat))
|
||||||
{
|
{
|
||||||
@ -1519,8 +1520,6 @@ namespace nana
|
|||||||
template<typename Pred>
|
template<typename Pred>
|
||||||
std::vector<std::pair<index_pair, bool>> select_display_range_if(const index_pair& fr_abs, index_pair to_dpl, bool deselect_others, Pred pred)
|
std::vector<std::pair<index_pair, bool>> select_display_range_if(const index_pair& fr_abs, index_pair to_dpl, bool deselect_others, Pred pred)
|
||||||
{
|
{
|
||||||
const index_pairs already_selected = (deselect_others ? this->pick_items(true) : index_pairs{});
|
|
||||||
|
|
||||||
if (to_dpl.empty())
|
if (to_dpl.empty())
|
||||||
{
|
{
|
||||||
if (fr_abs.empty())
|
if (fr_abs.empty())
|
||||||
@ -1533,6 +1532,11 @@ namespace nana
|
|||||||
if (fr_dpl > to_dpl)
|
if (fr_dpl > to_dpl)
|
||||||
std::swap(fr_dpl, to_dpl);
|
std::swap(fr_dpl, to_dpl);
|
||||||
|
|
||||||
|
if (to_dpl.is_category() && this->size_item(to_dpl.cat) > 0)
|
||||||
|
to_dpl.item = this->size_item(to_dpl.cat) - 1;
|
||||||
|
|
||||||
|
const index_pairs already_selected = (deselect_others ? this->pick_items(true) : index_pairs{});
|
||||||
|
|
||||||
const auto begin = fr_dpl;
|
const auto begin = fr_dpl;
|
||||||
const auto last = to_dpl;
|
const auto last = to_dpl;
|
||||||
|
|
||||||
@ -1586,7 +1590,7 @@ namespace nana
|
|||||||
return pairs;
|
return pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool select_for_all(bool sel, const index_pair& except = index_pair{npos, npos})
|
bool select_for_all(bool sel, const index_pair& except_abs = index_pair{npos, npos})
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
index_pair pos;
|
index_pair pos;
|
||||||
@ -1595,7 +1599,7 @@ namespace nana
|
|||||||
pos.item = 0;
|
pos.item = 0;
|
||||||
for(auto & m : cat.items)
|
for(auto & m : cat.items)
|
||||||
{
|
{
|
||||||
if (except != pos)
|
if (except_abs != pos)
|
||||||
{
|
{
|
||||||
if (m.flags.selected != sel)
|
if (m.flags.selected != sel)
|
||||||
{
|
{
|
||||||
@ -1618,7 +1622,7 @@ namespace nana
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// return absolute positions, no relative to display
|
/// return absolute positions, no relative to display
|
||||||
index_pairs pick_items(bool for_selection) const
|
index_pairs pick_items(bool for_selection, bool find_first = false) const
|
||||||
{
|
{
|
||||||
index_pairs results;
|
index_pairs results;
|
||||||
index_pair id;
|
index_pair id;
|
||||||
@ -1629,7 +1633,11 @@ namespace nana
|
|||||||
for (auto & m : cat.items)
|
for (auto & m : cat.items)
|
||||||
{
|
{
|
||||||
if (for_selection ? m.flags.selected : m.flags.checked)
|
if (for_selection ? m.flags.selected : m.flags.checked)
|
||||||
|
{
|
||||||
results.push_back(id); // absolute positions, no relative to display
|
results.push_back(id); // absolute positions, no relative to display
|
||||||
|
if (find_first)
|
||||||
|
return results;
|
||||||
|
}
|
||||||
++id.item;
|
++id.item;
|
||||||
}
|
}
|
||||||
++id.cat;
|
++id.cat;
|
||||||
@ -1978,6 +1986,15 @@ namespace nana
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cs_status(index_pair abs_pos, bool for_selection) const
|
||||||
|
{
|
||||||
|
if (abs_pos.is_category())
|
||||||
|
return lister.cat_status(abs_pos.cat, for_selection);
|
||||||
|
|
||||||
|
auto & flags = lister.get(abs_pos.cat)->items.at(abs_pos.item).flags;
|
||||||
|
return (for_selection ? flags.selected : flags.checked);
|
||||||
|
}
|
||||||
|
|
||||||
void resize_disp_area()
|
void resize_disp_area()
|
||||||
{
|
{
|
||||||
auto head_px = this->header_visible_px();
|
auto head_px = this->header_visible_px();
|
||||||
@ -3416,6 +3433,8 @@ namespace nana
|
|||||||
rect.y - static_cast<int>(origin.y % item_height_px)
|
rect.y - static_cast<int>(origin.y % item_height_px)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
essence_->inline_buffered_table.swap(essence_->inline_table);
|
||||||
|
|
||||||
// The first display is empty when the listbox is empty.
|
// The first display is empty when the listbox is empty.
|
||||||
if (!first_disp.empty())
|
if (!first_disp.empty())
|
||||||
{
|
{
|
||||||
@ -3438,8 +3457,6 @@ namespace nana
|
|||||||
|
|
||||||
auto idx = first_disp;
|
auto idx = first_disp;
|
||||||
|
|
||||||
essence_->inline_buffered_table.swap(essence_->inline_table);
|
|
||||||
|
|
||||||
for (auto & cat : lister.cat_container())
|
for (auto & cat : lister.cat_container())
|
||||||
for (auto & ind : cat.indicators)
|
for (auto & ind : cat.indicators)
|
||||||
{
|
{
|
||||||
@ -3509,10 +3526,10 @@ namespace nana
|
|||||||
++idx.item;
|
++idx.item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
essence_->inline_buffered_table.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
essence_->inline_buffered_table.clear();
|
||||||
|
|
||||||
if (item_coord.y < rect.bottom())
|
if (item_coord.y < rect.bottom())
|
||||||
{
|
{
|
||||||
rectangle bground_r{ rect.x, item_coord.y, rect.width, static_cast<unsigned>(rect.bottom() - item_coord.y) };
|
rectangle bground_r{ rect.x, item_coord.y, rect.width, static_cast<unsigned>(rect.bottom() - item_coord.y) };
|
||||||
@ -4117,17 +4134,16 @@ namespace nana
|
|||||||
essence_->content_view->sync(false);
|
essence_->content_view->sync(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sel = true;
|
bool new_selected_status = true;
|
||||||
|
|
||||||
//no single selected
|
if (!lister.single_status(true)) //multiply selection enabled
|
||||||
if (!lister.single_status(true))
|
|
||||||
{
|
{
|
||||||
if (arg.shift)
|
if (arg.shift)
|
||||||
{
|
{
|
||||||
//Set the first item as the begin of selected item if there
|
//Set the first item as the begin of selected item if there
|
||||||
//is not a latest selected item.(#154 reported by RenaudAlpes)
|
//is not a latest selected item.(#154 reported by RenaudAlpes)
|
||||||
if (lister.latest_selected_abs.empty() || lister.latest_selected_abs.is_category())
|
if (lister.latest_selected_abs.empty())
|
||||||
lister.latest_selected_abs.set_both(0);
|
lister.latest_selected_abs = lister.first();
|
||||||
|
|
||||||
auto before = lister.latest_selected_abs;
|
auto before = lister.latest_selected_abs;
|
||||||
|
|
||||||
@ -4141,7 +4157,7 @@ namespace nana
|
|||||||
else if (arg.ctrl)
|
else if (arg.ctrl)
|
||||||
{
|
{
|
||||||
essence_->mouse_selection.reverse_selection = true;
|
essence_->mouse_selection.reverse_selection = true;
|
||||||
sel = !item_proxy(essence_, abs_item_pos).selected();
|
new_selected_status = !essence_->cs_status(abs_item_pos, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -4150,12 +4166,12 @@ namespace nana
|
|||||||
//Unselects all selected items if the current item is not selected before selecting.
|
//Unselects all selected items if the current item is not selected before selecting.
|
||||||
auto selected = lister.pick_items(true);
|
auto selected = lister.pick_items(true);
|
||||||
if (selected.cend() == std::find(selected.cbegin(), selected.cend(), item_pos))
|
if (selected.cend() == std::find(selected.cbegin(), selected.cend(), item_pos))
|
||||||
lister.select_for_all(false, item_pos);
|
lister.select_for_all(false, abs_item_pos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Unselects all selected items except current item if right button clicked.
|
//Unselects all selected items except current item if right button clicked.
|
||||||
lister.select_for_all(false, item_pos); //cancel all selections
|
lister.select_for_all(false, abs_item_pos); //cancel all selections
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4164,14 +4180,14 @@ namespace nana
|
|||||||
//Clicking on a category is ignored when single selection is enabled.
|
//Clicking on a category is ignored when single selection is enabled.
|
||||||
//Fixed by Greentwip(issue #121)
|
//Fixed by Greentwip(issue #121)
|
||||||
if (item_ptr)
|
if (item_ptr)
|
||||||
sel = !item_proxy(essence_, abs_item_pos).selected();
|
new_selected_status = !item_proxy(essence_, abs_item_pos).selected();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(item_ptr)
|
if(item_ptr)
|
||||||
{
|
{
|
||||||
if (item_ptr->flags.selected != sel)
|
if (item_ptr->flags.selected != new_selected_status)
|
||||||
{
|
{
|
||||||
if (sel)
|
if (new_selected_status)
|
||||||
{
|
{
|
||||||
//Deselects the previously selected item.
|
//Deselects the previously selected item.
|
||||||
lister.cancel_others_if_single_enabled(true, abs_item_pos);
|
lister.cancel_others_if_single_enabled(true, abs_item_pos);
|
||||||
@ -4180,13 +4196,15 @@ namespace nana
|
|||||||
else if (essence_->lister.latest_selected_abs == abs_item_pos)
|
else if (essence_->lister.latest_selected_abs == abs_item_pos)
|
||||||
essence_->lister.latest_selected_abs.set_both(npos);
|
essence_->lister.latest_selected_abs.set_both(npos);
|
||||||
|
|
||||||
item_ptr->flags.selected = sel;
|
item_ptr->flags.selected = new_selected_status;
|
||||||
lister.emit_cs(abs_item_pos, true);
|
lister.emit_cs(abs_item_pos, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lister.cat_status(item_pos.cat, true, true);
|
//A category was clicked. Sets all child items to be selected only if multiply selection is enabled.
|
||||||
|
if(!lister.single_status(true))
|
||||||
|
lister.cat_status(item_pos.cat, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -4336,8 +4354,9 @@ namespace nana
|
|||||||
|
|
||||||
void trigger::key_press(graph_reference graph, const arg_keyboard& arg)
|
void trigger::key_press(graph_reference graph, const arg_keyboard& arg)
|
||||||
{
|
{
|
||||||
|
auto & list = essence_->lister;
|
||||||
// Exit if list is empty
|
// Exit if list is empty
|
||||||
if (essence_->lister.first().empty())
|
if (list.first().empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool upward = false;
|
bool upward = false;
|
||||||
@ -4347,12 +4366,12 @@ namespace nana
|
|||||||
case keyboard::os_arrow_up:
|
case keyboard::os_arrow_up:
|
||||||
upward = true;
|
upward = true;
|
||||||
case keyboard::os_arrow_down:
|
case keyboard::os_arrow_down:
|
||||||
essence_->lister.move_select(upward, !arg.shift, true);
|
list.move_select(upward, !arg.shift, true);
|
||||||
break;
|
break;
|
||||||
case L' ':
|
case L' ':
|
||||||
{
|
{
|
||||||
index_pairs s;
|
index_pairs s;
|
||||||
bool ck = ! essence_->lister.item_selected_all_checked(s);
|
bool ck = ! list.item_selected_all_checked(s);
|
||||||
for(auto i : s)
|
for(auto i : s)
|
||||||
item_proxy(essence_, i).check(ck);
|
item_proxy(essence_, i).check(ck);
|
||||||
}
|
}
|
||||||
@ -4361,30 +4380,69 @@ namespace nana
|
|||||||
upward = true;
|
upward = true;
|
||||||
case keyboard::os_pagedown:
|
case keyboard::os_pagedown:
|
||||||
{
|
{
|
||||||
//Turns page, then returns if no change occurs
|
auto const item_px = essence_->item_height();
|
||||||
if (!essence_->content_view->turn_page(!upward, false))
|
auto picked_items = list.pick_items(true, true);
|
||||||
return;
|
index_pair init_idx = (picked_items.empty() ? list.first() : picked_items[0]);
|
||||||
|
|
||||||
essence_->lister.select_for_all(false);
|
essence_->lister.select_for_all(false);
|
||||||
|
|
||||||
auto idx = essence_->first_display();
|
//Get the pixels between the init item and top edge or bottom edge
|
||||||
|
auto logic_top = static_cast<int>(list.distance(list.first(), init_idx) * item_px);
|
||||||
|
|
||||||
if (!upward)
|
auto const screen_top = essence_->content_view->origin().y;
|
||||||
idx = essence_->lister.advance(idx, static_cast<int>(essence_->count_of_exposed(false)) - 1);
|
auto const screen_bottom = screen_top + essence_->content_view->view_area().height;
|
||||||
|
index_pair target_idx;
|
||||||
|
|
||||||
if (!idx.is_category())
|
//Check if it scrolls in current screen window
|
||||||
item_proxy::from_display(essence_, idx).select(true);
|
//condition: top of target item is not less than top edge of content view and
|
||||||
else if (!essence_->lister.single_status(true)) //not selected
|
//the bottom of target item is not greater than bottom edge of content view.
|
||||||
essence_->lister.cat_status(idx.cat, true, true);
|
if ((screen_top + item_px <= logic_top) && (logic_top + item_px + item_px <= screen_bottom))
|
||||||
|
{
|
||||||
|
int offset = (static_cast<int>(upward ? screen_top : screen_bottom - item_px) - logic_top) / static_cast<int>(item_px);
|
||||||
|
target_idx = list.advance(init_idx, offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//turn page
|
||||||
|
auto page_item_count = (std::max)(1, static_cast<int>(essence_->count_of_exposed(false)));
|
||||||
|
|
||||||
break;
|
auto origin = essence_->content_view->origin();
|
||||||
|
if (upward)
|
||||||
|
{
|
||||||
|
target_idx = list.advance(init_idx, -page_item_count);
|
||||||
|
if (target_idx.empty())
|
||||||
|
target_idx = list.first();
|
||||||
|
|
||||||
|
origin.y = list.distance(list.first(), target_idx) * item_px;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target_idx = list.advance(init_idx, page_item_count);
|
||||||
|
if (target_idx.empty())
|
||||||
|
target_idx = list.last();
|
||||||
|
|
||||||
|
origin.y = list.distance(list.first(), target_idx) * item_px + item_px;
|
||||||
|
if (origin.y >= (screen_bottom - screen_top))
|
||||||
|
origin.y -= (screen_bottom - screen_top);
|
||||||
|
else
|
||||||
|
origin.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
essence_->content_view->move_origin(origin - essence_->content_view->origin());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target_idx.is_category())
|
||||||
|
item_proxy::from_display(essence_, target_idx).select(true);
|
||||||
|
else if (!list.single_status(true)) //not selected
|
||||||
|
list.cat_status(target_idx.cat, true, true);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case keyboard::os_home:
|
case keyboard::os_home:
|
||||||
case keyboard::os_end:
|
case keyboard::os_end:
|
||||||
{
|
{
|
||||||
essence_->lister.select_for_all(false);
|
list.select_for_all(false);
|
||||||
|
|
||||||
auto pos = (keyboard::os_home == arg.key ? essence_->lister.first() : essence_->lister.last());
|
auto pos = (keyboard::os_home == arg.key ? list.first() : list.last());
|
||||||
if (!pos.empty())
|
if (!pos.empty())
|
||||||
{
|
{
|
||||||
//When the pos indicates an empty category, then search forwards/backwards(depending on arg.key whether it is Home or End) for a non empty category.
|
//When the pos indicates an empty category, then search forwards/backwards(depending on arg.key whether it is Home or End) for a non empty category.
|
||||||
@ -4393,9 +4451,9 @@ namespace nana
|
|||||||
{
|
{
|
||||||
if (keyboard::os_home == arg.key)
|
if (keyboard::os_home == arg.key)
|
||||||
{
|
{
|
||||||
while (0 == essence_->lister.size_item(pos.cat))
|
while (0 == list.size_item(pos.cat))
|
||||||
{
|
{
|
||||||
if (++pos.cat >= essence_->lister.cat_container().size())
|
if (++pos.cat >= list.cat_container().size())
|
||||||
{
|
{
|
||||||
pos = index_pair{ npos, npos };
|
pos = index_pair{ npos, npos };
|
||||||
break;
|
break;
|
||||||
@ -4404,7 +4462,7 @@ namespace nana
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (0 == essence_->lister.size_item(pos.cat))
|
while (0 == list.size_item(pos.cat))
|
||||||
{
|
{
|
||||||
if (pos.cat-- == 0)
|
if (pos.cat-- == 0)
|
||||||
{
|
{
|
||||||
@ -4416,7 +4474,7 @@ namespace nana
|
|||||||
|
|
||||||
if (!pos.empty())
|
if (!pos.empty())
|
||||||
{
|
{
|
||||||
if (essence_->lister.expand(pos.cat))
|
if (list.expand(pos.cat))
|
||||||
pos.item = 0;
|
pos.item = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4425,8 +4483,8 @@ namespace nana
|
|||||||
{
|
{
|
||||||
if (pos.is_category())
|
if (pos.is_category())
|
||||||
{
|
{
|
||||||
if (!essence_->lister.single_status(true)) //multiple selection is not enabled
|
if (!list.single_status(true)) //multiple selection is not enabled
|
||||||
essence_->lister.cat_status(pos.cat, true, true);
|
list.cat_status(pos.cat, true, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
item_proxy::from_display(essence_, pos).select(true);
|
item_proxy::from_display(essence_, pos).select(true);
|
||||||
@ -4662,12 +4720,12 @@ namespace nana
|
|||||||
|
|
||||||
bool item_proxy::operator==(const std::string& s) const
|
bool item_proxy::operator==(const std::string& s) const
|
||||||
{
|
{
|
||||||
return (text(pos_.item) == s);
|
return (text(0) == s);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool item_proxy::operator==(const std::wstring& s) const
|
bool item_proxy::operator==(const std::wstring& s) const
|
||||||
{
|
{
|
||||||
return (text(pos_.item) == to_utf8(s));
|
return (text(0) == to_utf8(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
item_proxy & item_proxy::operator=(const item_proxy& rhs)
|
item_proxy & item_proxy::operator=(const item_proxy& rhs)
|
||||||
@ -5158,7 +5216,8 @@ namespace nana
|
|||||||
cat_->make_sort_order();
|
cat_->make_sort_order();
|
||||||
ess_->lister.sort();
|
ess_->lister.sort();
|
||||||
|
|
||||||
ess_->update(true);
|
//Don't ignore the auto-draw flag for performance enhancement.
|
||||||
|
ess_->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//end class cat_proxy
|
//end class cat_proxy
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* A Progress Indicator Implementation
|
* A Progress Indicator Implementation
|
||||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 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
|
||||||
@ -96,7 +96,11 @@ namespace nana
|
|||||||
{
|
{
|
||||||
if (widget_)
|
if (widget_)
|
||||||
{
|
{
|
||||||
auto value_px = (widget_->size().width - border_px * 2) * value_ / max_;
|
auto value_px = (widget_->size().width - border_px * 2);
|
||||||
|
|
||||||
|
//avoid overflow
|
||||||
|
if (value_ < max_)
|
||||||
|
value_px = static_cast<unsigned>(value_px * (double(value_) / double(max_)));
|
||||||
|
|
||||||
if (value_px != value_px_)
|
if (value_px != value_px_)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* A Scroll Implementation
|
* A Scroll Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2018 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,9 +20,15 @@ namespace nana
|
|||||||
namespace scroll
|
namespace scroll
|
||||||
{
|
{
|
||||||
//struct metrics_type
|
//struct metrics_type
|
||||||
metrics_type::metrics_type()
|
metrics_type::metrics_type():
|
||||||
:peak(1), range(1), step(1), value(0),
|
peak(1),
|
||||||
what(buttons::none), pressed(false), scroll_length(0), scroll_pos(0)
|
range(1),
|
||||||
|
step(1),
|
||||||
|
value(0),
|
||||||
|
what(buttons::none),
|
||||||
|
pressed(false),
|
||||||
|
scroll_length(0),
|
||||||
|
scroll_pos(0)
|
||||||
{}
|
{}
|
||||||
//end struct metrics_type
|
//end struct metrics_type
|
||||||
|
|
||||||
|
|||||||
@ -91,7 +91,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
::jpeg_create_decompress(&jdstru);
|
::jpeg_create_decompress(&jdstru);
|
||||||
|
|
||||||
::jpeg_mem_src(&jdstru, const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(data)), bytes);
|
::jpeg_mem_src(&jdstru, const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(data)), static_cast<unsigned long>(bytes));
|
||||||
_m_read_jpg(jdstru);
|
_m_read_jpg(jdstru);
|
||||||
|
|
||||||
jpeg_finish_decompress(&jdstru);
|
jpeg_finish_decompress(&jdstru);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user