Fix of leaking GDI resources on Win7 #8002:
- Code refactoring for draw_focus_rect. - Use one PaintDC for rendering - DoubleSlider::Control::Ruler refactoring - Suppress to update ruler for horizontal slider
This commit is contained in:
parent
4967b940b8
commit
3505e5a290
@ -122,6 +122,10 @@ Control::Control( wxWindow *parent,
|
||||
this->Bind(wxEVT_KEY_UP, &Control::OnKeyUp, this);
|
||||
this->Bind(wxEVT_RIGHT_DOWN, &Control::OnRightDown,this);
|
||||
this->Bind(wxEVT_RIGHT_UP, &Control::OnRightUp, this);
|
||||
this->Bind(wxEVT_SIZE, [this](wxSizeEvent& event) {
|
||||
m_ruler.update(m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
|
||||
event.Skip();
|
||||
});
|
||||
|
||||
// control's view variables
|
||||
SLIDER_MARGIN = 4 + GUI::wxGetApp().em_unit();
|
||||
@ -137,8 +141,14 @@ Control::Control( wxWindow *parent,
|
||||
m_line_pens = { &DARK_GREY_PEN, &GREY_PEN, &LIGHT_GREY_PEN };
|
||||
m_segm_pens = { &DARK_ORANGE_PEN, &ORANGE_PEN, &LIGHT_ORANGE_PEN };
|
||||
|
||||
FOCUS_RECT_PEN = wxPen(wxColour(128, 128, 10), 1, wxPENSTYLE_DOT);
|
||||
FOCUS_RECT_BRUSH = wxBrush(wxColour(0, 0, 0), wxBRUSHSTYLE_TRANSPARENT);
|
||||
|
||||
m_font = GetFont();
|
||||
this->SetMinSize(get_min_size());
|
||||
|
||||
if (style == wxSL_VERTICAL)
|
||||
m_ruler.set_parent(this->GetParent());
|
||||
}
|
||||
|
||||
void Control::msw_rescale()
|
||||
@ -170,6 +180,9 @@ void Control::msw_rescale()
|
||||
|
||||
SetMinSize(get_min_size());
|
||||
GetParent()->Layout();
|
||||
|
||||
m_ruler.update_dpi();
|
||||
m_ruler.update(m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
|
||||
}
|
||||
|
||||
void Control::sys_color_changed()
|
||||
@ -266,7 +279,11 @@ void Control::SetMaxValue(const int max_value)
|
||||
void Control::SetSliderValues(const std::vector<double>& values)
|
||||
{
|
||||
m_values = values;
|
||||
m_ruler.init(m_values);
|
||||
m_ruler.init(m_values, get_scroll_step());
|
||||
|
||||
// When "No sparce layer" is enabled, use m_layers_values for ruler update.
|
||||
// Because of m_values has duplicate values in this case.
|
||||
// m_ruler.update(this->GetParent(), m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
|
||||
}
|
||||
|
||||
void Control::draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos)
|
||||
@ -426,9 +443,12 @@ void Control::SetLayersTimes(const std::vector<float>& layers_times, float total
|
||||
if (m_layers_values.size() != m_layers_times.size())
|
||||
for (size_t i = m_layers_times.size(); i < m_layers_values.size(); i++)
|
||||
m_layers_times.push_back(total_time);
|
||||
m_ruler.update(m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
|
||||
Refresh();
|
||||
Update();
|
||||
}
|
||||
else
|
||||
m_ruler.update(m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
|
||||
}
|
||||
|
||||
void Control::SetLayersTimes(const std::vector<double>& layers_times)
|
||||
@ -494,15 +514,17 @@ void Control::get_lower_and_higher_position(int& lower_pos, int& higher_pos)
|
||||
}
|
||||
}
|
||||
|
||||
void Control::draw_focus_rect()
|
||||
void Control::draw_focus_rect(wxDC& dc)
|
||||
{
|
||||
if (!m_is_focused)
|
||||
return;
|
||||
const wxSize sz = GetSize();
|
||||
wxPaintDC dc(this);
|
||||
const wxPen pen = wxPen(wxColour(128, 128, 10), 1, wxPENSTYLE_DOT);
|
||||
dc.SetPen(pen);
|
||||
dc.SetBrush(wxBrush(wxColour(0, 0, 0), wxBRUSHSTYLE_TRANSPARENT));
|
||||
// wxPaintDC dc(this);
|
||||
//const wxPen pen = wxPen(wxColour(128, 128, 10), 1, wxPENSTYLE_DOT);
|
||||
//dc.SetPen(pen);
|
||||
//dc.SetBrush(wxBrush(wxColour(0, 0, 0), wxBRUSHSTYLE_TRANSPARENT));
|
||||
dc.SetPen(FOCUS_RECT_PEN);
|
||||
dc.SetBrush(FOCUS_RECT_BRUSH);
|
||||
dc.DrawRectangle(1, 1, sz.x - 2, sz.y - 2);
|
||||
}
|
||||
|
||||
@ -513,11 +535,12 @@ void Control::render()
|
||||
#else
|
||||
SetBackgroundColour(GetParent()->GetBackgroundColour());
|
||||
#endif // _WIN32
|
||||
draw_focus_rect();
|
||||
|
||||
wxPaintDC dc(this);
|
||||
dc.SetFont(m_font);
|
||||
|
||||
draw_focus_rect(dc);
|
||||
|
||||
const wxCoord lower_pos = get_position_from_value(m_lower_value);
|
||||
const wxCoord higher_pos = get_position_from_value(m_higher_value);
|
||||
|
||||
@ -807,7 +830,7 @@ void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, LabelType l
|
||||
}
|
||||
|
||||
wxColour old_clr = dc.GetTextForeground();
|
||||
const wxPen& pen = is_wipe_tower_layer(tick) && (tick == m_lower_value || tick == m_higher_value) ? DARK_ORANGE_PEN : wxPen(old_clr);
|
||||
const wxPen& pen = is_wipe_tower_layer(tick) && (tick == m_lower_value || tick == m_higher_value) ? DARK_ORANGE_PEN : /*wxPen(old_clr)*/GREY_PEN;
|
||||
dc.SetPen(pen);
|
||||
dc.SetTextForeground(pen.GetColour());
|
||||
|
||||
@ -1028,8 +1051,10 @@ void Control::draw_colored_band(wxDC& dc)
|
||||
}
|
||||
}
|
||||
|
||||
void Control::Ruler::init(const std::vector<double>& values)
|
||||
void Control::Ruler::init(const std::vector<double>& values, double scroll_step)
|
||||
{
|
||||
if (!m_parent)
|
||||
return;
|
||||
max_values.clear();
|
||||
max_values.reserve(std::count(values.begin(), values.end(), values.front()));
|
||||
|
||||
@ -1039,14 +1064,35 @@ void Control::Ruler::init(const std::vector<double>& values)
|
||||
it = std::find(it + 1, values.end(), values.front());
|
||||
}
|
||||
max_values.push_back(*(it - 1));
|
||||
|
||||
update(values, scroll_step);
|
||||
}
|
||||
|
||||
void Control::Ruler::update(wxWindow* win, const std::vector<double>& values, double scroll_step)
|
||||
void Control::Ruler::set_parent(wxWindow* parent)
|
||||
{
|
||||
if (values.empty())
|
||||
m_parent = parent;
|
||||
update_dpi();
|
||||
}
|
||||
|
||||
void Control::Ruler::update_dpi()
|
||||
{
|
||||
if (m_parent)
|
||||
m_DPI = GUI::get_dpi_for_window(m_parent);
|
||||
}
|
||||
|
||||
void Control::Ruler::update(const std::vector<double>& values, double scroll_step)
|
||||
{
|
||||
if (!m_parent || values.empty() ||
|
||||
// check if need to update ruler in respect to input values
|
||||
values.front() == m_min_val && values.back() == m_max_val && m_scroll_step == scroll_step && max_values.size() == m_max_values_cnt)
|
||||
return;
|
||||
int DPI = GUI::get_dpi_for_window(win);
|
||||
int pixels_per_sm = lround((double)(DPI) * 5.0/25.4);
|
||||
|
||||
m_min_val = values.front();
|
||||
m_max_val = values.back();
|
||||
m_scroll_step = scroll_step;
|
||||
m_max_values_cnt = max_values.size();
|
||||
|
||||
int pixels_per_sm = lround((double)(m_DPI) * 5.0/25.4);
|
||||
|
||||
if (lround(scroll_step) > pixels_per_sm) {
|
||||
long_step = -1.0;
|
||||
@ -1091,11 +1137,11 @@ void Control::Ruler::update(wxWindow* win, const std::vector<double>& values, do
|
||||
|
||||
void Control::draw_ruler(wxDC& dc)
|
||||
{
|
||||
if (m_values.empty())
|
||||
if (m_values.empty() || !m_ruler.can_draw())
|
||||
return;
|
||||
// When "No sparce layer" is enabled, use m_layers_values for ruler update.
|
||||
// Because of m_values has duplicate values in this case.
|
||||
m_ruler.update(this->GetParent(), m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
|
||||
// m_ruler.update(this->GetParent(), m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
|
||||
|
||||
int height, width;
|
||||
get_size(&width, &height);
|
||||
|
@ -303,7 +303,7 @@ public:
|
||||
protected:
|
||||
|
||||
void render();
|
||||
void draw_focus_rect();
|
||||
void draw_focus_rect(wxDC& dc);
|
||||
void draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end);
|
||||
void draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos);
|
||||
void draw_thumb(wxDC& dc, const wxCoord& pos_coord, const SelectedSlider& selection);
|
||||
@ -438,19 +438,36 @@ private:
|
||||
wxPen GREY_PEN;
|
||||
wxPen LIGHT_GREY_PEN;
|
||||
|
||||
wxPen FOCUS_RECT_PEN;
|
||||
wxBrush FOCUS_RECT_BRUSH;
|
||||
|
||||
std::vector<wxPen*> m_line_pens;
|
||||
std::vector<wxPen*> m_segm_pens;
|
||||
|
||||
struct Ruler {
|
||||
class Ruler {
|
||||
wxWindow* m_parent{nullptr}; // m_parent is nullptr for Unused ruler
|
||||
// in this case we will not init/update/render it
|
||||
// values to check if ruler has to be updated
|
||||
double m_min_val;
|
||||
double m_max_val;
|
||||
double m_scroll_step;
|
||||
size_t m_max_values_cnt;
|
||||
int m_DPI;
|
||||
|
||||
public:
|
||||
|
||||
double long_step;
|
||||
double short_step;
|
||||
std::vector<double> max_values;// max value for each object/instance in sequence print
|
||||
// > 1 for sequential print
|
||||
|
||||
void init(const std::vector<double>& values);
|
||||
void update(wxWindow* win, const std::vector<double>& values, double scroll_step);
|
||||
void set_parent(wxWindow* parent);
|
||||
void update_dpi();
|
||||
void init(const std::vector<double>& values, double scroll_step);
|
||||
void update(const std::vector<double>& values, double scroll_step);
|
||||
bool is_ok() { return long_step > 0 && short_step > 0; }
|
||||
size_t count() { return max_values.size(); }
|
||||
bool can_draw() { return m_parent != nullptr; }
|
||||
} m_ruler;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user