fix bug that dropdown list of combox may excess screen
This commit is contained in:
parent
24bbfc6493
commit
94ab3b9f78
@ -38,9 +38,9 @@ namespace nana
|
|||||||
{
|
{
|
||||||
std::vector<std::shared_ptr<item_interface>> items;
|
std::vector<std::shared_ptr<item_interface>> items;
|
||||||
|
|
||||||
std::size_t max_items{10}; // the number of items display.
|
std::size_t max_items{ 10 }; // the number of items display.
|
||||||
mutable std::size_t index{::nana::npos}; // the result of the selection.
|
mutable std::size_t index{ ::nana::npos }; // the result of the selection.
|
||||||
mutable bool have_selected;
|
mutable bool have_selected{ false };
|
||||||
};
|
};
|
||||||
|
|
||||||
class item_renderer
|
class item_renderer
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <nana/gui/widgets/scroll.hpp>
|
#include <nana/gui/widgets/scroll.hpp>
|
||||||
|
|
||||||
#include <nana/gui/layout_utility.hpp>
|
#include <nana/gui/layout_utility.hpp>
|
||||||
|
#include <nana/gui/screen.hpp>
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@ -198,16 +199,14 @@ namespace nana
|
|||||||
return widget_;
|
return widget_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void attach(widget* wd, nana::paint::graphics* graph)
|
void attach(widget& wd, nana::paint::graphics& graph)
|
||||||
{
|
{
|
||||||
if(wd)
|
widget_ = &wd;
|
||||||
{
|
wd.events().mouse_wheel.connect_unignorable([this](const arg_wheel& arg){
|
||||||
widget_ = wd;
|
scroll_items(arg.upwards);
|
||||||
wd->events().mouse_wheel.connect_unignorable([this](const arg_wheel& arg){
|
});
|
||||||
scroll_items(arg.upwards);
|
|
||||||
});
|
graph_ = &graph;
|
||||||
}
|
|
||||||
if(graph) graph_ = graph;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void detach()
|
void detach()
|
||||||
@ -219,9 +218,46 @@ namespace nana
|
|||||||
{
|
{
|
||||||
if(module_)
|
if(module_)
|
||||||
{
|
{
|
||||||
std::size_t items = (module_->max_items <= module_->items.size() ? module_->max_items : module_->items.size());
|
|
||||||
std::size_t h = items * state_.renderer->item_pixels(*graph_);
|
auto const items = (module_->max_items <= module_->items.size() ? module_->max_items : module_->items.size());
|
||||||
widget_->size(size{ widget_->size().width, static_cast<unsigned>(h + 4) });
|
|
||||||
|
rectangle list_r{
|
||||||
|
0, 0,
|
||||||
|
widget_->size().width,
|
||||||
|
static_cast<unsigned>(items * state_.renderer->item_pixels(*graph_)) + 4
|
||||||
|
};
|
||||||
|
|
||||||
|
//Test if the listbox excesses the screen
|
||||||
|
|
||||||
|
screen scr;
|
||||||
|
auto & disp = scr.from_window(*widget_);
|
||||||
|
|
||||||
|
auto disp_r = disp.area();
|
||||||
|
|
||||||
|
point pos;
|
||||||
|
API::calc_screen_point(*widget_, pos);
|
||||||
|
list_r.position(pos);
|
||||||
|
|
||||||
|
if (widget_->size().width >= disp_r.width)
|
||||||
|
{
|
||||||
|
pos.x = 0;
|
||||||
|
list_r.width = disp_r.width;
|
||||||
|
}
|
||||||
|
else if (list_r.right() > disp_r.right())
|
||||||
|
pos.x = disp_r.right() - static_cast<int>(list_r.width);
|
||||||
|
|
||||||
|
if (list_r.height >= disp_r.height)
|
||||||
|
{
|
||||||
|
pos.y = 0;
|
||||||
|
list_r.height = disp_r.height;
|
||||||
|
}
|
||||||
|
else if (list_r.bottom() > disp_r.bottom())
|
||||||
|
pos.y = disp_r.bottom() - static_cast<int>(list_r.height);
|
||||||
|
|
||||||
|
API::calc_window_point(API::get_owner_window(*widget_), pos);
|
||||||
|
list_r.position(pos);
|
||||||
|
|
||||||
|
widget_->move(list_r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,36 +348,37 @@ namespace nana
|
|||||||
|
|
||||||
void _m_open_scrollbar(widget_reference wd, bool v)
|
void _m_open_scrollbar(widget_reference wd, bool v)
|
||||||
{
|
{
|
||||||
if(v)
|
if (!v)
|
||||||
{
|
{
|
||||||
if(scrollbar_.empty() && module_)
|
|
||||||
{
|
|
||||||
scrollbar_.create(wd, rectangle(static_cast<int>(wd.size().width - 18), 2, 16, wd.size().height - 4));
|
|
||||||
scrollbar_.amount(module_->items.size());
|
|
||||||
scrollbar_.range(module_->max_items);
|
|
||||||
scrollbar_.value(state_.offset_y);
|
|
||||||
|
|
||||||
auto & events = scrollbar_.events();
|
|
||||||
events.mouse_wheel.connect([this](const arg_wheel& arg)
|
|
||||||
{
|
|
||||||
scroll_items(arg.upwards);
|
|
||||||
});
|
|
||||||
|
|
||||||
auto fn = [this](const arg_mouse& arg)
|
|
||||||
{
|
|
||||||
if (arg.is_left_button() && (scrollbar_.value() != state_.offset_y))
|
|
||||||
{
|
|
||||||
state_.offset_y = static_cast<unsigned>(scrollbar_.value());
|
|
||||||
draw();
|
|
||||||
API::update_window(*widget_);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
events.mouse_move.connect(fn);
|
|
||||||
events.mouse_up.connect(fn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
scrollbar_.close();
|
scrollbar_.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(scrollbar_.empty() && module_)
|
||||||
|
{
|
||||||
|
scrollbar_.create(wd, rectangle(static_cast<int>(wd.size().width - 18), 2, 16, wd.size().height - 4));
|
||||||
|
scrollbar_.amount(module_->items.size());
|
||||||
|
scrollbar_.range(module_->max_items);
|
||||||
|
scrollbar_.value(state_.offset_y);
|
||||||
|
|
||||||
|
auto & events = scrollbar_.events();
|
||||||
|
events.mouse_wheel.connect([this](const arg_wheel& arg)
|
||||||
|
{
|
||||||
|
scroll_items(arg.upwards);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto fn = [this](const arg_mouse& arg)
|
||||||
|
{
|
||||||
|
if (arg.is_left_button() && (scrollbar_.value() != state_.offset_y))
|
||||||
|
{
|
||||||
|
state_.offset_y = static_cast<unsigned>(scrollbar_.value());
|
||||||
|
draw();
|
||||||
|
API::update_window(*widget_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
events.mouse_move.connect(fn);
|
||||||
|
events.mouse_up.connect(fn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
widget * widget_{nullptr};
|
widget * widget_{nullptr};
|
||||||
@ -393,7 +430,7 @@ namespace nana
|
|||||||
|
|
||||||
void trigger::attached(widget_reference widget, graph_reference graph)
|
void trigger::attached(widget_reference widget, graph_reference graph)
|
||||||
{
|
{
|
||||||
drawer_->attach(&widget, &graph);
|
drawer_->attach(widget, graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::detached()
|
void trigger::detached()
|
||||||
|
@ -4168,6 +4168,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
if (sel)
|
if (sel)
|
||||||
{
|
{
|
||||||
|
//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);
|
||||||
essence_->lister.latest_selected_abs = abs_item_pos;
|
essence_->lister.latest_selected_abs = abs_item_pos;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user