mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-12 05:36:59 -04:00
Implement scrolling ourselfs rather than relying on wxScrolledWindow
This commit is contained in:
@@ -42,14 +42,12 @@ class ConsoleMessage : public IntrusivePtrBase<ConsoleMessage> {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
class MessageCtrl : public wxScrolledWindow {
|
class MessageCtrl : public wxPanel {
|
||||||
public:
|
public:
|
||||||
MessageCtrl(wxWindow* parent, int id)
|
MessageCtrl(wxWindow* parent, int id)
|
||||||
: wxScrolledWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxBORDER_THEME)
|
: wxPanel(parent, id, wxDefaultPosition, wxDefaultSize, wxBORDER_THEME | wxVSCROLL)
|
||||||
{
|
{
|
||||||
SetBackgroundStyle(wxBG_STYLE_CUSTOM);
|
SetBackgroundStyle(wxBG_STYLE_CUSTOM);
|
||||||
SetScrollRate(0, 1);
|
|
||||||
EnableScrolling(false,true);
|
|
||||||
// icons
|
// icons
|
||||||
BOOST_STATIC_ASSERT(MESSAGE_TYPE_MAX == 6);
|
BOOST_STATIC_ASSERT(MESSAGE_TYPE_MAX == 6);
|
||||||
icons[MESSAGE_INPUT] = wxBitmap(load_resource_image(_("message_input")));
|
icons[MESSAGE_INPUT] = wxBitmap(load_resource_image(_("message_input")));
|
||||||
@@ -64,6 +62,8 @@ class MessageCtrl : public wxScrolledWindow {
|
|||||||
colors[MESSAGE_INFO] = wxColour(0,0,255);
|
colors[MESSAGE_INFO] = wxColour(0,0,255);
|
||||||
colors[MESSAGE_WARNING] = wxColour(255,255,0);
|
colors[MESSAGE_WARNING] = wxColour(255,255,0);
|
||||||
colors[MESSAGE_ERROR] = colors[MESSAGE_FATAL_ERROR] = wxColour(255,0,0);
|
colors[MESSAGE_ERROR] = colors[MESSAGE_FATAL_ERROR] = wxColour(255,0,0);
|
||||||
|
// scrollbar
|
||||||
|
update_scrollbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_message(ConsoleMessageP const& msg) {
|
void add_message(ConsoleMessageP const& msg) {
|
||||||
@@ -73,6 +73,7 @@ class MessageCtrl : public wxScrolledWindow {
|
|||||||
selection = messages.size();
|
selection = messages.size();
|
||||||
// refresh
|
// refresh
|
||||||
ensure_visible(*messages.back());
|
ensure_visible(*messages.back());
|
||||||
|
update_scrollbar();
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
}
|
}
|
||||||
void add_message(MessageType type, String const& text, bool joined_to_previous = false) {
|
void add_message(MessageType type, String const& text, bool joined_to_previous = false) {
|
||||||
@@ -122,8 +123,7 @@ class MessageCtrl : public wxScrolledWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onLeftDown(wxMouseEvent& ev) {
|
void onLeftDown(wxMouseEvent& ev) {
|
||||||
int ystart; GetViewStart(nullptr,&ystart);
|
select(find_point(view_start + ev.GetY()));
|
||||||
select( find_point(ystart + ev.GetY()) );
|
|
||||||
ev.Skip(); // for focus
|
ev.Skip(); // for focus
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,8 +146,9 @@ class MessageCtrl : public wxScrolledWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onFocus(wxFocusEvent&) {
|
void onFocus(wxFocusEvent& ev) {
|
||||||
if (selection < messages.size()) Refresh(false);
|
if (selection < messages.size()) Refresh(false);
|
||||||
|
ev.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t find_point(int y) {
|
size_t find_point(int y) {
|
||||||
@@ -159,17 +160,67 @@ class MessageCtrl : public wxScrolledWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ensure_visible(ConsoleMessage const& msg) {
|
void ensure_visible(ConsoleMessage const& msg) {
|
||||||
int ystart; GetViewStart(nullptr,&ystart);
|
|
||||||
int height = GetClientSize().y;
|
int height = GetClientSize().y;
|
||||||
if (msg.top < ystart) {
|
if (msg.top < view_start) {
|
||||||
Scroll(0, msg.top);
|
scroll_to(msg.top);
|
||||||
} else if (msg.bottom() > ystart + height) {
|
} else if (msg.bottom() > view_start + height) {
|
||||||
Scroll(0, msg.bottom() - height);
|
scroll_to(msg.bottom() - height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------- : Scrolling
|
||||||
|
int view_start = 0; // y coordinate where the view starts
|
||||||
|
|
||||||
|
void scroll_to(int new_view_start, bool update_scrollbar = true) {
|
||||||
|
int bottom = messages.empty() ? 0 : messages.back()->bottom() - GetClientSize().y;
|
||||||
|
view_start = new_view_start;
|
||||||
|
view_start = min(bottom, view_start);
|
||||||
|
view_start = max(0, view_start);
|
||||||
|
if (update_scrollbar) {
|
||||||
|
// update actual scrollbar
|
||||||
|
this->update_scrollbar();
|
||||||
|
// scroll actual window content
|
||||||
|
Refresh(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_scrollbar() {
|
||||||
|
int screen_height = GetClientSize().y;
|
||||||
|
int total_height = messages.empty() ? 0 : messages.back()->bottom();
|
||||||
|
SetScrollbar(wxVERTICAL, view_start, screen_height, total_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onScroll(wxScrollWinEvent& ev) {
|
||||||
|
wxEventType type = ev.GetEventType();
|
||||||
|
if (type == wxEVT_SCROLLWIN_TOP) {
|
||||||
|
scroll_to(0);
|
||||||
|
} else if (type == wxEVT_SCROLLWIN_BOTTOM) {
|
||||||
|
scroll_to(INT_MAX);
|
||||||
|
} else if (type == wxEVT_SCROLLWIN_LINEUP) {
|
||||||
|
scroll_to(view_start - MIN_ITEM_HEIGHT);
|
||||||
|
} else if (type == wxEVT_SCROLLWIN_LINEDOWN) {
|
||||||
|
scroll_to(view_start + MIN_ITEM_HEIGHT);
|
||||||
|
} else if (type == wxEVT_SCROLLWIN_PAGEUP) {
|
||||||
|
scroll_to(view_start - GetClientSize().y*3/4);
|
||||||
|
} else if (type == wxEVT_SCROLLWIN_PAGEDOWN) {
|
||||||
|
scroll_to(view_start + GetClientSize().y*3/4);
|
||||||
|
} else {
|
||||||
|
scroll_to(ev.GetPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onMouseWheel(wxMouseEvent& ev) {
|
||||||
|
scroll_to(view_start - MIN_ITEM_HEIGHT * ev.GetWheelRotation() / ev.GetWheelDelta());
|
||||||
|
}
|
||||||
|
|
||||||
|
void onSize(wxSizeEvent&) {
|
||||||
|
update_scrollbar();
|
||||||
|
Refresh(false);
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------- : Drawing
|
// --------------------------------------------------- : Drawing
|
||||||
|
|
||||||
|
void onEraseBackground(wxEraseEvent&) {}
|
||||||
void onPaint(wxPaintEvent& ev) {
|
void onPaint(wxPaintEvent& ev) {
|
||||||
wxAutoBufferedPaintDC dc(this);
|
wxAutoBufferedPaintDC dc(this);
|
||||||
PrepareDC(dc);
|
PrepareDC(dc);
|
||||||
@@ -178,6 +229,7 @@ class MessageCtrl : public wxScrolledWindow {
|
|||||||
void draw(wxDC& dc) const {
|
void draw(wxDC& dc) const {
|
||||||
clearDC(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
clearDC(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||||
dc.SetFont(*wxNORMAL_FONT);
|
dc.SetFont(*wxNORMAL_FONT);
|
||||||
|
int height = GetClientSize().y;
|
||||||
FOR_EACH_CONST(msg, messages) {
|
FOR_EACH_CONST(msg, messages) {
|
||||||
draw(dc, *msg);
|
draw(dc, *msg);
|
||||||
}
|
}
|
||||||
@@ -187,9 +239,11 @@ class MessageCtrl : public wxScrolledWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void draw(wxDC& dc, ConsoleMessage const& msg) const {
|
void draw(wxDC& dc, ConsoleMessage const& msg) const {
|
||||||
|
auto client_size = GetClientSize();
|
||||||
|
if (msg.bottom() < view_start || msg.top > view_start + client_size.y) return; // out of view
|
||||||
int left = 0;
|
int left = 0;
|
||||||
int top = msg.top;
|
int top = msg.top - view_start;
|
||||||
int width = GetClientSize().x;
|
int width = client_size.x;
|
||||||
wxColour color = colors[msg.type];
|
wxColour color = colors[msg.type];
|
||||||
wxColour bg, fg;
|
wxColour bg, fg;
|
||||||
if (selection < messages.size() && messages[selection].get() == &msg) {
|
if (selection < messages.size() && messages[selection].get() == &msg) {
|
||||||
@@ -322,6 +376,10 @@ BEGIN_EVENT_TABLE(MessageCtrl,wxScrolledWindow)
|
|||||||
EVT_CHAR(MessageCtrl::onChar)
|
EVT_CHAR(MessageCtrl::onChar)
|
||||||
EVT_SET_FOCUS(MessageCtrl::onFocus)
|
EVT_SET_FOCUS(MessageCtrl::onFocus)
|
||||||
EVT_KILL_FOCUS(MessageCtrl::onFocus)
|
EVT_KILL_FOCUS(MessageCtrl::onFocus)
|
||||||
|
EVT_SCROLLWIN(MessageCtrl::onScroll)
|
||||||
|
EVT_MOUSEWHEEL(MessageCtrl::onMouseWheel)
|
||||||
|
EVT_ERASE_BACKGROUND(MessageCtrl::onEraseBackground)
|
||||||
|
EVT_SIZE(MessageCtrl::onSize)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : TextCtrl with history
|
// ----------------------------------------------------------------------------- : TextCtrl with history
|
||||||
|
|||||||
Reference in New Issue
Block a user