add keyboard accelerator
This commit is contained in:
parent
56143087c3
commit
f6548acc84
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Basis Implementation
|
||||
* 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.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -30,6 +30,15 @@ namespace nana
|
||||
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
|
||||
{
|
||||
unchecked, checked, partial
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* A Bedrock Implementation
|
||||
* 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.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -27,6 +27,7 @@ namespace detail
|
||||
struct basic_window;
|
||||
class window_manager;
|
||||
|
||||
struct window_platform_assoc;
|
||||
|
||||
/// @brief fundamental core component, it provides an abstraction to the OS platform and some basic functions.
|
||||
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
|
||||
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:
|
||||
void event_expose(core_window_t *, bool exposed);
|
||||
void event_move(core_window_t*, int x, int y);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* A Form Implementation
|
||||
* 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.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -68,6 +68,8 @@ namespace nana
|
||||
|
||||
void modality() const;
|
||||
void wait_for_this();
|
||||
|
||||
void keyboard_accelerator(const accel_key&, const std::function<void()>& fn);
|
||||
};
|
||||
|
||||
class nested_form
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* A Bedrock Implementation
|
||||
* 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.
|
||||
* (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/event_code.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/layout_utility.hpp>
|
||||
#include <nana/gui/detail/element_store.hpp>
|
||||
#include "inner_fwd_implement.hpp"
|
||||
#include <errno.h>
|
||||
#include <algorithm>
|
||||
|
||||
@ -222,6 +222,11 @@ namespace detail
|
||||
arg.shift = (xkey.state & ShiftMask);
|
||||
}
|
||||
|
||||
void bedrock::keyboard_accelerator(native_window_type, const accel_key&, const std::function<void()>& fn)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
element_store& bedrock::get_element_store() const
|
||||
{
|
||||
return impl_->estore;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* A Bedrock Implementation
|
||||
* 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.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -20,11 +20,11 @@
|
||||
#include <nana/system/platform.hpp>
|
||||
#include <nana/system/timepiece.hpp>
|
||||
#include <nana/gui.hpp>
|
||||
#include <nana/gui/detail/inner_fwd_implement.hpp>
|
||||
#include <nana/gui/detail/native_window_interface.hpp>
|
||||
#include <nana/gui/layout_utility.hpp>
|
||||
#include <nana/gui/detail/element_store.hpp>
|
||||
#include <nana/gui/detail/color_schemes.hpp>
|
||||
#include "inner_fwd_implement.hpp"
|
||||
|
||||
#include <iostream> //use std::cerr
|
||||
|
||||
@ -182,6 +182,12 @@ namespace detail
|
||||
}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
|
||||
//here is the definition of this object
|
||||
bedrock bedrock::bedrock_object;
|
||||
@ -345,6 +351,20 @@ namespace detail
|
||||
}
|
||||
}
|
||||
|
||||
void process_msg(bedrock* brock, MSG& msg)
|
||||
{
|
||||
auto misc = brock->wd_manager().root_runtime(reinterpret_cast<native_window_type>(msg.hwnd));
|
||||
|
||||
if (misc && misc->wpassoc->accel && ::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)
|
||||
{
|
||||
const unsigned tid = ::GetCurrentThreadId();
|
||||
@ -383,11 +403,15 @@ namespace detail
|
||||
if (msg.message == WM_QUIT) break;
|
||||
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);
|
||||
if (menu_wd) interior_helper_for_menu(msg, menu_wd);
|
||||
|
||||
::TranslateMessage(&msg);
|
||||
::TranslateMessage(&msg); //deprecated
|
||||
::DispatchMessage(&msg);
|
||||
#else
|
||||
process_msg(this, msg);
|
||||
#endif
|
||||
|
||||
wd_manager().remove_trash_handle(tid);
|
||||
}
|
||||
@ -400,11 +424,15 @@ namespace detail
|
||||
{
|
||||
if (-1 != ::GetMessage(&msg, 0, 0, 0))
|
||||
{
|
||||
#if 0
|
||||
auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
|
||||
if (menu_wd) interior_helper_for_menu(msg, menu_wd);
|
||||
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessage(&msg);
|
||||
#else
|
||||
process_msg(this, msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
wd_manager().call_safe_place(tid);
|
||||
@ -420,11 +448,15 @@ namespace detail
|
||||
{
|
||||
if(-1 != ::GetMessage(&msg, 0, 0, 0))
|
||||
{
|
||||
#if 0
|
||||
auto menu_wd = get_menu(reinterpret_cast<native_window_type>(msg.hwnd), true);
|
||||
if(menu_wd) interior_helper_for_menu(msg, menu_wd);
|
||||
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessage(&msg);
|
||||
#else
|
||||
process_msg(this, msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
wd_manager().call_safe_place(tid);
|
||||
@ -635,6 +667,7 @@ namespace detail
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case WM_COMMAND:
|
||||
case WM_DESTROY:
|
||||
case WM_SHOWWINDOW:
|
||||
case WM_SIZING:
|
||||
@ -786,6 +819,17 @@ namespace detail
|
||||
|
||||
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:
|
||||
if (msgwnd->other.attribute.root->ime_enabled)
|
||||
{
|
||||
@ -1582,6 +1626,54 @@ namespace detail
|
||||
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;
|
||||
|
||||
auto wpassoc = misc->wpassoc;
|
||||
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
|
||||
{
|
||||
return impl_->estore;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Implementations of Inner Forward Declaration
|
||||
* 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.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -15,9 +15,9 @@
|
||||
#define NANA_GUI_INNER_FWD_IMPLEMENT_HPP
|
||||
|
||||
#include <nana/push_ignore_diagnostic>
|
||||
#include "inner_fwd.hpp"
|
||||
#include "basic_window.hpp"
|
||||
#include "../../paint/graphics.hpp"
|
||||
#include <nana/gui/detail/inner_fwd.hpp>
|
||||
#include <nana/gui/detail/basic_window.hpp>
|
||||
#include <nana/paint/graphics.hpp>
|
||||
|
||||
#include <map>
|
||||
|
||||
@ -54,10 +54,13 @@ namespace nana{
|
||||
implementation * impl_;
|
||||
};
|
||||
|
||||
struct window_platform_assoc;
|
||||
|
||||
struct root_misc
|
||||
{
|
||||
basic_window * window;
|
||||
window_platform_assoc * wpassoc{ nullptr };
|
||||
|
||||
nana::paint::graphics root_graph;
|
||||
shortkey_container shortkeys;
|
||||
|
||||
@ -71,6 +74,10 @@ namespace nana{
|
||||
|
||||
root_misc(root_misc&&);
|
||||
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
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Window Manager Implementation
|
||||
* 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.
|
||||
* (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/window_manager.hpp>
|
||||
#include <nana/gui/detail/window_layout.hpp>
|
||||
#include "window_register.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/detail/effects_renderer.hpp>
|
||||
#include "window_register.hpp"
|
||||
#include "inner_fwd_implement.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
@ -140,10 +140,12 @@ namespace nana
|
||||
//struct root_misc
|
||||
root_misc::root_misc(root_misc&& other):
|
||||
window(other.window),
|
||||
wpassoc(other.wpassoc),
|
||||
root_graph(std::move(other.root_graph)),
|
||||
shortkeys(std::move(other.shortkeys)),
|
||||
condition(std::move(other.condition))
|
||||
{
|
||||
other.wpassoc = nullptr; //moved-from
|
||||
}
|
||||
|
||||
root_misc::root_misc(basic_window * wd, unsigned width, unsigned height)
|
||||
@ -155,6 +157,11 @@ namespace nana
|
||||
condition.pressed_by_space = nullptr;
|
||||
condition.hovered = nullptr;
|
||||
}
|
||||
|
||||
root_misc::~root_misc()
|
||||
{
|
||||
bedrock::delete_platform_assoc(wpassoc);
|
||||
}
|
||||
//end struct root_misc
|
||||
|
||||
//class root_register
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include <nana/gui/widgets/form.hpp>
|
||||
#include <nana/gui/detail/bedrock.hpp>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
@ -94,6 +95,11 @@ namespace nana
|
||||
{
|
||||
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
|
||||
|
||||
//class nested_form
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user