refactor types(#450)
This commit is contained in:
@@ -24,10 +24,11 @@ namespace nana
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct native_window_handle_impl{};
|
||||
struct window_handle_impl{};
|
||||
struct event_handle_impl{};
|
||||
struct native_drawable_impl{};
|
||||
struct basic_window;
|
||||
|
||||
struct native_window_handle_impl;
|
||||
struct native_drawable_impl;
|
||||
struct event_handle_impl;
|
||||
}
|
||||
|
||||
struct accel_key
|
||||
@@ -87,10 +88,11 @@ namespace nana
|
||||
struct root_tag : public widget_tag{ static const flags value = flags::root; };
|
||||
}// end namespace category
|
||||
|
||||
using native_window_type = detail::native_window_handle_impl*;
|
||||
using window = detail::window_handle_impl*; ///< \see [What is window class ](https://sourceforge.net/p/nanapro/discussion/general/thread/bd0fabfb/)
|
||||
using event_handle = detail::event_handle_impl*;
|
||||
using native_drawable_type = detail::native_drawable_impl*;
|
||||
using window = detail::basic_window*; ///< The window handle type representing nana window objects
|
||||
using native_window_type = detail::native_window_handle_impl*; ///< The native window handle type representing system native windows. E.g, HWND in windows, Window in X11
|
||||
|
||||
using event_handle = detail::event_handle_impl*; ///< The event handle type representing nana window events
|
||||
using native_drawable_type = detail::native_drawable_impl*; ///< The drawable handle type representing system native drawable objects. E.g. HDC in windows, Drawable in X11
|
||||
|
||||
|
||||
struct keyboard
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
/**
|
||||
* A Basic Window Widget Definition
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2019 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/basic_window.hpp
|
||||
* @brief A Basic Window Widget Definition
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_DETAIL_BASIC_WINDOW_HPP
|
||||
#define NANA_GUI_DETAIL_BASIC_WINDOW_HPP
|
||||
#include <nana/push_ignore_diagnostic>
|
||||
#include "drawer.hpp"
|
||||
#include "events_holder.hpp"
|
||||
#include "widget_geometrics.hpp"
|
||||
#include "widget_content_measurer_interface.hpp"
|
||||
#include "widget_notifier_interface.hpp"
|
||||
#include <nana/basic_types.hpp>
|
||||
#include <nana/system/platform.hpp>
|
||||
#include <nana/gui/effects.hpp>
|
||||
|
||||
namespace nana{
|
||||
namespace detail
|
||||
{
|
||||
struct basic_window;
|
||||
|
||||
enum class visible_state
|
||||
{
|
||||
invisible, visible, displayed
|
||||
};
|
||||
|
||||
class caret
|
||||
: public caret_interface
|
||||
{
|
||||
public:
|
||||
caret(basic_window* owner, const size& size);
|
||||
~caret();
|
||||
|
||||
void activate(bool activity);
|
||||
basic_window* owner() const noexcept;
|
||||
void update();
|
||||
public:
|
||||
//Implement caret_interface functions
|
||||
|
||||
//This function is useless for class caret, see caret_proxy.
|
||||
void disable_throw() noexcept override;
|
||||
void effective_range(const rectangle& r) override;
|
||||
void position(const point& pos) override;
|
||||
nana::point position() const override;
|
||||
size dimension() const override;
|
||||
void dimension(const size& s) override;
|
||||
void visible(bool visibility) override;
|
||||
bool visible() const override;
|
||||
bool activated() const override;
|
||||
private:
|
||||
basic_window * owner_;
|
||||
point position_;
|
||||
size size_;
|
||||
size visual_size_;
|
||||
visible_state visibility_{ visible_state::invisible };
|
||||
bool out_of_range_{ false };
|
||||
rectangle effect_range_;
|
||||
};//end class caret
|
||||
|
||||
|
||||
/// Define some constant about tab category, these flags can be combine with operator |
|
||||
struct tab_type
|
||||
{
|
||||
enum t
|
||||
{
|
||||
none, ///< process by nana
|
||||
tabstop, ///< move to the next tabstop window
|
||||
eating, ///< process by current window
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/// a window data structure descriptor
|
||||
struct basic_window
|
||||
: public events_holder
|
||||
{
|
||||
using container = std::vector<basic_window*>;
|
||||
|
||||
enum class update_state
|
||||
{
|
||||
none, lazy, refreshed, request_refresh
|
||||
};
|
||||
|
||||
struct edge_nimbus_action
|
||||
{
|
||||
basic_window * window;
|
||||
bool rendered;
|
||||
};
|
||||
|
||||
/// constructor for the root window
|
||||
basic_window(basic_window* owner, std::unique_ptr<widget_notifier_interface>&&, category::root_tag**);
|
||||
|
||||
template<typename Category>
|
||||
basic_window(basic_window* parent, std::unique_ptr<widget_notifier_interface>&& wdg_notifier, const rectangle& r, Category**)
|
||||
: widget_notifier(std::move(wdg_notifier)), other(Category::value)
|
||||
{
|
||||
drawer.bind(this);
|
||||
if(parent)
|
||||
{
|
||||
_m_init_pos_and_size(parent, r);
|
||||
_m_initialize(parent);
|
||||
}
|
||||
}
|
||||
|
||||
~basic_window();
|
||||
|
||||
/// bind a native window and baisc_window
|
||||
void bind_native_window(native_window_type, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, paint::graphics&);
|
||||
|
||||
bool is_ancestor_of(const basic_window* wd) const;
|
||||
bool visible_parents() const;
|
||||
bool displayed() const;
|
||||
bool belong_to_lazy() const;
|
||||
const basic_window * child_caret() const; ///< Returns the child which owns the caret
|
||||
|
||||
bool is_draw_through() const; ///< Determines whether it is a draw-through window.
|
||||
|
||||
basic_window * seek_non_lite_widget_ancestor() const;
|
||||
|
||||
void set_action(mouse_action);
|
||||
|
||||
/// Only refresh when the root of window is in lazy-updating mode
|
||||
bool try_lazy_update(bool try_refresh);
|
||||
public:
|
||||
/// Override event_holder
|
||||
bool set_events(const std::shared_ptr<general_events>&) override;
|
||||
general_events * get_events() const override;
|
||||
private:
|
||||
void _m_init_pos_and_size(basic_window* parent, const rectangle&);
|
||||
void _m_initialize(basic_window* parent);
|
||||
public:
|
||||
#if defined(NANA_POSIX)
|
||||
point pos_native;
|
||||
#endif
|
||||
point pos_root; ///< coordinates of the root window
|
||||
point pos_owner;
|
||||
size dimension;
|
||||
::nana::size min_track_size;
|
||||
::nana::size max_track_size;
|
||||
|
||||
bool visible;
|
||||
|
||||
unsigned extra_width;
|
||||
unsigned extra_height;
|
||||
|
||||
basic_window *parent;
|
||||
basic_window *owner;
|
||||
|
||||
native_string_type title;
|
||||
::nana::detail::drawer drawer; ///< Self Drawer with owen graphics
|
||||
basic_window* root_widget; ///< A pointer refers to the root basic window, if the window is a root, the pointer refers to itself.
|
||||
paint::graphics* root_graph; ///< Refer to the root buffer graphics
|
||||
cursor predef_cursor;
|
||||
std::unique_ptr<widget_notifier_interface> widget_notifier;
|
||||
|
||||
struct flags_type
|
||||
{
|
||||
bool enabled :1;
|
||||
bool dbl_click :1;
|
||||
bool captured :1; ///< if mouse button is down, it always receive mouse move even the mouse is out of its rectangle
|
||||
bool modal :1;
|
||||
bool take_active:1; ///< If take_active is false, other.active_window still keeps the focus.
|
||||
bool refreshing :1;
|
||||
bool destroying :1;
|
||||
bool dropable :1; ///< Whether the window has make mouse_drop event.
|
||||
bool fullscreen :1; ///< When the window is maximizing whether it fit for fullscreen.
|
||||
bool borderless :1;
|
||||
bool make_bground_declared : 1; ///< explicitly make bground for bground effects
|
||||
bool ignore_menubar_focus : 1; ///< A flag indicates whether the menubar sets the focus.
|
||||
bool ignore_mouse_focus : 1; ///< A flag indicates whether the widget accepts focus when clicking on it
|
||||
bool space_click_enabled : 1; ///< A flag indicates whether enable mouse_down/click/mouse_up when pressing and releasing whitespace key.
|
||||
bool draggable : 1;
|
||||
unsigned Reserved : 17;
|
||||
unsigned char tab; ///< indicate a window that can receive the keyboard TAB
|
||||
mouse_action action;
|
||||
mouse_action action_before;
|
||||
}flags;
|
||||
|
||||
|
||||
struct annex_components
|
||||
{
|
||||
caret* caret_ptr{ nullptr };
|
||||
|
||||
//The following pointers refer to the widget's object.
|
||||
std::shared_ptr<general_events> events_ptr;
|
||||
widget_geometrics* scheme{ nullptr };
|
||||
::nana::dev::widget_content_measurer_interface* content_measurer{ nullptr };
|
||||
}annex;
|
||||
|
||||
struct
|
||||
{
|
||||
effects::edge_nimbus edge_nimbus;
|
||||
effects::bground_interface * bground;
|
||||
double bground_fade_rate;
|
||||
}effect;
|
||||
|
||||
struct other_tag
|
||||
{
|
||||
struct attr_root_tag
|
||||
{
|
||||
bool ime_enabled{ false };
|
||||
bool lazy_update{ false }; ///< Indicates whether the window is in lazy-updating mode.
|
||||
|
||||
container update_requesters; ///< Container for lazy-updating requesting windows.
|
||||
container tabstop;
|
||||
std::vector<edge_nimbus_action> effects_edge_nimbus;
|
||||
basic_window* focus{nullptr};
|
||||
basic_window* menubar{nullptr};
|
||||
cursor state_cursor{nana::cursor::arrow};
|
||||
basic_window* state_cursor_window{ nullptr };
|
||||
|
||||
std::function<void()> draw_through; ///< A draw through renderer for root widgets.
|
||||
};
|
||||
|
||||
const category::flags category;
|
||||
basic_window *active_window; ///< if flags.take_active is false, the active_window still keeps the focus,
|
||||
///< if the active_window is null, the parent of this window keeps focus.
|
||||
paint::graphics glass_buffer; ///< if effect.bground is avaiable. Refer to window_layout::make_bground.
|
||||
update_state upd_state;
|
||||
dragdrop_status dnd_state{ dragdrop_status::not_ready };
|
||||
|
||||
union
|
||||
{
|
||||
attr_root_tag * root;
|
||||
}attribute;
|
||||
|
||||
other_tag(category::flags);
|
||||
~other_tag();
|
||||
}other;
|
||||
|
||||
native_window_type root; ///< root Window handle
|
||||
thread_t thread_id; ///< the identifier of the thread that created the window.
|
||||
unsigned index;
|
||||
container children;
|
||||
};
|
||||
|
||||
}//end namespace detail
|
||||
}//end namespace nana
|
||||
#include <nana/pop_ignore_diagnostic>
|
||||
#endif
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
#define NANA_GUI_DETAIL_EFFECTS_RENDERER_HPP
|
||||
#include <nana/gui/effects.hpp>
|
||||
#include <nana/paint/graphics.hpp>
|
||||
#include <nana/paint/pixel_buffer.hpp>
|
||||
#include <nana/gui/layout_utility.hpp>
|
||||
#include <nana/gui/detail/window_layout.hpp>
|
||||
|
||||
namespace nana{
|
||||
namespace detail
|
||||
{
|
||||
template<typename CoreWindow>
|
||||
class edge_nimbus_renderer
|
||||
{
|
||||
edge_nimbus_renderer() = default;
|
||||
public:
|
||||
using core_window_t = CoreWindow;
|
||||
using window_layer = ::nana::detail::window_layout;
|
||||
using graph_reference = ::nana::paint::graphics&;
|
||||
|
||||
static edge_nimbus_renderer& instance()
|
||||
{
|
||||
static edge_nimbus_renderer object;
|
||||
return object;
|
||||
}
|
||||
|
||||
constexpr unsigned weight() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
void erase(core_window_t* wd)
|
||||
{
|
||||
if (effects::edge_nimbus::none == wd->effect.edge_nimbus)
|
||||
return;
|
||||
|
||||
core_window_t * root_wd = wd->root_widget;
|
||||
auto & nimbus = root_wd->other.attribute.root->effects_edge_nimbus;
|
||||
|
||||
for (auto i = nimbus.begin(); i != nimbus.end(); ++i)
|
||||
{
|
||||
if (i->window == wd)
|
||||
{
|
||||
auto pixels = weight();
|
||||
rectangle r{wd->pos_root, wd->dimension};
|
||||
r.x -= static_cast<int>(pixels);
|
||||
r.y -= static_cast<int>(pixels);
|
||||
r.width += static_cast<unsigned>(pixels << 1);
|
||||
r.height += static_cast<unsigned>(pixels << 1);
|
||||
|
||||
root_wd->root_graph->paste(root_wd->root, r, r.x, r.y);
|
||||
|
||||
nimbus.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void render(core_window_t * wd, bool forced, const rectangle* update_area = nullptr)
|
||||
{
|
||||
bool copy_separately = true;
|
||||
std::vector<std::pair<rectangle, core_window_t*>> rd_set;
|
||||
|
||||
if (wd->root_widget->other.attribute.root->effects_edge_nimbus.size())
|
||||
{
|
||||
auto root_wd = wd->root_widget;
|
||||
|
||||
auto & nimbus = root_wd->other.attribute.root->effects_edge_nimbus;
|
||||
|
||||
auto focused = root_wd->other.attribute.root->focus;
|
||||
|
||||
const unsigned pixels = weight();
|
||||
|
||||
auto graph = root_wd->root_graph;
|
||||
|
||||
nana::rectangle r;
|
||||
for(auto & action : nimbus)
|
||||
{
|
||||
if(_m_edge_nimbus(action.window, focused) && window_layer::read_visual_rectangle(action.window, r))
|
||||
{
|
||||
if (action.window == wd)
|
||||
{
|
||||
if (update_area)
|
||||
::nana::overlap(*update_area, rectangle(r), r);
|
||||
copy_separately = false;
|
||||
}
|
||||
|
||||
//Avoiding duplicated rendering. If the window is declared to lazy refresh, it should be rendered.
|
||||
if ((forced && (action.window == wd)) || (focused == action.window) || !action.rendered || (action.window->other.upd_state == core_window_t::update_state::refreshed))
|
||||
{
|
||||
rd_set.emplace_back(r, action.window);
|
||||
action.rendered = true;
|
||||
}
|
||||
}
|
||||
else if(action.rendered)
|
||||
{
|
||||
action.rendered = false;
|
||||
|
||||
if (action.window == wd)
|
||||
copy_separately = false;
|
||||
|
||||
::nana::rectangle erase_r(
|
||||
action.window->pos_root.x - static_cast<int>(pixels),
|
||||
action.window->pos_root.y - static_cast<int>(pixels),
|
||||
static_cast<unsigned>(action.window->dimension.width + (pixels << 1)),
|
||||
static_cast<unsigned>(action.window->dimension.height + (pixels << 1))
|
||||
);
|
||||
|
||||
graph->paste(root_wd->root, erase_r, erase_r.x, erase_r.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (copy_separately)
|
||||
{
|
||||
rectangle vr;
|
||||
if (window_layer::read_visual_rectangle(wd, vr))
|
||||
{
|
||||
if (update_area)
|
||||
::nana::overlap(*update_area, rectangle(vr), vr);
|
||||
wd->root_graph->paste(wd->root, vr, vr.x, vr.y);
|
||||
}
|
||||
}
|
||||
|
||||
rectangle wd_r{ wd->pos_root, wd->dimension };
|
||||
wd_r.pare_off(-static_cast<int>(this->weight()));
|
||||
//Render
|
||||
for (auto & rd : rd_set)
|
||||
{
|
||||
auto other_wd = rd.second;
|
||||
|
||||
if (other_wd != wd)
|
||||
{
|
||||
rectangle other_r{ other_wd->pos_root, other_wd->dimension };
|
||||
other_r.pare_off(-static_cast<int>(this->weight()));
|
||||
if (!overlapped(wd_r, other_r))
|
||||
continue;
|
||||
}
|
||||
_m_render_edge_nimbus(other_wd, rd.first);
|
||||
}
|
||||
}
|
||||
private:
|
||||
/// 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)
|
||||
{
|
||||
// Don't render the effect if the window is disabled.
|
||||
if (wd->flags.enabled)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void _m_render_edge_nimbus(core_window_t* wd, const nana::rectangle & visual)
|
||||
{
|
||||
wd->flags.action_before = wd->flags.action;
|
||||
|
||||
auto r = visual;
|
||||
r.pare_off(-static_cast<int>(weight()));
|
||||
rectangle good_r;
|
||||
if (overlap(r, rectangle{ wd->root_graph->size() }, good_r))
|
||||
{
|
||||
if ((good_r.x < wd->pos_root.x) || (good_r.y < wd->pos_root.y) ||
|
||||
(good_r.right() > visual.right()) || (good_r.bottom() > visual.bottom()))
|
||||
{
|
||||
auto graph = wd->root_graph;
|
||||
nana::paint::pixel_buffer pixbuf(graph->handle(), r);
|
||||
|
||||
pixel_argb_t px0, px1, px2, px3;
|
||||
|
||||
px0 = pixbuf.pixel(0, 0);
|
||||
px1 = pixbuf.pixel(r.width - 1, 0);
|
||||
px2 = pixbuf.pixel(0, r.height - 1);
|
||||
px3 = pixbuf.pixel(r.width - 1, r.height - 1);
|
||||
|
||||
good_r.x = good_r.y = 1;
|
||||
good_r.width = r.width - 2;
|
||||
good_r.height = r.height - 2;
|
||||
pixbuf.rectangle(good_r, wd->annex.scheme->activated.get_color(), 0.95, false);
|
||||
|
||||
good_r.x = good_r.y = 0;
|
||||
good_r.width = r.width;
|
||||
good_r.height = r.height;
|
||||
pixbuf.rectangle(good_r, wd->annex.scheme->activated.get_color(), 0.4, false);
|
||||
|
||||
pixbuf.pixel(0, 0, px0);
|
||||
pixbuf.pixel(r.width - 1, 0, px1);
|
||||
pixbuf.pixel(0, r.height - 1, px2);
|
||||
pixbuf.pixel(r.width - 1, r.height - 1, px3);
|
||||
|
||||
pixbuf.paste(wd->root, { r.x, r.y });
|
||||
|
||||
std::vector<typename window_layer::wd_rectangle> overlaps;
|
||||
if(window_layer::read_overlaps(wd, visual, overlaps))
|
||||
{
|
||||
for(auto & wdr : overlaps)
|
||||
graph->paste(wd->root, wdr.r, wdr.r.x, wdr.r.y);
|
||||
}
|
||||
}
|
||||
else
|
||||
wd->root_graph->paste(wd->root, visual, visual.x, visual.y);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
@@ -24,9 +24,13 @@
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace API
|
||||
{
|
||||
bool is_window(window); ///< Determines whether a window is existing, equal to !empty_window.
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
bool check_window(window);
|
||||
void events_operation_register(event_handle);
|
||||
|
||||
class event_interface
|
||||
@@ -36,16 +40,16 @@ namespace nana
|
||||
virtual void remove(event_handle) = 0;
|
||||
};
|
||||
|
||||
class docker_interface
|
||||
class event_docker_interface
|
||||
{
|
||||
public:
|
||||
virtual ~docker_interface() = default;
|
||||
virtual ~event_docker_interface() = default;
|
||||
virtual event_interface* get_event() const = 0;
|
||||
};
|
||||
|
||||
|
||||
struct docker_base
|
||||
: public docker_interface
|
||||
: public event_docker_interface
|
||||
{
|
||||
event_interface * const event_ptr;
|
||||
bool flag_deleted;
|
||||
@@ -78,11 +82,11 @@ namespace nana
|
||||
event_base * const evt_;
|
||||
};
|
||||
|
||||
event_handle _m_emplace(detail::docker_interface*, bool in_front);
|
||||
event_handle _m_emplace(detail::event_docker_interface*, bool in_front);
|
||||
protected:
|
||||
unsigned emitting_count_{ 0 };
|
||||
bool deleted_flags_{ false };
|
||||
std::vector<detail::docker_interface*> * dockers_{ nullptr };
|
||||
std::vector<detail::event_docker_interface*> * dockers_{ nullptr };
|
||||
};
|
||||
}//end namespace detail
|
||||
|
||||
@@ -228,7 +232,7 @@ namespace nana
|
||||
|
||||
d->invoke(arg);
|
||||
|
||||
if (window_handle && (!detail::check_window(window_handle)))
|
||||
if (window_handle && (!::nana::API::is_window(window_handle)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user