diff options
author | B Stack <bgstack15@gmail.com> | 2019-03-13 10:36:44 +0000 |
---|---|---|
committer | B Stack <bgstack15@gmail.com> | 2019-03-13 10:36:44 +0000 |
commit | 2c01454a3fea1c29df0aeb208862243cb928b74c (patch) | |
tree | dc226d83311470a23cdf0c02064feb525fcc5096 /wx+ | |
parent | Merge branch '10.9' into 'master' (diff) | |
parent | 10.10 (diff) | |
download | FreeFileSync-2c01454a3fea1c29df0aeb208862243cb928b74c.tar.gz FreeFileSync-2c01454a3fea1c29df0aeb208862243cb928b74c.tar.bz2 FreeFileSync-2c01454a3fea1c29df0aeb208862243cb928b74c.zip |
Merge branch '10.10' into 'master'10.10
10.10
Latest changes:
* New option: synchronize selection
* Dynamically disable unsuitable context menu options
* Support MTP devices without move command
* Fall back to copy/delete when implicitly moving to different device (e.g. symlink)
* Fixed incorrect statistics after parallel move
* Fixed menu button not triggering context menu
* Fixed crash on focus change while message popup is dismissed
* Fixed crash when trying to shrink empty image
* Fixed invisible dialogs when monitor is turned off in multi-monitor setup
* Work around GetFileInformationByHandle error code 58 on WD My Cloud EX
* Changing deletion handling now correctly triggers updated config
* Support root-relative FTP file paths (e.g. FreeNAS)
* Move and rename MTP items as a transaction
* Exclude AppleDouble files (._) via default filter on macOS
* Support home path for FTP folder picker
* Use server default permissions when creating SFTP folder
* Use native OpenSSL AES-CTR rather than libssh2 fallback
* Added context information for cloud connection errors
* Updated translation files
See merge request opensource-tracking/FreeFileSync!7
Diffstat (limited to 'wx+')
-rw-r--r-- | wx+/grid.cpp | 74 | ||||
-rw-r--r-- | wx+/grid.h | 25 | ||||
-rw-r--r-- | wx+/image_resources.cpp | 2 | ||||
-rw-r--r-- | wx+/image_tools.h | 4 | ||||
-rw-r--r-- | wx+/popup_dlg.cpp | 1 | ||||
-rw-r--r-- | wx+/tooltip.cpp | 11 |
6 files changed, 90 insertions, 27 deletions
diff --git a/wx+/grid.cpp b/wx+/grid.cpp index 3c19c246..114bb82d 100644 --- a/wx+/grid.cpp +++ b/wx+/grid.cpp @@ -293,6 +293,7 @@ public: Connect(wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEventHandler(SubWindow::onMouseCaptureLost), nullptr, this); Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(SubWindow::onKeyDown), nullptr, this); + Connect(wxEVT_KEY_UP, wxKeyEventHandler(SubWindow::onKeyUp ), nullptr, this); assert(GetClientAreaOrigin() == wxPoint()); //generally assumed when dealing with coordinates below } @@ -300,7 +301,7 @@ public: const Grid& refParent() const { return parent_; } template <class T> - bool sendEventNow(T&& event) //take both "rvalue + lvalues", return "true" if a suitable event handler function was found and executed, and the function did not call wxEvent::Skip. + bool sendEventToParent(T&& event) //take both "rvalue + lvalues", return "true" if a suitable event handler function was found and executed, and the function did not call wxEvent::Skip. { if (wxEvtHandler* evtHandler = parent_.GetEventHandler()) return evtHandler->ProcessEvent(event); @@ -346,7 +347,13 @@ private: void onKeyDown(wxKeyEvent& event) { - if (!sendEventNow(event)) //let parent collect all key events + if (!sendEventToParent(event)) //let parent collect all key events + event.Skip(); + } + + void onKeyUp(wxKeyEvent& event) + { + if (!sendEventToParent(event)) //let parent collect all key events event.Skip(); } @@ -366,7 +373,7 @@ private: //=> call wxScrolledWindow mouse wheel handler directly parent_.HandleOnMouseWheel(event); - //if (!sendEventNow(event)) + //if (!sendEventToParent(event)) // event.Skip(); } @@ -723,7 +730,7 @@ private: else //notify single label click { if (const std::optional<ColumnType> colType = refParent().colToType(activeClickOrMove_->getColumnFrom())) - sendEventNow(GridLabelClickEvent(EVENT_GRID_COL_LABEL_MOUSE_LEFT, event, *colType)); + sendEventToParent(GridLabelClickEvent(EVENT_GRID_COL_LABEL_MOUSE_LEFT, *colType)); } activeClickOrMove_.reset(); } @@ -832,13 +839,13 @@ private: if (const std::optional<ColAction> action = refParent().clientPosToColumnAction(event.GetPosition())) { if (const std::optional<ColumnType> colType = refParent().colToType(action->col)) - sendEventNow(GridLabelClickEvent(EVENT_GRID_COL_LABEL_MOUSE_RIGHT, event, *colType)); //notify right click + sendEventToParent(GridLabelClickEvent(EVENT_GRID_COL_LABEL_MOUSE_RIGHT, *colType)); //notify right click else assert(false); } else //notify right click (on free space after last column) if (fillGapAfterColumns) - sendEventNow(GridLabelClickEvent(EVENT_GRID_COL_LABEL_MOUSE_RIGHT, event, ColumnType::NONE)); + sendEventToParent(GridLabelClickEvent(EVENT_GRID_COL_LABEL_MOUSE_RIGHT, ColumnType::NONE)); event.Skip(); } @@ -971,8 +978,10 @@ private: const ptrdiff_t row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 for invalid position; >= rowCount if out of range const ColumnPosInfo cpi = refParent().getColumnAtPos(absPos.x); //returns ColumnType::NONE if no column at x position! const HoverArea rowHover = prov->getRowMouseHover(row, cpi.colType, cpi.cellRelativePosX, cpi.colWidth); + const wxPoint mousePos = GetPosition() + event.GetPosition(); + //client is interested in all double-clicks, even those outside of the grid! - sendEventNow(GridClickEvent(EVENT_GRID_MOUSE_LEFT_DOUBLE, event, row, rowHover)); + sendEventToParent(GridClickEvent(EVENT_GRID_MOUSE_LEFT_DOUBLE, row, rowHover, mousePos)); } event.Skip(); } @@ -985,10 +994,11 @@ private: const ptrdiff_t row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 for invalid position; >= rowCount if out of range const ColumnPosInfo cpi = refParent().getColumnAtPos(absPos.x); //returns ColumnType::NONE if no column at x position! const HoverArea rowHover = prov->getRowMouseHover(row, cpi.colType, cpi.cellRelativePosX, cpi.colWidth); + const wxPoint mousePos = GetPosition() + event.GetPosition(); //row < 0 possible!!! Pressing "Menu Key" simulates mouse-right-button down + up at position 0xffff/0xffff! - GridClickEvent mouseEvent(event.RightDown() ? EVENT_GRID_MOUSE_RIGHT_DOWN : EVENT_GRID_MOUSE_LEFT_DOWN, event, row, rowHover); - if (!sendEventNow(mouseEvent)) //allow client to swallow event! + GridClickEvent mouseEvent(event.RightDown() ? EVENT_GRID_MOUSE_RIGHT_DOWN : EVENT_GRID_MOUSE_LEFT_DOWN, row, rowHover, mousePos); + if (!sendEventToParent(mouseEvent)) //allow client to swallow event! { if (wxWindow::FindFocus() != this) //doesn't seem to happen automatically for right mouse button SetFocus(); @@ -1057,8 +1067,9 @@ private: const ptrdiff_t row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 for invalid position; >= rowCount if out of range const ColumnPosInfo cpi = refParent().getColumnAtPos(absPos.x); //returns ColumnType::NONE if no column at x position! const HoverArea rowHover = prov->getRowMouseHover(row, cpi.colType, cpi.cellRelativePosX, cpi.colWidth); + const wxPoint mousePos = GetPosition() + event.GetPosition(); //notify click event after the range selection! e.g. this makes sure the selection is applied before showing a context menu - sendEventNow(GridClickEvent(event.RightUp() ? EVENT_GRID_MOUSE_RIGHT_UP : EVENT_GRID_MOUSE_LEFT_UP, event, row, rowHover)); + sendEventToParent(GridClickEvent(event.RightUp() ? EVENT_GRID_MOUSE_RIGHT_UP : EVENT_GRID_MOUSE_LEFT_UP, row, rowHover, mousePos)); } //update highlight_ and tooltip: on OS X no mouse movement event is generated after a mouse button click (unlike on Windows) @@ -1317,6 +1328,7 @@ Grid::Grid(wxWindow* parent, Bind(wxEVT_ERASE_BACKGROUND, [](wxEraseEvent& event) {}); //http://wiki.wxwidgets.org/Flicker-Free_Drawing Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(Grid::onKeyDown), nullptr, this); + Connect(wxEVT_KEY_UP, wxKeyEventHandler(Grid::onKeyUp ), nullptr, this); } @@ -1481,6 +1493,32 @@ wxSize Grid::GetSizeAvailableForScrollTarget(const wxSize& size) void Grid::onPaintEvent(wxPaintEvent& event) { wxPaintDC dc(this); } +void Grid::onKeyUp(wxKeyEvent& event) +{ + int keyCode = event.GetKeyCode(); + if (event.ShiftDown() && keyCode == WXK_F10) //== alias for menu key + keyCode = WXK_WINDOWS_MENU; + + switch (keyCode) + { + case WXK_MENU: // + case WXK_WINDOWS_MENU: //simulate right mouse click at cursor(+1) position + { + const int cursorNextPosY = rowLabelWin_->getRowHeight() * std::min(getRowCount(), mainWin_->getCursor() + 1); + const int clientPosMainWinY = std::clamp(CalcScrolledPosition(wxPoint(0, cursorNextPosY)).y, //absolute -> client coordinates + 0, mainWin_->GetClientSize().GetHeight() - 1); + const wxPoint mousePos = mainWin_->GetPosition() + wxPoint(0, clientPosMainWinY); //mainWin_-relative to Grid-relative + + GridClickEvent clickEvent(EVENT_GRID_MOUSE_RIGHT_UP, -1, HoverArea::NONE, mousePos); + if (wxEvtHandler* evtHandler = GetEventHandler()) + evtHandler->ProcessEvent(clickEvent); + } + return; + } + event.Skip(); +} + + void Grid::onKeyDown(wxKeyEvent& event) { int keyCode = event.GetKeyCode(); @@ -1491,6 +1529,8 @@ void Grid::onKeyDown(wxKeyEvent& event) else if (keyCode == WXK_RIGHT || keyCode == WXK_NUMPAD_RIGHT) keyCode = WXK_LEFT; } + if (event.ShiftDown() && keyCode == WXK_F10) //== alias for menu key + keyCode = WXK_WINDOWS_MENU; const ptrdiff_t rowCount = getRowCount(); const ptrdiff_t cursorRow = mainWin_->getCursor(); @@ -1515,6 +1555,20 @@ void Grid::onKeyDown(wxKeyEvent& event) switch (keyCode) { + case WXK_MENU: // + case WXK_WINDOWS_MENU: //simulate right mouse click at cursor(+1) position + { + const int cursorNextPosY = rowLabelWin_->getRowHeight() * std::min(getRowCount(), mainWin_->getCursor() + 1); + const int clientPosMainWinY = std::clamp(CalcScrolledPosition(wxPoint(0, cursorNextPosY)).y, //absolute -> client coordinates + 0, mainWin_->GetClientSize().GetHeight() - 1); + const wxPoint mousePos = mainWin_->GetPosition() + wxPoint(0, clientPosMainWinY); //mainWin_-relative to Grid-relative + + GridClickEvent clickEvent(EVENT_GRID_MOUSE_RIGHT_DOWN, -1, HoverArea::NONE, mousePos); + if (wxEvtHandler* evtHandler = GetEventHandler()) + evtHandler->ProcessEvent(clickEvent); + } + return; + //case WXK_TAB: // if (Navigate(event.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward)) // return; @@ -22,6 +22,10 @@ namespace zen enum class ColumnType { NONE = -1 }; //user-defiend column type enum class HoverArea { NONE = -1 }; //user-defined area for mouse selections for a given row (may span multiple columns or split a single column into multiple areas) +//wxContextMenuEvent? => automatically generated by wxWidgets when right mouse down/up is not handled; even OS-dependent in which case event is generated +//=> inappropriate! client decides when to show context! => simulate right mouse click when WXK_WINDOWS_MENU button is pressed +//=> same behavior as earlier wxWidgets: https://github.com/wxWidgets/wxWidgets/commit/2c69d27c0d225d3a331c773da466686153185320#diff-9f11c8f2cb1f734f7c0c1071aba491a5 + //------------------------ events ------------------------------------------------ extern const wxEventType EVENT_GRID_MOUSE_LEFT_DOUBLE; // extern const wxEventType EVENT_GRID_MOUSE_LEFT_DOWN; // @@ -38,21 +42,21 @@ extern const wxEventType EVENT_GRID_COL_RESIZE; //generates: GridColumnResizeEve //example: wnd.Connect(EVENT_GRID_COL_LABEL_LEFT_CLICK, GridClickEventHandler(MyDlg::OnLeftClick), nullptr, this); -struct GridClickEvent : public wxMouseEvent +struct GridClickEvent : public wxEvent { - GridClickEvent(wxEventType et, const wxMouseEvent& me, ptrdiff_t row, HoverArea hoverArea) : - wxMouseEvent(me), row_(row), hoverArea_(hoverArea) { SetEventType(et); } + GridClickEvent(wxEventType et, ptrdiff_t row, HoverArea hoverArea, const wxPoint& mousePos) : + wxEvent(0 /*winid*/, et), row_(row), hoverArea_(hoverArea), mousePos_(mousePos) {} GridClickEvent* Clone() const override { return new GridClickEvent(*this); } const ptrdiff_t row_; //-1 for invalid position, >= rowCount if out of range const HoverArea hoverArea_; //may be HoverArea::NONE + const wxPoint mousePos_; //client coordinates }; - -struct GridSelectEvent : public wxCommandEvent +struct GridSelectEvent : public wxEvent { GridSelectEvent(size_t rowFirst, size_t rowLast, bool positive, const GridClickEvent* mouseClick) : - wxCommandEvent(EVENT_GRID_SELECT_RANGE), rowFirst_(rowFirst), rowLast_(rowLast), positive_(positive), + wxEvent(0 /*winid*/, EVENT_GRID_SELECT_RANGE), rowFirst_(rowFirst), rowLast_(rowLast), positive_(positive), mouseClick_(mouseClick ? *mouseClick : std::optional<GridClickEvent>()) { assert(rowFirst <= rowLast); } GridSelectEvent* Clone() const override { return new GridSelectEvent(*this); } @@ -62,17 +66,17 @@ struct GridSelectEvent : public wxCommandEvent const std::optional<GridClickEvent> mouseClick_; //filled unless selection was performed via keyboard shortcuts }; -struct GridLabelClickEvent : public wxMouseEvent +struct GridLabelClickEvent : public wxEvent { - GridLabelClickEvent(wxEventType et, const wxMouseEvent& me, ColumnType colType) : wxMouseEvent(me), colType_(colType) { SetEventType(et); } + GridLabelClickEvent(wxEventType et, ColumnType colType) : wxEvent(0 /*winid*/, et), colType_(colType) {} GridLabelClickEvent* Clone() const override { return new GridLabelClickEvent(*this); } const ColumnType colType_; //may be ColumnType::NONE }; -struct GridColumnResizeEvent : public wxCommandEvent +struct GridColumnResizeEvent : public wxEvent { - GridColumnResizeEvent(int offset, ColumnType colType) : wxCommandEvent(EVENT_GRID_COL_RESIZE), colType_(colType), offset_(offset) {} + GridColumnResizeEvent(int offset, ColumnType colType) : wxEvent(0 /*winid*/, EVENT_GRID_COL_RESIZE), colType_(colType), offset_(offset) {} GridColumnResizeEvent* Clone() const override { return new GridColumnResizeEvent(*this); } const ColumnType colType_; @@ -224,6 +228,7 @@ private: void onPaintEvent(wxPaintEvent& event); void onSizeEvent(wxSizeEvent& event) { updateWindowSizes(); event.Skip(); } void onKeyDown(wxKeyEvent& event); + void onKeyUp (wxKeyEvent& event); void updateWindowSizes(bool updateScrollbar = true); diff --git a/wx+/image_resources.cpp b/wx+/image_resources.cpp index 5bc8006f..faabbb2a 100644 --- a/wx+/image_resources.cpp +++ b/wx+/image_resources.cpp @@ -88,7 +88,7 @@ auto getScalerTask(const wxString& name, const wxImage& img, int hqScale, Protec width = img.GetWidth(), height = img.GetHeight(), dpiWidth = fastFromDIP(img.GetWidth()), - dpiHeight = fastFromDIP(img.GetHeight()), //don't call fastFromDIP() from worker thread (wxWidgets function!) + dpiHeight = fastFromDIP(img.GetHeight()), //don't call (wxWidgets function!) fastFromDIP() from worker thread rgb = img.GetData(), alpha = img.GetAlpha(), hqScale, &result] diff --git a/wx+/image_tools.h b/wx+/image_tools.h index e1a6953c..b1df41e6 100644 --- a/wx+/image_tools.h +++ b/wx+/image_tools.h @@ -187,6 +187,10 @@ wxImage shrinkImage(const wxImage& img, int requestedSize) { const int maxExtent = std::max(img.GetWidth(), img.GetHeight()); assert(requestedSize <= maxExtent); + + if (requestedSize >= maxExtent) + return img; + return img.Scale(img.GetWidth () * requestedSize / maxExtent, img.GetHeight() * requestedSize / maxExtent, wxIMAGE_QUALITY_BILINEAR); //looks sharper than wxIMAGE_QUALITY_HIGH! } diff --git a/wx+/popup_dlg.cpp b/wx+/popup_dlg.cpp index 689b364e..8ee44521 100644 --- a/wx+/popup_dlg.cpp +++ b/wx+/popup_dlg.cpp @@ -113,7 +113,6 @@ public: int maxWidth = fastFromDIP(500); int maxHeight = fastFromDIP(400); //try to determine better value based on actual display resolution: - //int [maxWidth, maxHeight] = wxSize(fastFromDIP(500), fastFromDIP(400)); if (parent) { diff --git a/wx+/tooltip.cpp b/wx+/tooltip.cpp index a7bf85fe..03025049 100644 --- a/wx+/tooltip.cpp +++ b/wx+/tooltip.cpp @@ -30,9 +30,10 @@ public: { //Suse Linux/X11: needs parent window, else there are z-order issues - this->SetSizeHints(wxDefaultSize, wxDefaultSize); - this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK)); //both required: on Ubuntu background is black, foreground white! - this->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT)); // + SetSizeHints(wxDefaultSize, wxDefaultSize); + SetExtraStyle(this->GetExtraStyle() | wxWS_EX_TRANSIENT); + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK)); //both required: on Ubuntu background is black, foreground white! + SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT)); // wxBoxSizer* bSizer158 = new wxBoxSizer(wxHORIZONTAL); bitmapLeft_ = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0); @@ -41,8 +42,8 @@ public: staticTextMain_ = new wxStaticText(this, wxID_ANY, wxString(), wxDefaultPosition, wxDefaultSize, 0); bSizer158->Add(staticTextMain_, 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5); - this->SetSizer(bSizer158); - this->Layout(); + SetSizer(bSizer158); + Layout(); bSizer158->Fit(this); } |