232 lines
9.4 KiB
C++
232 lines
9.4 KiB
C++
|
// for scroll
|
||
|
#pragma once
|
||
|
#include <wx/wxprec.h>
|
||
|
#ifndef WX_PRECOMP
|
||
|
#include <wx/wx.h>
|
||
|
#endif
|
||
|
|
||
|
#include <wx/splitter.h>
|
||
|
#include "ScrolledWindow.hpp"
|
||
|
#include "Scrollbar.hpp"
|
||
|
|
||
|
ScrolledWindow::ScrolledWindow(wxWindow *parent, wxWindowID id, wxPoint position, wxSize size, long style, int marginWidth, int scrollbarWidth, int tipLength)
|
||
|
: wxScrolled<wxWindow>(parent, id, position, size, style)
|
||
|
{
|
||
|
bool bVertical = (style & wxVSCROLL) != 0;
|
||
|
bool bHorizontal = (style & wxHSCROLL) != 0;
|
||
|
m_bothDirections = bVertical & bHorizontal;
|
||
|
EnableScrolling(bHorizontal, bVertical);
|
||
|
ShowScrollbars(wxSHOW_SB_NEVER, wxSHOW_SB_NEVER);
|
||
|
|
||
|
m_rightScrollbar = NULL;
|
||
|
m_bottomScrollbar = NULL;
|
||
|
m_verticalSplitter = NULL;
|
||
|
m_horizontalSplitter = NULL;
|
||
|
|
||
|
m_marginWidth = marginWidth;
|
||
|
|
||
|
wxSize hsSize = size;
|
||
|
hsSize.SetWidth(hsSize.GetWidth() - marginWidth);
|
||
|
hsSize.SetHeight(hsSize.GetHeight() - marginWidth);
|
||
|
|
||
|
wxSize vsSize = size;
|
||
|
vsSize.SetWidth(vsSize.GetWidth() - marginWidth);
|
||
|
|
||
|
|
||
|
if (bVertical) {
|
||
|
m_verticalSplitter = new wxWindow(this, -1, position, vsSize);
|
||
|
m_userPanel = new wxPanel(m_verticalSplitter, -1, wxPoint(0, 0), wxSize(size.GetWidth() - marginWidth, size.GetHeight()));
|
||
|
m_scroll_win = new wxWindow(m_verticalSplitter, -1, wxPoint(size.GetWidth() - marginWidth, 0), wxSize(marginWidth, size.GetHeight()));
|
||
|
m_rightScrollbar = new MyScrollbar(m_scroll_win, -1, wxPoint(0, 0), wxSize(scrollbarWidth, size.GetHeight()), this, wxVSCROLL, scrollbarWidth, tipLength);
|
||
|
} else if (bHorizontal) {
|
||
|
m_horizontalSplitter = new wxSplitterWindow(this, -1, position, hsSize);
|
||
|
m_userPanel = new wxPanel(m_horizontalSplitter, -1, wxPoint(0, 0), wxSize(size.GetWidth() - marginWidth, size.GetHeight() - marginWidth));
|
||
|
m_userPanel->SetBackgroundColour(parent->GetBackgroundColour());
|
||
|
|
||
|
m_bottomScrollbar = new MyScrollbar(m_horizontalSplitter, -1, wxPoint(0, 0), wxSize(size.GetWidth() - marginWidth, marginWidth), this, wxHSCROLL, scrollbarWidth,
|
||
|
tipLength);
|
||
|
m_horizontalSplitter->SplitHorizontally(m_userPanel, m_bottomScrollbar, -marginWidth);
|
||
|
m_horizontalSplitter->SetSashInvisible();
|
||
|
}
|
||
|
|
||
|
SetTargetWindow(m_userPanel); // very very important line
|
||
|
|
||
|
Bind(wxEVT_SIZE, &ScrolledWindow::OnSize, this);
|
||
|
Bind(wxEVT_SCROLLWIN_TOP, &ScrolledWindow::OnScroll, this);
|
||
|
Bind(wxEVT_SCROLLWIN_BOTTOM, &ScrolledWindow::OnScroll, this);
|
||
|
Bind(wxEVT_SCROLLWIN_LINEUP, &ScrolledWindow::OnScroll, this);
|
||
|
Bind(wxEVT_SCROLLWIN_LINEDOWN, &ScrolledWindow::OnScroll, this);
|
||
|
Bind(wxEVT_SCROLLWIN_PAGEUP, &ScrolledWindow::OnScroll, this);
|
||
|
Bind(wxEVT_SCROLLWIN_PAGEDOWN, &ScrolledWindow::OnScroll, this);
|
||
|
Bind(wxEVT_SCROLLWIN_THUMBTRACK, &ScrolledWindow::OnScroll, this);
|
||
|
Bind(wxEVT_SCROLLWIN_THUMBRELEASE, &ScrolledWindow::OnScroll, this);
|
||
|
Bind(wxEVT_MOUSEWHEEL, &ScrolledWindow::OnMouseWheel, this);
|
||
|
}
|
||
|
|
||
|
void ScrolledWindow::OnMouseWheel(wxMouseEvent &event)
|
||
|
{
|
||
|
m_rightScrollbar->GetEventHandler()->ProcessEvent(event);
|
||
|
|
||
|
// int dMotion, actualDim;
|
||
|
// if (event.GetWheelRotation() > 0)
|
||
|
// dMotion = -m_pixelsPerUnit;
|
||
|
// else
|
||
|
// dMotion = m_pixelsPerUnit;
|
||
|
// m_previousMouse += dMotion;
|
||
|
// actualDim = m_actualDim;
|
||
|
|
||
|
// if (m_direction == wxVSCROLL) {
|
||
|
// m_viewStartInPixels += (dMotion * m_virtualDim) / (float) actualDim + 0.5; // in pixels
|
||
|
|
||
|
// if (m_viewStartInPixels < 0)
|
||
|
// m_viewStartInPixels = 0;
|
||
|
// else if (m_viewStartInPixels + actualDim >= m_virtualDim)
|
||
|
// m_viewStartInPixels = m_virtualDim - actualDim;
|
||
|
|
||
|
// m_viewStartInScrollUnits = m_viewStartInPixels / (float) m_pixelsPerUnit + 0.5; // in scroll units
|
||
|
// m_scrolledWindow->Scroll(-1, m_viewStartInScrollUnits); // -1 means no change in this direction
|
||
|
// SetViewStart(m_viewStartInScrollUnits);
|
||
|
//} else {
|
||
|
// dMotion = -dMotion;
|
||
|
// if (m_scrolledWindow->IsBothDirections()) actualDim -= m_marginWidth; // must take into account the right margin
|
||
|
|
||
|
// m_viewStartInPixels += (dMotion * m_virtualDim) / (float) actualDim + 0.5; // in pixels
|
||
|
|
||
|
// if (m_viewStartInPixels < 0)
|
||
|
// m_viewStartInPixels = 0;
|
||
|
// else if (m_viewStartInPixels + actualDim >= m_virtualDim)
|
||
|
// m_viewStartInPixels = m_virtualDim - actualDim;
|
||
|
|
||
|
// m_viewStartInScrollUnits = m_viewStartInPixels / (float) m_pixelsPerUnit + 0.5; // in scroll units
|
||
|
// m_scrolledWindow->Scroll(m_viewStartInScrollUnits, -1); // -1 means no change in this direction
|
||
|
// SetViewStart(m_viewStartInScrollUnits);
|
||
|
//}
|
||
|
// Refresh();
|
||
|
// Update();
|
||
|
}
|
||
|
|
||
|
void ScrolledWindow::SetTipColor(wxColour color)
|
||
|
{
|
||
|
if (m_rightScrollbar) m_rightScrollbar->SetTipColor(color);
|
||
|
if (m_bottomScrollbar) m_bottomScrollbar->SetTipColor(color);
|
||
|
}
|
||
|
|
||
|
void ScrolledWindow::Refresh()
|
||
|
{
|
||
|
// m_rightScrollbar->SetViewStart(0);
|
||
|
// m_rightScrollbar->Refresh();
|
||
|
// m_rightScrollbar->Update();
|
||
|
// m_userPanel->Refresh();
|
||
|
// m_bottomScrollbar->SetViewStart(0);
|
||
|
// m_rightScrollbar->Refresh();
|
||
|
// m_bottomScrollbar->Refresh();
|
||
|
}
|
||
|
|
||
|
void ScrolledWindow::SetBackgroundColour(wxColour color)
|
||
|
{
|
||
|
wxWindow::SetBackgroundColour(color);
|
||
|
m_verticalSplitter->SetBackgroundColour(color);
|
||
|
m_userPanel->SetBackgroundColour(color);
|
||
|
m_scroll_win->SetBackgroundColour(color);
|
||
|
}
|
||
|
|
||
|
void ScrolledWindow::SetMarginColor(wxColour color)
|
||
|
{
|
||
|
if (m_rightScrollbar) m_rightScrollbar->SetMarginColor(color);
|
||
|
if (m_bottomScrollbar) m_bottomScrollbar->SetMarginColor(color);
|
||
|
}
|
||
|
|
||
|
void ScrolledWindow::SetScrollbarColor(wxColour color)
|
||
|
{
|
||
|
if (m_rightScrollbar) m_rightScrollbar->SetScrollbarColor(color);
|
||
|
if (m_bottomScrollbar) m_bottomScrollbar->SetScrollbarColor(color);
|
||
|
}
|
||
|
|
||
|
void ScrolledWindow::SetScrollbarTip(int len)
|
||
|
{
|
||
|
if (m_rightScrollbar) m_rightScrollbar->SetScrollbarTip(len);
|
||
|
if (m_bottomScrollbar) m_bottomScrollbar->SetScrollbarTip(len);
|
||
|
}
|
||
|
|
||
|
void ScrolledWindow::SetVirtualSize(int x, int y) { SetScrollbars(1, 1, x, y); }
|
||
|
|
||
|
void ScrolledWindow::SetVirtualSize(wxSize &size) { SetScrollbars(1, 1, size.GetWidth(), size.GetHeight()); }
|
||
|
|
||
|
void ScrolledWindow::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, int noUnitsX, int noUnitsY, int xPos, int yPos, bool noRefresh)
|
||
|
{
|
||
|
wxScrolled<wxWindow>::SetScrollbars(pixelsPerUnitX, pixelsPerUnitY, noUnitsX, noUnitsY, xPos, yPos, noRefresh);
|
||
|
wxScrolled<wxWindow>::SetVirtualSize(pixelsPerUnitX * noUnitsX, pixelsPerUnitY * noUnitsY); // So that GetVirtualSize gives good values
|
||
|
if (m_rightScrollbar) m_rightScrollbar->SetVirtualDim(pixelsPerUnitY, noUnitsY);
|
||
|
if (m_bottomScrollbar) m_bottomScrollbar->SetVirtualDim(pixelsPerUnitX, noUnitsX);
|
||
|
}
|
||
|
|
||
|
void ScrolledWindow::OnSize(wxSizeEvent &event)
|
||
|
{
|
||
|
int startX, startY, virtX, virtY, clientW, clientH;
|
||
|
|
||
|
if (!m_verticalSplitter && !m_horizontalSplitter) return;
|
||
|
|
||
|
GetViewStart(&startX, &startY);
|
||
|
GetVirtualSize(&virtX, &virtY);
|
||
|
GetClientSize(&clientW, &clientH);
|
||
|
|
||
|
// trace / log in the output / console window
|
||
|
// wxString str; str.sprintf("Actual=(%d,%d). Virtual=(%d,%d)\n", clientW, clientH, virtX, virtY); OutputDebugString(str);
|
||
|
if (m_verticalSplitter) m_verticalSplitter->SetSize(clientW, clientH);
|
||
|
if (m_horizontalSplitter) m_horizontalSplitter->SetSize(clientW, clientH);
|
||
|
|
||
|
if (m_rightScrollbar) {
|
||
|
if (clientH >= virtY) // hide the scrollbar by enlarging the user panel
|
||
|
{
|
||
|
// m_verticalSplitter->SetSashPosition(clientW);
|
||
|
m_userPanel->SetSize(GetClientSize());
|
||
|
m_rightScrollbar->SetSize(0, clientH);
|
||
|
m_userPanel->Refresh();
|
||
|
m_userPanel->Update();
|
||
|
} else {
|
||
|
// m_verticalSplitter->SetSashPosition(clientW - m_marginWidth); // resize the splitter panes
|
||
|
}
|
||
|
m_rightScrollbar->SetViewStart(startY);
|
||
|
m_rightScrollbar->Refresh();
|
||
|
m_rightScrollbar->Update(); // we want to repaint
|
||
|
}
|
||
|
if (m_bottomScrollbar) {
|
||
|
if (clientW >= virtX) // hide the scrollbar by enlarging the user panel
|
||
|
{
|
||
|
m_horizontalSplitter->SetSashPosition(clientH); // we don't need horizontal scrollbar
|
||
|
if (m_rightScrollbar)
|
||
|
m_userPanel->SetSize(clientW - m_marginWidth, clientH); // don't hide the vertical scrollbar
|
||
|
else
|
||
|
m_userPanel->SetSize(GetClientSize());
|
||
|
|
||
|
m_bottomScrollbar->SetSize(clientW, 0);
|
||
|
m_userPanel->Refresh();
|
||
|
m_userPanel->Update();
|
||
|
} else {
|
||
|
m_horizontalSplitter->SetSashPosition(clientH - m_marginWidth); // resize the splitter panes
|
||
|
}
|
||
|
m_bottomScrollbar->SetViewStart(startX);
|
||
|
m_bottomScrollbar->Refresh();
|
||
|
m_bottomScrollbar->Update(); // we want to repaint even if the panel gets smaller
|
||
|
}
|
||
|
Layout();
|
||
|
AdjustScrollbars();
|
||
|
}
|
||
|
|
||
|
void ScrolledWindow::OnScroll(wxScrollWinEvent &event)
|
||
|
{
|
||
|
int startX, startY;
|
||
|
GetViewStart(&startX, &startY);
|
||
|
if (m_rightScrollbar) {
|
||
|
m_rightScrollbar->SetViewStart(startY);
|
||
|
m_rightScrollbar->Refresh();
|
||
|
m_rightScrollbar->Update();
|
||
|
}
|
||
|
if (m_bottomScrollbar) {
|
||
|
m_bottomScrollbar->SetViewStart(startX);
|
||
|
m_bottomScrollbar->Refresh();
|
||
|
m_bottomScrollbar->Update();
|
||
|
}
|
||
|
// event.Skip(); // then do the regular process // uncomment if you want to use the mouse and the trackpad in the scrolled panel
|
||
|
}
|