refactor the class screen
This commit is contained in:
parent
2ca3573049
commit
e4382239e5
@ -27,25 +27,37 @@ namespace nana
|
|||||||
/// The index of monitor.
|
/// The index of monitor.
|
||||||
virtual std::size_t get_index() const = 0;
|
virtual std::size_t get_index() const = 0;
|
||||||
|
|
||||||
|
virtual bool is_primary_monitor() const = 0;
|
||||||
|
|
||||||
/// Returns the positional coordinates and size of the display device in reference to the desktop area
|
/// Returns the positional coordinates and size of the display device in reference to the desktop area
|
||||||
virtual const ::nana::rectangle& area() const = 0;
|
virtual const ::nana::rectangle& area() const = 0;
|
||||||
|
virtual const ::nana::rectangle& workarea() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class screen
|
class screen
|
||||||
{
|
{
|
||||||
|
struct implement;
|
||||||
public:
|
public:
|
||||||
static ::nana::size desktop_size();
|
static ::nana::size desktop_size();
|
||||||
static ::nana::size primary_monitor_size();
|
static ::nana::size primary_monitor_size();
|
||||||
static std::shared_ptr<display> from_point(const point&);
|
|
||||||
static std::shared_ptr<display> from_window(window);
|
screen();
|
||||||
|
|
||||||
|
/// Reload has no preconditions, it's safe to call on moved-from
|
||||||
|
void reload();
|
||||||
|
|
||||||
/// Returns the number of display monitors
|
/// Returns the number of display monitors
|
||||||
std::size_t count() const;
|
std::size_t count() const;
|
||||||
|
|
||||||
std::shared_ptr<display> get_display(std::size_t index) const;
|
display& from_point(const point&);
|
||||||
std::shared_ptr<display> get_primary() const;
|
display& from_window(window);
|
||||||
|
|
||||||
|
display& get_display(std::size_t index) const;
|
||||||
|
display& get_primary() const;
|
||||||
|
|
||||||
void for_each(std::function<void(display&)>) const;
|
void for_each(std::function<void(display&)>) const;
|
||||||
|
private:
|
||||||
|
std::shared_ptr<implement> impl_;
|
||||||
};
|
};
|
||||||
}//end namespace nana
|
}//end namespace nana
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
* http://www.boost.org/LICENSE_1_0.txt)
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
*
|
*
|
||||||
* @file: nana/gui/widgets/panel.hpp
|
* @file: nana/gui/widgets/panel.hpp
|
||||||
|
* @author: Jinhao
|
||||||
|
* @contributors: qPCR4vir
|
||||||
*
|
*
|
||||||
* @brief panel is a widget used for placing some widgets.
|
* @brief panel is a widget used for placing some widgets.
|
||||||
*/
|
*/
|
||||||
@ -44,13 +46,13 @@ namespace nana
|
|||||||
panel(window wd, bool visible)
|
panel(window wd, bool visible)
|
||||||
{
|
{
|
||||||
this->create(wd, rectangle(), visible);
|
this->create(wd, rectangle(), visible);
|
||||||
bgcolor(API::bgcolor(wd));
|
bgcolor(API::bgcolor(wd));
|
||||||
}
|
}
|
||||||
|
|
||||||
panel(window wd, const nana::rectangle& r = rectangle(), bool visible = true)
|
panel(window wd, const nana::rectangle& r = rectangle(), bool visible = true)
|
||||||
{
|
{
|
||||||
this->create(wd, r, visible);
|
this->create(wd, r, visible);
|
||||||
bgcolor(API::bgcolor(wd));
|
bgcolor(API::bgcolor(wd));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool transparent() const
|
bool transparent() const
|
||||||
|
|||||||
@ -25,39 +25,22 @@ namespace nana
|
|||||||
: public display
|
: public display
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
real_display(std::size_t number)
|
real_display() = default; //For requirement of vector
|
||||||
: index_(number)
|
|
||||||
{
|
|
||||||
#if defined(NANA_WINDOWS)
|
|
||||||
DISPLAY_DEVICE disp;
|
|
||||||
disp.cb = sizeof disp;
|
|
||||||
if (::EnumDisplayDevices(nullptr, static_cast<DWORD>(index_), &disp, 0))
|
|
||||||
{
|
|
||||||
DEVMODE mode;
|
|
||||||
mode.dmSize = sizeof mode;
|
|
||||||
if (::EnumDisplaySettings(disp.DeviceName, ENUM_CURRENT_SETTINGS, &mode))
|
|
||||||
{
|
|
||||||
area_.x = mode.dmPosition.x;
|
|
||||||
area_.y = mode.dmPosition.y;
|
|
||||||
area_.width = mode.dmPelsWidth;
|
|
||||||
area_.height = mode.dmPelsHeight;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (0 == index_)
|
|
||||||
{
|
|
||||||
area_ = detail::native_interface::primary_monitor_size();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
throw std::invalid_argument("Nana.Screen: Invalid monitor index.");
|
|
||||||
}
|
|
||||||
|
|
||||||
real_display(std::size_t number, const ::nana::rectangle& r)
|
#if defined(NANA_WINDOWS)
|
||||||
: index_(number), area_(r)
|
real_display(std::size_t number, const MONITORINFOEX& mi)
|
||||||
|
: index_(number),
|
||||||
|
is_primary_(mi.dwFlags & MONITORINFOF_PRIMARY),
|
||||||
|
area_(mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right - mi.rcMonitor.left, mi.rcMonitor.bottom - mi.rcMonitor.top),
|
||||||
|
workarea_(mi.rcWork.left, mi.rcWork.top, mi.rcWork.right - mi.rcWork.left, mi.rcWork.bottom - mi.rcWork.top)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
real_display(std::size_t number, const ::nana::rectangle& r)
|
||||||
|
: index_(number), is_primary_(true), area_(r), workarea_(r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
public:
|
public:
|
||||||
//Implementation of display
|
//Implementation of display
|
||||||
std::size_t get_index() const override
|
std::size_t get_index() const override
|
||||||
@ -65,13 +48,25 @@ namespace nana
|
|||||||
return index_;
|
return index_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_primary_monitor() const override
|
||||||
|
{
|
||||||
|
return is_primary_;
|
||||||
|
}
|
||||||
|
|
||||||
const ::nana::rectangle& area() const override
|
const ::nana::rectangle& area() const override
|
||||||
{
|
{
|
||||||
return area_;
|
return area_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ::nana::rectangle& workarea() const override
|
||||||
|
{
|
||||||
|
return workarea_;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
const std::size_t index_;
|
std::size_t index_;
|
||||||
|
bool is_primary_;
|
||||||
::nana::rectangle area_;
|
::nana::rectangle area_;
|
||||||
|
::nana::rectangle workarea_;
|
||||||
};
|
};
|
||||||
|
|
||||||
//class screen
|
//class screen
|
||||||
@ -92,7 +87,58 @@ namespace nana
|
|||||||
return ::nana::detail::native_interface::primary_monitor_size();
|
return ::nana::detail::native_interface::primary_monitor_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<display> screen::from_point(const point& pos)
|
|
||||||
|
struct screen::implement
|
||||||
|
{
|
||||||
|
std::vector<real_display> displays;
|
||||||
|
|
||||||
|
#if defined(NANA_WINDOWS)
|
||||||
|
void load_monitors()
|
||||||
|
{
|
||||||
|
std::vector<real_display> tmp;
|
||||||
|
::EnumDisplayMonitors(nullptr, nullptr, implement::enum_proc, reinterpret_cast<LPARAM>(&tmp));
|
||||||
|
tmp.swap(displays);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL __stdcall enum_proc(HMONITOR handle, HDC context, LPRECT r, LPARAM self_ptr)
|
||||||
|
{
|
||||||
|
auto disp_cont = reinterpret_cast<std::vector<real_display>*>(self_ptr);
|
||||||
|
MONITORINFOEX mi;
|
||||||
|
mi.cbSize = sizeof(MONITORINFOEX);
|
||||||
|
if (::GetMonitorInfo(handle, &mi))
|
||||||
|
disp_cont->emplace_back(disp_cont->size(), mi);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void load_monitors()
|
||||||
|
{
|
||||||
|
displays.emplace_back(0, primary_monitor_size());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
screen::screen()
|
||||||
|
: impl_(std::make_shared<implement>())
|
||||||
|
{
|
||||||
|
impl_->load_monitors();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void screen::reload()
|
||||||
|
{
|
||||||
|
impl_.reset(std::make_shared<implement>());
|
||||||
|
impl_->load_monitors();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t screen::count() const
|
||||||
|
{
|
||||||
|
return impl_->displays.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
display& screen::from_point(const point& pos)
|
||||||
{
|
{
|
||||||
#if defined(NANA_WINDOWS)
|
#if defined(NANA_WINDOWS)
|
||||||
typedef HMONITOR(__stdcall * MonitorFromPointT)(POINT, DWORD);
|
typedef HMONITOR(__stdcall * MonitorFromPointT)(POINT, DWORD);
|
||||||
@ -107,87 +153,47 @@ namespace nana
|
|||||||
mi.cbSize = sizeof mi;
|
mi.cbSize = sizeof mi;
|
||||||
if (::GetMonitorInfo(monitor, &mi))
|
if (::GetMonitorInfo(monitor, &mi))
|
||||||
{
|
{
|
||||||
DISPLAY_DEVICE disp;
|
for (auto & disp : impl_->displays)
|
||||||
disp.cb = sizeof disp;
|
|
||||||
|
|
||||||
DWORD index = 0;
|
|
||||||
while (::EnumDisplayDevices(nullptr, index++, &disp, 0))
|
|
||||||
{
|
{
|
||||||
DEVMODE mode;
|
auto & r = disp.area();
|
||||||
mode.dmSize = sizeof mode;
|
if (r.x == mi.rcMonitor.left && r.y == mi.rcMonitor.top &&
|
||||||
if (::EnumDisplaySettings(disp.DeviceName, ENUM_CURRENT_SETTINGS, &mode))
|
r.width == unsigned(mi.rcMonitor.right - mi.rcMonitor.left) &&
|
||||||
{
|
r.height == unsigned(mi.rcMonitor.bottom - mi.rcMonitor.top)
|
||||||
if (mode.dmPosition.x == mi.rcWork.left && mode.dmPosition.y == mi.rcWork.top &&
|
)
|
||||||
(static_cast<int>(mode.dmPelsWidth) == mi.rcWork.right - mi.rcWork.left) &&
|
return disp;
|
||||||
(static_cast<int>(mode.dmPelsHeight) == mi.rcWork.bottom - mi.rcWork.top))
|
|
||||||
{
|
|
||||||
return std::make_shared<real_display>(static_cast<std::size_t>(index - 1), rectangle{ mode.dmPosition.x, mode.dmPosition.y, static_cast<unsigned>(mode.dmPelsWidth), static_cast<unsigned>(mode.dmPelsHeight) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return screen().get_primary();
|
return get_primary();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<display> screen::from_window(window wd)
|
display& screen::from_window(window wd)
|
||||||
{
|
{
|
||||||
::nana::point pos;
|
::nana::point pos;
|
||||||
API::calc_screen_point(wd, pos);
|
API::calc_screen_point(wd, pos);
|
||||||
return from_point(pos);
|
return from_point(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t screen::count() const
|
|
||||||
{
|
|
||||||
#if defined(NANA_WINDOWS)
|
|
||||||
DISPLAY_DEVICE disp;
|
|
||||||
disp.cb = sizeof disp;
|
|
||||||
|
|
||||||
DWORD index = 0;
|
display& screen::get_display(std::size_t index) const
|
||||||
while (::EnumDisplayDevices(nullptr, index++, &disp, 0));
|
{
|
||||||
return static_cast<std::size_t>(index - 1);
|
return impl_->displays.at(index);
|
||||||
#else
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<display> screen::get_display(std::size_t index) const
|
display& screen::get_primary() const
|
||||||
{
|
{
|
||||||
return std::make_shared<real_display>(index);
|
for (auto & disp : impl_->displays)
|
||||||
}
|
if (disp.is_primary_monitor())
|
||||||
|
return disp;
|
||||||
|
|
||||||
std::shared_ptr<display> screen::get_primary() const
|
throw std::logic_error("no primary monitor found");
|
||||||
{
|
|
||||||
#if defined(NANA_WINDOWS)
|
|
||||||
//return rectangle(mi.rcWork.left, mi.rcWork.top,
|
|
||||||
// mi.rcWork.right - mi.rcWork.left, mi.rcWork.bottom - mi.rcWork.top);
|
|
||||||
DISPLAY_DEVICE disp;
|
|
||||||
disp.cb = sizeof disp;
|
|
||||||
|
|
||||||
DWORD index = 0;
|
|
||||||
while (::EnumDisplayDevices(nullptr, index++, &disp, 0))
|
|
||||||
{
|
|
||||||
DEVMODE mode;
|
|
||||||
mode.dmSize = sizeof mode;
|
|
||||||
if (::EnumDisplaySettings(disp.DeviceName, ENUM_CURRENT_SETTINGS, &mode))
|
|
||||||
{
|
|
||||||
if (mode.dmPosition.x == 0 && mode.dmPosition.y == 0)
|
|
||||||
return std::make_shared<real_display>(static_cast<std::size_t>(index - 1), rectangle{ mode.dmPosition.x, mode.dmPosition.y, static_cast<unsigned>(mode.dmPelsWidth), static_cast<unsigned>(mode.dmPelsHeight) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return std::make_shared<real_display>(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void screen::for_each(std::function<void(display&)> fn) const
|
void screen::for_each(std::function<void(display&)> fn) const
|
||||||
{
|
{
|
||||||
auto n = count();
|
for (auto & disp : impl_->displays)
|
||||||
for (decltype(n) i = 0; i < n; ++i)
|
|
||||||
{
|
|
||||||
real_display disp(i);
|
|
||||||
fn(disp);
|
fn(disp);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//end class screen
|
//end class screen
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ namespace nana
|
|||||||
|
|
||||||
nana::point pos_by_screen(nana::point pos, const nana::size& sz, bool overlap_allowed)
|
nana::point pos_by_screen(nana::point pos, const nana::size& sz, bool overlap_allowed)
|
||||||
{
|
{
|
||||||
auto scr_area = screen::from_point(pos)->area();
|
auto scr_area = screen().from_point(pos).workarea();
|
||||||
if (pos.x + sz.width > scr_area.x + scr_area.width)
|
if (pos.x + sz.width > scr_area.x + scr_area.width)
|
||||||
pos.x = static_cast<int>(scr_area.x + scr_area.width - sz.width);
|
pos.x = static_cast<int>(scr_area.x + scr_area.width - sz.width);
|
||||||
if (pos.x < scr_area.x)
|
if (pos.x < scr_area.x)
|
||||||
@ -77,7 +77,7 @@ namespace nana
|
|||||||
void tooltip_text(const nana::string& text) override
|
void tooltip_text(const nana::string& text) override
|
||||||
{
|
{
|
||||||
label_.caption(text);
|
label_.caption(text);
|
||||||
auto text_s = label_.measure(screen::from_window(label_)->area().width * 2 / 3);
|
auto text_s = label_.measure(screen().from_window(label_).workarea().width * 2 / 3);
|
||||||
this->size(nana::size{ text_s.width + 10, text_s.height + 10 });
|
this->size(nana::size{ text_s.width + 10, text_s.height + 10 });
|
||||||
label_.move(rectangle{ 5, 5, text_s.width, text_s.height });
|
label_.move(rectangle{ 5, 5, text_s.width, text_s.height });
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
* http://www.boost.org/LICENSE_1_0.txt)
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
*
|
*
|
||||||
* @file: source/gui/widgets/label.cpp
|
* @file: source/gui/widgets/label.cpp
|
||||||
|
* @author: Jinhao
|
||||||
|
* @contributors: qPCR4vir
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nana/gui/widgets/label.hpp>
|
#include <nana/gui/widgets/label.hpp>
|
||||||
@ -771,21 +773,21 @@ namespace nana
|
|||||||
label::label(window wd, const nana::string& text, bool visible)
|
label::label(window wd, const nana::string& text, bool visible)
|
||||||
{
|
{
|
||||||
create(wd, rectangle(), visible);
|
create(wd, rectangle(), visible);
|
||||||
bgcolor(API::bgcolor(wd));
|
bgcolor(API::bgcolor(wd));
|
||||||
caption(text);
|
caption(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
label::label(window wd, const nana::char_t* text, bool visible)
|
label::label(window wd, const nana::char_t* text, bool visible)
|
||||||
{
|
{
|
||||||
create(wd, rectangle(), visible);
|
create(wd, rectangle(), visible);
|
||||||
bgcolor(API::bgcolor(wd));
|
bgcolor(API::bgcolor(wd));
|
||||||
caption(text);
|
caption(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
label::label(window wd, const rectangle& r, bool visible)
|
label::label(window wd, const rectangle& r, bool visible)
|
||||||
{
|
{
|
||||||
create(wd, r, visible);
|
create(wd, r, visible);
|
||||||
bgcolor(API::bgcolor(wd));
|
bgcolor(API::bgcolor(wd));
|
||||||
}
|
}
|
||||||
|
|
||||||
label& label::transparent(bool enabled)
|
label& label::transparent(bool enabled)
|
||||||
|
|||||||
@ -659,7 +659,7 @@ namespace nana
|
|||||||
API::calc_screen_point(*widget_, pos);
|
API::calc_screen_point(*widget_, pos);
|
||||||
|
|
||||||
//get the screen coordinates of the widget pos.
|
//get the screen coordinates of the widget pos.
|
||||||
auto scr_area = screen::from_point(detail_.monitor_pos)->area();
|
auto scr_area = screen().from_point(detail_.monitor_pos).workarea();
|
||||||
|
|
||||||
if(pos.x + size.width > scr_area.x + scr_area.width)
|
if(pos.x + size.width > scr_area.x + scr_area.width)
|
||||||
pos.x = static_cast<int>(scr_area.x + scr_area.width - size.width);
|
pos.x = static_cast<int>(scr_area.x + scr_area.width - size.width);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user