diff options
Diffstat (limited to 'wx+')
-rw-r--r-- | wx+/context_menu.h | 8 | ||||
-rw-r--r-- | wx+/dc.h | 11 | ||||
-rw-r--r-- | wx+/file_drop.cpp | 3 | ||||
-rw-r--r-- | wx+/graph.cpp | 8 | ||||
-rw-r--r-- | wx+/grid.cpp | 54 | ||||
-rw-r--r-- | wx+/grid.h | 41 | ||||
-rw-r--r-- | wx+/image_resources.cpp | 18 | ||||
-rw-r--r-- | wx+/no_flicker.h | 10 | ||||
-rw-r--r-- | wx+/popup_dlg.cpp | 12 | ||||
-rw-r--r-- | wx+/popup_dlg_generated.cpp | 24 | ||||
-rw-r--r-- | wx+/popup_dlg_generated.h | 19 | ||||
-rw-r--r-- | wx+/tooltip.cpp | 27 |
12 files changed, 149 insertions, 86 deletions
diff --git a/wx+/context_menu.h b/wx+/context_menu.h index d1d2bd9f..92d8504c 100644 --- a/wx+/context_menu.h +++ b/wx+/context_menu.h @@ -126,6 +126,9 @@ void fixMenuIcons(wxMenu& menu) } +//better call wxClipboard::Get()->Flush() *once* during app exit instead of after each setClipboardText()? +// => OleFlushClipboard: "Carries out the clipboard shutdown sequence" +// => maybe this helps with clipboard randomly "forgetting" content after app exit? inline void setClipboardText(const wxString& txt) { @@ -133,9 +136,8 @@ void setClipboardText(const wxString& txt) if (clip.Open()) { ZEN_ON_SCOPE_EXIT(clip.Close()); - [[maybe_unused]] const bool rv1 = clip.SetData(new wxTextDataObject(txt)); //ownership passed - [[maybe_unused]] const bool rv2 = clip.Flush(); - assert(rv1 && rv2); + [[maybe_unused]] const bool rv = clip.SetData(new wxTextDataObject(txt)); //ownership passed + assert(rv); } else assert(false); } @@ -147,6 +147,14 @@ void setScaleFactor(wxDC& dc, double scale) } +//add some sanity to moronic const/non-const wxRect::Intersect() +inline +wxRect getIntersection(const wxRect& rect1, const wxRect& rect2) +{ + return rect1.Intersect(rect2); +} + + //---------------------- implementation ------------------------ class RecursiveDcClipper { @@ -158,8 +166,7 @@ public: { oldRect_ = it->second; - wxRect tmp = r; - tmp.Intersect(*oldRect_); //better safe than sorry + const wxRect tmp = getIntersection(r, *oldRect_); //better safe than sorry assert(!tmp.IsEmpty()); //"setting an empty clipping region is equivalent to DestroyClippingRegion()" diff --git a/wx+/file_drop.cpp b/wx+/file_drop.cpp index 86db57c1..cd233c56 100644 --- a/wx+/file_drop.cpp +++ b/wx+/file_drop.cpp @@ -60,8 +60,7 @@ private: filePaths.push_back(utfTo<Zstring>(file)); //create a custom event on drop window: execute event after file dropping is completed! (after mouse is released) - if (wxEvtHandler* handler = dropWindow_.GetEventHandler()) - handler->AddPendingEvent(FileDropEvent(filePaths)); + dropWindow_.GetEventHandler()->AddPendingEvent(FileDropEvent(filePaths)); return true; } diff --git a/wx+/graph.cpp b/wx+/graph.cpp index ce65d299..07268f34 100644 --- a/wx+/graph.cpp +++ b/wx+/graph.cpp @@ -247,7 +247,7 @@ void cutPoints(std::vector<CurvePoint>& curvePoints, std::vector<unsigned char>& auto savePoint = [&](const CurvePoint& pt, bool markedOob) { curvePointsTmp.push_back(pt); oobMarkerTmp.push_back(markedOob); }; - bool pointInside = isInside(curvePoints[0]); + bool pointInside = isInside(curvePoints[0]); if (pointInside) savePoint(curvePoints[0], isMarkedOob(0)); @@ -283,7 +283,7 @@ void cutPoints(std::vector<CurvePoint>& curvePoints, std::vector<unsigned char>& struct GetIntersectionX { explicit GetIntersectionX(double x) : x_(x) {} - + CurvePoint operator()(const CurvePoint& from, const CurvePoint& to) const { const double deltaX = to.x - from.x; @@ -493,9 +493,7 @@ void Graph2D::onMouseLeftUp(wxMouseEvent& event) { if (activeSel_->getStartPos() != activeSel_->refCurrentPos()) //if it's just a single mouse click: discard selection { - GraphSelectEvent selEvent(activeSel_->refSelection()); //fire off GraphSelectEvent - if (wxEvtHandler* handler = GetEventHandler()) - handler->AddPendingEvent(selEvent); + GetEventHandler()->AddPendingEvent(GraphSelectEvent(activeSel_->refSelection())); oldSel_.push_back(activeSel_->refSelection()); //commit selection } diff --git a/wx+/grid.cpp b/wx+/grid.cpp index 0ffee3a7..f997d72c 100644 --- a/wx+/grid.cpp +++ b/wx+/grid.cpp @@ -295,9 +295,7 @@ public: template <class T> 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); - return false; + return parent_.GetEventHandler()->ProcessEvent(event); } protected: @@ -1412,8 +1410,7 @@ private: if (!gridUpdatePending_) //without guarding, the number of outstanding async events can become very high during scrolling!! test case: Ubuntu: 170; Windows: 20 { gridUpdatePending_ = true; - wxCommandEvent scrollEvent(EVENT_GRID_HAS_SCROLLED); - AddPendingEvent(scrollEvent); //asynchronously call updateAfterScroll() + GetEventHandler()->AddPendingEvent(wxCommandEvent(EVENT_GRID_HAS_SCROLLED)); //asynchronously call updateAfterScroll() } } @@ -1776,8 +1773,7 @@ void Grid::onKeyDown(wxKeyEvent& event) const wxPoint mousePos = mainWin_->GetPosition() + wxPoint(0, clientPosMainWinY); //mainWin_-relative to Grid-relative GridContextMenuEvent contextEvent(mousePos); - if (wxEvtHandler* evtHandler = GetEventHandler()) - evtHandler->ProcessEvent(contextEvent); + GetEventHandler()->ProcessEvent(contextEvent); } return; @@ -1907,19 +1903,21 @@ void Grid::selectRange(size_t rowFirst, size_t rowLast, bool positive, GridEvent void Grid::selectRange2(size_t rowFirst, size_t rowLast, bool positive, const GridClickEvent* mouseClick, GridEventPolicy rangeEventPolicy) { assert(rowFirst <= rowLast); + assert(getRowCount() == selection_.gridSize()); + rowFirst = std::clamp<size_t>(rowFirst, 0, selection_.gridSize()); + rowLast = std::clamp<size_t>(rowLast, 0, selection_.gridSize()); - const size_t rowCount = getRowCount(); - rowFirst = std::clamp<size_t>(rowFirst, 0, rowCount); - rowLast = std::clamp<size_t>(rowLast, 0, rowCount); - - selection_.selectRange(rowFirst, rowLast, positive); - mainWin_->Refresh(); + if (rowFirst < rowLast && !selection_.matchesRange(rowFirst, rowLast, positive)) + { + selection_.selectRange(rowFirst, rowLast, positive); + mainWin_->Refresh(); + } + //issue event even for unchanged selection! e.g. MainWin::onMouseDown() temporarily clears range with GridEventPolicy::deny! if (rangeEventPolicy == GridEventPolicy::allow) { GridSelectEvent selEvent(rowFirst, rowLast, positive, mouseClick); - if (wxEvtHandler* evtHandler = GetEventHandler()) - [[maybe_unused]] const bool processed = evtHandler->ProcessEvent(selEvent); + [[maybe_unused]] const bool processed = GetEventHandler()->ProcessEvent(selEvent); } } @@ -1962,8 +1960,19 @@ void Grid::Refresh(bool eraseBackground, const wxRect* rect) updateWindowSizes(); } - if (selection_.gridSize() != rowCountNew) //clear selection only when needed (consider setSelectedRows()) - selection_.init(rowCountNew); + if (selection_.gridSize() != rowCountNew) + { + const bool priorSelection = !selection_.matchesRange(0, selection_.gridSize(), false /*positive*/); + + selection_.resize(rowCountNew); + + if (priorSelection) //clear selection only when needed + { + //clearSelection(GridEventPolicy::allow); -> no, we need async event to make filegrid::refresh(*m_gridMainL, *m_gridMainC, *m_gridMainR) work + selection_.clear(); + GetEventHandler()->AddPendingEvent(GridSelectEvent(0, rowCountNew, false /*positive*/, nullptr /*mouseClick*/)); + } + } wxScrolledWindow::Refresh(eraseBackground, rect); } @@ -2306,13 +2315,10 @@ void Grid::setColumnWidth(int width, size_t col, GridEventPolicy columnResizeEve if (columnResizeEventPolicy == GridEventPolicy::allow) { GridColumnResizeEvent sizeEvent(vcRs.offset, vcRs.type); - if (wxEvtHandler* evtHandler = GetEventHandler()) - { - if (notifyAsync) - evtHandler->AddPendingEvent(sizeEvent); - else - evtHandler->ProcessEvent(sizeEvent); - } + if (notifyAsync) + GetEventHandler()->AddPendingEvent(sizeEvent); + else + GetEventHandler()->ProcessEvent(sizeEvent); } } else @@ -97,9 +97,6 @@ struct GridContextMenuEvent : public wxEvent }; //------------------------------------------------------------------------------------------------------------ -class Grid; - - class GridData { public: @@ -113,21 +110,21 @@ public: virtual void renderCell (wxDC& dc, const wxRect& rect, size_t row, ColumnType colType, bool enabled, bool selected, HoverArea rowHover); virtual int getBestSize (wxDC& dc, size_t row, ColumnType colType); //must correspond to renderCell()! virtual HoverArea getMouseHover (wxDC& dc, size_t row, ColumnType colType, int cellRelativePosX, int cellWidth) { return HoverArea::none; } - virtual std::wstring getToolTip (size_t row, ColumnType colType, HoverArea rowHover) { return std::wstring(); } + virtual std::wstring getToolTip ( size_t row, ColumnType colType, HoverArea rowHover) { return std::wstring(); } //label area: virtual std::wstring getColumnLabel(ColumnType colType) const = 0; virtual void renderColumnLabel(wxDC& dc, const wxRect& rect, ColumnType colType, bool enabled, bool highlighted); //default implementation virtual std::wstring getToolTip(ColumnType colType) const { return std::wstring(); } + //optional helper routines: static int getColumnGapLeft(); //for left-aligned text static wxColor getColorSelectionGradientFrom(); static wxColor getColorSelectionGradientTo(); - //optional helper routines: static void drawCellText(wxDC& dc, const wxRect& rect, const std::wstring& text, - int alignment = wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, const wxSize* textExtentHint = nullptr); //returns text extent - static wxRect drawCellBorder (wxDC& dc, const wxRect& rect); //returns inner rectangle + int alignment = wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, const wxSize* textExtentHint = nullptr); + static wxRect drawCellBorder(wxDC& dc, const wxRect& rect); //returns inner rectangle static wxRect drawColumnLabelBackground(wxDC& dc, const wxRect& rect, bool highlighted); //returns inner rectangle static void drawColumnLabelText (wxDC& dc, const wxRect& rect, const std::wstring& text, bool enabled); @@ -253,7 +250,7 @@ private: class Selection { public: - void init(size_t rowCount) { selected_.resize(rowCount); clear(); } + void resize(size_t rowCount) { selected_.resize(rowCount, false); } size_t gridSize() const { return selected_.size(); } @@ -266,20 +263,30 @@ private: return result; } - void clear() { selectRange(0, selected_.size(), false); } - bool isSelected(size_t row) const { return row < selected_.size() ? selected_[row] != 0 : false; } - void selectRange(size_t rowFirst, size_t rowLast, bool positive = true) //select [rowFirst, rowLast), trims if required! + bool matchesRange(size_t rowFirst, size_t rowLast, bool positive) { - if (rowFirst <= rowLast) + if (rowFirst <= rowLast && rowLast <= selected_.size()) { - rowFirst = std::clamp<size_t>(rowFirst, 0, selected_.size()); - rowLast = std::clamp<size_t>(rowLast, 0, selected_.size()); - - std::fill(selected_.begin() + rowFirst, selected_.begin() + rowLast, positive); + const auto rangeEnd = selected_.begin() + rowLast; + return std::find(selected_.begin() + rowFirst, rangeEnd, static_cast<unsigned char>(!positive)) == rangeEnd; } - else assert(false); + else + { + assert(false); + return false; + } + } + + void clear() { selectRange(0, selected_.size(), false); } + + void selectRange(size_t rowFirst, size_t rowLast, bool positive = true) //select [rowFirst, rowLast), trims if required! + { + assert(rowFirst <= rowLast && rowLast <= selected_.size()); + if (rowFirst < rowLast) + std::fill(selected_.begin() + std::min(rowFirst, selected_.size()), + selected_.begin() + std::min(rowLast, selected_.size()), positive); } private: diff --git a/wx+/image_resources.cpp b/wx+/image_resources.cpp index 667b5912..823e867e 100644 --- a/wx+/image_resources.cpp +++ b/wx+/image_resources.cpp @@ -70,7 +70,7 @@ ImageHolder xbrzScale(int width, int height, const unsigned char* imageRgb, cons } -auto createScalerTask(const std::string& imageName, const wxImage& img, int hqScale, Protected<std::vector<std::pair<std::string, ImageHolder>>>& result) +auto createScalerTask(const std::string& imageName, const wxImage& img, int hqScale, Protected<std::vector<std::pair<std::string, ImageHolder>>>& protResult) { assert(runningOnMainThread()); return [imageName, @@ -78,10 +78,10 @@ auto createScalerTask(const std::string& imageName, const wxImage& img, int hqSc height = img.GetHeight(), //don't call wxWidgets functions from worker thread rgb = img.GetData(), // alpha = img.GetAlpha(), // - hqScale, &result] + hqScale, &protResult] { ImageHolder ih = xbrzScale(width, height, rgb, alpha, hqScale); - result.access([&](std::vector<std::pair<std::string, ImageHolder>>& r) { r.emplace_back(imageName, std::move(ih)); }); + protResult.access([&](std::vector<std::pair<std::string, ImageHolder>>& result) { result.emplace_back(imageName, std::move(ih)); }); }; } @@ -97,7 +97,7 @@ public: { assert(runningOnMainThread()); imgKeeper_.push_back(img); //retain (ref-counted) wxImage so that the rgb/alpha pointers remain valid after passed to threads - threadGroup_->run(createScalerTask(imageName, img, hqScale_, result_)); + threadGroup_->run(createScalerTask(imageName, img, hqScale_, protResult_)); } std::unordered_map<std::string, wxImage> waitAndGetResult() @@ -107,9 +107,9 @@ public: std::unordered_map<std::string, wxImage> output; - result_.access([&](std::vector<std::pair<std::string, ImageHolder>>& r) + protResult_.access([&](std::vector<std::pair<std::string, ImageHolder>>& result) { - for (auto& [imageName, ih] : r) + for (auto& [imageName, ih] : result) { wxImage img(ih.getWidth(), ih.getHeight(), ih.releaseRgb(), false /*static_data*/); //pass ownership img.SetAlpha(ih.releaseAlpha(), false /*static_data*/); @@ -123,7 +123,7 @@ public: private: const int hqScale_; std::vector<wxImage> imgKeeper_; - Protected<std::vector<std::pair<std::string, ImageHolder>>> result_; + Protected<std::vector<std::pair<std::string, ImageHolder>>> protResult_; using TaskType = FunctionReturnTypeT<decltype(&createScalerTask)>; std::optional<ThreadGroup<TaskType>> threadGroup_{ThreadGroup<TaskType>(std::max<int>(std::thread::hardware_concurrency(), 1), Zstr("xBRZ Scaler"))}; @@ -195,7 +195,7 @@ ImageBuffer::ImageBuffer(const Zstring& zipPath) //throw FileError catch (FileError&) //fall back to folder: dev build (only!?) { const Zstring fallbackFolder = beforeLast(zipPath, Zstr(".zip"), IfNotFoundReturn::none); - if (!itemStillExists(fallbackFolder)) //throw FileError + if (!itemExists(fallbackFolder)) //throw FileError throw; traverseFolder(fallbackFolder, [&](const FileInfo& fi) @@ -205,7 +205,7 @@ ImageBuffer::ImageBuffer(const Zstring& zipPath) //throw FileError std::string stream = getFileContent(fi.fullPath, nullptr /*notifyUnbufferedIO*/); //throw FileError streams.emplace_back(fi.itemName, std::move(stream)); } - }, nullptr, nullptr, [](const std::wstring& errorMsg) { throw FileError(errorMsg); }); + }, nullptr, nullptr); //throw FileError } //-------------------------------------------------------------------- diff --git a/wx+/no_flicker.h b/wx+/no_flicker.h index 185ee052..1c91bd48 100644 --- a/wx+/no_flicker.h +++ b/wx+/no_flicker.h @@ -123,7 +123,7 @@ void setTextWithUrls(wxRichTextCtrl& richCtrl, const wxString& newText) using KeyEventsFun = void(*)(wxKeyEvent& event); static const KeyEventsFun onKeyEvents = [](wxKeyEvent& event) { - wxRichTextCtrl& richCtrl = dynamic_cast<UserData*>(event.GetEventUserData())->richCtrl; //unclear if we can rely on event.GetEventObject() == richCtrl + wxRichTextCtrl& richCtrl2 = dynamic_cast<UserData*>(event.GetEventUserData())->richCtrl; //unclear if we can rely on event.GetEventObject() == richCtrl //CTRL/SHIFT + INS is broken for wxRichTextCtrl on Windows/Linux (apparently never was a thing on macOS) if (event.ControlDown()) @@ -131,8 +131,8 @@ void setTextWithUrls(wxRichTextCtrl& richCtrl, const wxString& newText) { case WXK_INSERT: case WXK_NUMPAD_INSERT: - assert(richCtrl.CanCopy()); //except when no selection - richCtrl.Copy(); + assert(richCtrl2.CanCopy()); //except when no selection + richCtrl2.Copy(); return; } @@ -141,8 +141,8 @@ void setTextWithUrls(wxRichTextCtrl& richCtrl, const wxString& newText) { case WXK_INSERT: case WXK_NUMPAD_INSERT: - assert(richCtrl.CanPaste()); //except wxTE_READONLY - richCtrl.Paste(); + assert(richCtrl2.CanPaste()); //except wxTE_READONLY + richCtrl2.Paste(); return; } event.Skip(); diff --git a/wx+/popup_dlg.cpp b/wx+/popup_dlg.cpp index dfa5494f..c30426cb 100644 --- a/wx+/popup_dlg.cpp +++ b/wx+/popup_dlg.cpp @@ -150,15 +150,9 @@ public: if (iconTmp.IsOk()) setImage(*m_bitmapMsgType, iconTmp); - if (titleTmp.empty()) - SetTitle(wxTheApp->GetAppDisplayName()); - else - { - if (parent && parent->IsShownOnScreen()) - SetTitle(titleTmp); - else - SetTitle(wxTheApp->GetAppDisplayName() + SPACED_DASH + titleTmp); - } + if (!parent || !parent->IsShownOnScreen()) + titleTmp = wxTheApp->GetAppDisplayName() + (!titleTmp.empty() ? SPACED_DASH + titleTmp : wxString()); + SetTitle(titleTmp); int maxWidth = fastFromDIP(500); int maxHeight = fastFromDIP(400); //try to determine better value based on actual display resolution: diff --git a/wx+/popup_dlg_generated.cpp b/wx+/popup_dlg_generated.cpp index fb449d13..b7e3d94d 100644 --- a/wx+/popup_dlg_generated.cpp +++ b/wx+/popup_dlg_generated.cpp @@ -98,3 +98,27 @@ PopupDialogGenerated::PopupDialogGenerated( wxWindow* parent, wxWindowID id, con PopupDialogGenerated::~PopupDialogGenerated() { } + +TooltipDlgGenerated::TooltipDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer158; + bSizer158 = new wxBoxSizer( wxHORIZONTAL ); + + m_bitmapLeft = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); + bSizer158->Add( m_bitmapLeft, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_staticTextMain = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMain->Wrap( 600 ); + bSizer158->Add( m_staticTextMain, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + + + this->SetSizer( bSizer158 ); + this->Layout(); + bSizer158->Fit( this ); +} + +TooltipDlgGenerated::~TooltipDlgGenerated() +{ +} diff --git a/wx+/popup_dlg_generated.h b/wx+/popup_dlg_generated.h index 6218c6d8..ce4e2ac8 100644 --- a/wx+/popup_dlg_generated.h +++ b/wx+/popup_dlg_generated.h @@ -70,3 +70,22 @@ public: }; +/////////////////////////////////////////////////////////////////////////////// +/// Class TooltipDlgGenerated +/////////////////////////////////////////////////////////////////////////////// +class TooltipDlgGenerated : public wxDialog +{ +private: + +protected: + +public: + wxStaticBitmap* m_bitmapLeft; + wxStaticText* m_staticTextMain; + + TooltipDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + + ~TooltipDlgGenerated(); + +}; + diff --git a/wx+/tooltip.cpp b/wx+/tooltip.cpp index a3fa770d..c56d80a1 100644 --- a/wx+/tooltip.cpp +++ b/wx+/tooltip.cpp @@ -27,10 +27,9 @@ const int TIP_WINDOW_OFFSET_DIP = 30; class Tooltip::TooltipDlgGenerated : public wxDialog { public: - TooltipDlgGenerated(wxWindow* parent) : wxDialog(parent, wxID_ANY, L"" /*title*/, wxDefaultPosition, wxDefaultSize, 0 /*style*/) + TooltipDlgGenerated(wxWindow* parent) : //Suse Linux/X11: needs parent window, else there are z-order issues + wxDialog(parent, wxID_ANY, L"" /*title*/, wxDefaultPosition, wxDefaultSize, 0 /*style*/) { - //Suse Linux/X11: needs parent window, else there are z-order issues - SetSizeHints(wxDefaultSize, wxDefaultSize); SetExtraStyle(this->GetExtraStyle() | wxWS_EX_TRANSIENT); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK)); //both required: on Ubuntu background is black, foreground white! @@ -44,11 +43,11 @@ public: bSizer158->Add(staticTextMain_, 0, wxALL | wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL, 5); SetSizer(bSizer158); - Layout(); - bSizer158->Fit(this); } + bool AcceptsFocus() const override { return false; } //any benefit? + wxStaticText* staticTextMain_ = nullptr; wxStaticBitmap* bitmapLeft_ = nullptr; }; @@ -61,21 +60,28 @@ void Tooltip::show(const wxString& text, wxPoint mousePos, const wxImage* img) const wxImage& newImg = img ? *img : wxNullImage; - if (!lastUsedImg_.IsSameAs(newImg)) + const bool imgChanged = !newImg.IsSameAs(lastUsedImg_); + const bool txtChanged = text != tipWindow_->staticTextMain_->GetLabelText(); + + if (imgChanged) { lastUsedImg_ = newImg; setImage(*tipWindow_->bitmapLeft_, newImg); - tipWindow_->Refresh(); //needed if bitmap size changed! + // tipWindow_->Refresh(); //needed if bitmap size changed! ->??? } - if (text != tipWindow_->staticTextMain_->GetLabelText()) + if (txtChanged) { tipWindow_->staticTextMain_->SetLabelText(text); tipWindow_->staticTextMain_->Wrap(fastFromDIP(600)); } - tipWindow_->GetSizer()->SetSizeHints(tipWindow_); //~=Fit() + SetMinSize() - //Linux: Fit() seems to be broken => this needs to be called EVERY time inside show, not only if text or bmp change + if (imgChanged || txtChanged) + { + //tipWindow_->Layout(); -> apparently not needed!? + tipWindow_->GetSizer()->SetSizeHints(tipWindow_); //~=Fit() + SetMinSize() + //Linux: Fit() seems to be broken => call EVERY time inside show, not only if text or bmp change -> still true?!? + } const wxPoint newPos = wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft ? mousePos - wxPoint(fastFromDIP(TIP_WINDOW_OFFSET_DIP) + tipWindow_->GetSize().GetWidth(), 0) : @@ -98,6 +104,7 @@ void Tooltip::hide() #if GTK_MAJOR_VERSION == 2 //the tooltip sometimes turns blank or is not shown again after it was hidden: e.g. drag-selection on middle grid tipWindow_->Destroy(); //apply brute force: tipWindow_ = nullptr; // + lastUsedImg_ = wxNullImage; #elif GTK_MAJOR_VERSION == 3 tipWindow_->Hide(); |