Fix scaling-related crashes
[lsnes.git] / src / platform / wxwidgets / scrollbar.cpp
blobddefa9d00a137562d7582693d2e45dcfa7cb5016
1 #include "platform/wxwidgets/scrollbar.hpp"
2 #include "platform/wxwidgets/platform.hpp"
3 #include "library/minmax.hpp"
4 #include <iostream>
6 scroll_bar::scroll_bar(wxWindow* parent, wxWindowID id, bool vertical)
7 : wxScrollBar(parent, id, wxDefaultPosition, wxDefaultSize, vertical ? wxSB_VERTICAL : wxSB_HORIZONTAL)
9 CHECK_UI_THREAD;
10 Connect(wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler(scroll_bar::on_scroll), NULL, this);
11 Connect(wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler(scroll_bar::on_scroll), NULL, this);
12 Connect(wxEVT_SCROLL_PAGEUP, wxScrollEventHandler(scroll_bar::on_scroll), NULL, this);
13 Connect(wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler(scroll_bar::on_scroll), NULL, this);
14 Connect(wxEVT_SCROLL_LINEUP, wxScrollEventHandler(scroll_bar::on_scroll), NULL, this);
15 Connect(wxEVT_SCROLL_TOP, wxScrollEventHandler(scroll_bar::on_scroll), NULL, this);
16 Connect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(scroll_bar::on_scroll), NULL, this);
17 position = 0;
18 range = 0;
19 pagesize = 1;
20 scroll_acc = 0;
23 scroll_bar::~scroll_bar()
27 void scroll_bar::set_page_size(unsigned _pagesize)
29 CHECK_UI_THREAD;
30 if(!_pagesize) _pagesize = 1;
31 pagesize = _pagesize;
32 if(range > pagesize)
33 SetScrollbar(position, pagesize, range, max(pagesize - 1, 1U));
34 else
35 SetScrollbar(0, 0, 0, 0);
38 void scroll_bar::set_range(unsigned _range)
40 CHECK_UI_THREAD;
41 if(pagesize >= _range)
42 position = 0;
43 else if(position + pagesize > _range)
44 position = _range - pagesize;
45 range = _range;
46 if(range > pagesize)
47 SetScrollbar(position, pagesize, range, max(pagesize - 1, 1U));
48 else
49 SetScrollbar(0, 0, 0, 0);
52 void scroll_bar::set_position(unsigned _position)
54 CHECK_UI_THREAD;
55 if(pagesize >= range)
56 _position = 0;
57 else if(_position + pagesize > range)
58 _position = range - pagesize;
59 position = _position;
60 if(range > pagesize)
61 SetScrollbar(position, pagesize, range, max(pagesize - 1, 1U));
62 else
63 SetScrollbar(0, 0, 0, 0);
66 void scroll_bar::apply_delta(int delta)
68 CHECK_UI_THREAD;
69 unsigned maxscroll = range - pagesize;
70 if(maxscroll > range)
71 maxscroll = 0;
72 unsigned newscroll = position + delta;
73 if(newscroll > range)
74 newscroll = (delta < 0) ? 0 : maxscroll;
75 position = newscroll;
76 if(position > maxscroll)
77 position = maxscroll;
78 if(range > pagesize)
79 SetScrollbar(position, pagesize, range, max(pagesize - 1, 1U));
80 else
81 SetScrollbar(0, 0, 0, 0);
82 callback(*this);
85 void scroll_bar::apply_wheel(int wheel, int wheelunit, unsigned speed)
87 if(!wheel || !wheelunit)
88 return;
89 scroll_acc += wheel;
90 while(wheelunit && scroll_acc <= -wheelunit) {
91 apply_delta(static_cast<int>(speed));
92 scroll_acc += wheelunit;
94 while(wheelunit && scroll_acc >= wheelunit) {
95 apply_delta(-static_cast<int>(speed));
96 scroll_acc -= wheelunit;
100 unsigned scroll_bar::get_position()
102 return position;
105 void scroll_bar::set_handler(std::function<void(scroll_bar&)> cb)
107 callback = cb;
110 void scroll_bar::on_scroll(wxScrollEvent& e)
112 CHECK_UI_THREAD;
113 if(range)
114 position = GetThumbPosition();
115 if(pagesize >= range)
116 position = 0;
117 else if(position + pagesize > range)
118 position = range - pagesize;
119 callback(*this);