diff options
Diffstat (limited to 'ui/triple_splitter.cpp')
-rw-r--r-- | ui/triple_splitter.cpp | 241 |
1 files changed, 0 insertions, 241 deletions
diff --git a/ui/triple_splitter.cpp b/ui/triple_splitter.cpp deleted file mode 100644 index fbdd22d7..00000000 --- a/ui/triple_splitter.cpp +++ /dev/null @@ -1,241 +0,0 @@ -// ************************************************************************** -// * This file is part of the FreeFileSync project. It is distributed under * -// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * -// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved * -// ************************************************************************** - -#include "triple_splitter.h" -#include <algorithm> - -using namespace zen; - - -namespace -{ -//------------ Grid Constants ------------------------------- -const int SASH_HIT_TOLERANCE = 5; //currently only a placebo! -const int SASH_SIZE = 10; -const double SASH_GRAVITY = 0.5; //value within [0, 1]; 1 := resize left only, 0 := resize right only -const int CHILD_WINDOW_MIN_SIZE = 50; //min. size of managed windows - -const wxColor COLOR_SASH_GRADIENT_FROM = wxColour(192, 192, 192); //light grey -const wxColor COLOR_SASH_GRADIENT_TO = *wxWHITE; -} - -TripleSplitter::TripleSplitter(wxWindow* parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style) : wxWindow(parent, id, pos, size, style | wxTAB_TRAVERSAL), //tab between windows - centerOffset(0), - windowL(nullptr), - windowC(nullptr), - windowR(nullptr) -{ - Connect(wxEVT_PAINT, wxPaintEventHandler(TripleSplitter::onPaintEvent ), nullptr, this); - Connect(wxEVT_SIZE, wxSizeEventHandler (TripleSplitter::onSizeEvent ), nullptr, this); - //http://wiki.wxwidgets.org/Flicker-Free_Drawing - Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(TripleSplitter::onEraseBackGround), nullptr, this); - - SetBackgroundStyle(wxBG_STYLE_PAINT); - - Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(TripleSplitter::onMouseLeftDown ), nullptr, this); - Connect(wxEVT_LEFT_UP, wxMouseEventHandler(TripleSplitter::onMouseLeftUp ), nullptr, this); - Connect(wxEVT_MOTION, wxMouseEventHandler(TripleSplitter::onMouseMovement ), nullptr, this); - Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(TripleSplitter::onLeaveWindow ), nullptr, this); - Connect(wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEventHandler(TripleSplitter::onMouseCaptureLost), nullptr, this); - Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(TripleSplitter::onMouseLeftDouble), nullptr, this); -} - - -TripleSplitter::~TripleSplitter() {} //make sure correct destructor gets created for std::unique_ptr<SashMove> - - -void TripleSplitter::updateWindowSizes() -{ - if (windowL && windowC && windowR) - { - const int centerPosX = getCenterPosX(); - const int centerWidth = getCenterWidth(); - - const wxRect clientRect = GetClientRect(); - - const int widthL = centerPosX; - const int windowRposX = widthL + centerWidth; - const int widthR = clientRect.width - windowRposX; - - windowL->SetSize(0, 0, widthL, clientRect.height); - windowC->SetSize(widthL + SASH_SIZE, 0, windowC->GetSize().GetWidth(), clientRect.height); - windowR->SetSize(windowRposX, 0, widthR, clientRect.height); - - wxClientDC dc(this); - drawSash(dc); - } -} - - -class TripleSplitter::SashMove -{ -public: - SashMove(wxWindow& wnd, int mousePosX, int centerOffset) : wnd_(wnd), mousePosX_(mousePosX), centerOffset_(centerOffset) - { - wnd_.SetCursor(wxCURSOR_SIZEWE); - wnd_.CaptureMouse(); - } - ~SashMove() - { - wnd_.SetCursor(*wxSTANDARD_CURSOR); - if (wnd_.HasCapture()) - wnd_.ReleaseMouse(); - } - int getMousePosXStart () const { return mousePosX_; } - int getCenterOffsetStart() const { return centerOffset_; } - -private: - wxWindow& wnd_; - const int mousePosX_; - const int centerOffset_; -}; - - -inline -int TripleSplitter::getCenterWidth() const -{ - return 2 * SASH_SIZE + (windowC ? windowC->GetSize().GetWidth() : 0); -} - - -int TripleSplitter::getCenterPosXOptimal() const -{ - const wxRect clientRect = GetClientRect(); - const int centerWidth = getCenterWidth(); - return (clientRect.width - centerWidth) * SASH_GRAVITY; //allowed to be negative for extreme client widths! -} - - -int TripleSplitter::getCenterPosX() const -{ - const wxRect clientRect = GetClientRect(); - const int centerWidth = getCenterWidth(); - const int centerPosXOptimal = getCenterPosXOptimal(); - - //normalize "centerPosXOptimal + centerOffset" - if (clientRect.width < 2 * CHILD_WINDOW_MIN_SIZE + centerWidth) - //use fixed "centeroffset" when "clientRect.width == 2 * CHILD_WINDOW_MIN_SIZE + centerWidth" - return centerPosXOptimal + CHILD_WINDOW_MIN_SIZE - static_cast<int>(2 * CHILD_WINDOW_MIN_SIZE * SASH_GRAVITY); //avoid rounding error - //make sure transition between conditional branches is continuous! - return std::max(CHILD_WINDOW_MIN_SIZE, //make sure centerPosXOptimal + offset is within bounds - std::min(centerPosXOptimal + centerOffset, clientRect.width - CHILD_WINDOW_MIN_SIZE - centerWidth)); -} - - -void TripleSplitter::drawSash(wxDC& dc) -{ - const int centerPosX = getCenterPosX(); - const int centerWidth = getCenterWidth(); - - auto draw = [&](wxRect rect) - { - const int sash2ndHalf = 3; - rect.width -= sash2ndHalf; - dc.GradientFillLinear(rect, COLOR_SASH_GRADIENT_FROM, COLOR_SASH_GRADIENT_TO, wxEAST); - - rect.x += rect.width; - rect.width = sash2ndHalf; - dc.GradientFillLinear(rect, COLOR_SASH_GRADIENT_FROM, COLOR_SASH_GRADIENT_TO, wxWEST); - - static_assert(SASH_SIZE > sash2ndHalf, ""); - }; - - const wxRect rectSashL(centerPosX, 0, SASH_SIZE, GetClientRect().height); - const wxRect rectSashR(centerPosX + centerWidth - SASH_SIZE, 0, SASH_SIZE, GetClientRect().height); - - draw(rectSashL); - draw(rectSashR); -} - - -bool TripleSplitter::hitOnSashLine(int posX) const -{ - const int centerPosX = getCenterPosX(); - const int centerWidth = getCenterWidth(); - - //we don't get events outside of sash, so SASH_HIT_TOLERANCE is currently *useless* - auto hitSash = [&](int sashX) { return sashX - SASH_HIT_TOLERANCE <= posX && posX < sashX + SASH_SIZE + SASH_HIT_TOLERANCE; }; - - return hitSash(centerPosX) || hitSash(centerPosX + centerWidth - SASH_SIZE); //hit one of the two sash lines -} - - -void TripleSplitter::onMouseLeftDown(wxMouseEvent& event) -{ - activeMove.reset(); - - const int posX = event.GetPosition().x; - if (hitOnSashLine(posX)) - activeMove.reset(new SashMove(*this, posX, centerOffset)); - event.Skip(); -} - - -void TripleSplitter::onMouseLeftUp(wxMouseEvent& event) -{ - activeMove.reset(); //nothing else to do, actual work done by onMouseMovement() - event.Skip(); -} - - -void TripleSplitter::onMouseMovement(wxMouseEvent& event) -{ - if (activeMove) - { - centerOffset = activeMove->getCenterOffsetStart() + event.GetPosition().x - activeMove->getMousePosXStart(); - - //CAVEAT: function getCenterPosX() normalizes centerPosX *not* centerOffset! - //This can lead to the strange effect of window not immediately resizing when centerOffset is extremely off limits - //=> normalize centerOffset right here - centerOffset = getCenterPosX() - getCenterPosXOptimal(); - - updateWindowSizes(); - Update(); //no time to wait until idle event! - } - else - { - //we receive those only while above the sash, not the managed windows (except when the managed windows are disabled!) - const int posX = event.GetPosition().x; - if (hitOnSashLine(posX)) - SetCursor(wxCURSOR_SIZEWE); //set window-local only! - else - SetCursor(*wxSTANDARD_CURSOR); - } - event.Skip(); -} - - -void TripleSplitter::onLeaveWindow(wxMouseEvent& event) -{ - //even called when moving from sash over to managed windows! - if (!activeMove) - SetCursor(*wxSTANDARD_CURSOR); - event.Skip(); -} - - -void TripleSplitter::onMouseCaptureLost(wxMouseCaptureLostEvent& event) -{ - activeMove.reset(); - updateWindowSizes(); - //event.Skip(); -> we DID handle it! -} - - -void TripleSplitter::onMouseLeftDouble(wxMouseEvent& event) -{ - const int posX = event.GetPosition().x; - if (hitOnSashLine(posX)) - { - centerOffset = 0; //reset sash according to gravity - updateWindowSizes(); - } - event.Skip(); -} |