include/vcl/toolkit/svlbitm.hxx | 1 include/vcl/toolkit/treelistbox.hxx | 1 sfx2/source/dialog/StyleList.cxx | 5 ++-- vcl/inc/jsdialog/jsdialogbuilder.hxx | 33 ++++++++++++++++++++++++++++- vcl/jsdialog/jsdialogbuilder.cxx | 39 +++++++++++++++++++---------------- vcl/source/treelist/svtabbx.cxx | 6 +++-- 6 files changed, 63 insertions(+), 22 deletions(-)
New commits: commit 990c4f2ac632305a09c09be0c4c89f91e3785d3b Author: Szymon Kłos <[email protected]> AuthorDate: Wed Jan 22 18:39:49 2025 +0100 Commit: Caolán McNamara <[email protected]> CommitDate: Thu Jul 3 09:41:54 2025 +0200 jsdialog: handle custom rendering in treeview Client can demand rendering of custom entries for treeview. Used in style list sidebar to render font previews. Let's use more width for LOK to fit all text into image. Core seems to ignore it and render based on size of passed device. Change-Id: If21b33a7e5ce36a5304b6aa2b8218f3b3460ea26 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186789 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> diff --git a/include/vcl/toolkit/svlbitm.hxx b/include/vcl/toolkit/svlbitm.hxx index b4001287d012..0a7968a27fd8 100644 --- a/include/vcl/toolkit/svlbitm.hxx +++ b/include/vcl/toolkit/svlbitm.hxx @@ -129,6 +129,7 @@ public: bool IsEmphasized() const { return mbEmphasized; } void SetCustomRender() { mbCustom = true; } + bool IsCustomRender() const { return mbCustom; } const OUString& GetText() const { diff --git a/include/vcl/toolkit/treelistbox.hxx b/include/vcl/toolkit/treelistbox.hxx index 78db5bcc2231..47850505cc52 100644 --- a/include/vcl/toolkit/treelistbox.hxx +++ b/include/vcl/toolkit/treelistbox.hxx @@ -188,6 +188,7 @@ class UNLESS_MERGELIBS_MORE(VCL_DLLPUBLIC) SvTreeListBox friend class SalInstanceIconView; friend class SalInstanceTreeView; friend class SalInstanceEntryTreeView; + friend class JSTreeView; std::unique_ptr<SvTreeListBoxImpl> mpImpl; Link<SvTreeListBox*,void> aScrolledHdl; diff --git a/sfx2/source/dialog/StyleList.cxx b/sfx2/source/dialog/StyleList.cxx index c62b125ceb37..2363ca06749d 100644 --- a/sfx2/source/dialog/StyleList.cxx +++ b/sfx2/source/dialog/StyleList.cxx @@ -1781,7 +1781,7 @@ IMPL_LINK(StyleList, CustomRenderHdl, weld::TreeView::render_args, aPayload, voi ::tools::Rectangle aRect( rRect.TopLeft(), Size(rRenderContext.GetOutputSize().Width() - rRect.Left(), rRect.GetHeight())); - bool bSelected = std::get<2>(aPayload); + bool bSelected = comphelper::LibreOfficeKit::isActive() ? false : std::get<2>(aPayload); const OUString& rId = std::get<3>(aPayload); rRenderContext.Push(vcl::PushFlags::TEXTCOLOR); @@ -1980,7 +1980,8 @@ const SfxStyleFamilyItem& StyleList::GetFamilyItemByIndex(size_t i) const IMPL_STATIC_LINK(StyleList, CustomGetSizeHdl, weld::TreeView::get_size_args, aPayload, Size) { vcl::RenderContext& rRenderContext = aPayload.first; - return Size(42, 32 * rRenderContext.GetDPIScaleFactor()); + return Size(comphelper::LibreOfficeKit::isActive() ? 200 : 42, + 32 * rRenderContext.GetDPIScaleFactor()); } IMPL_LINK(StyleList, PopupFlatMenuHdl, const CommandEvent&, rCEvt, bool) diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx index 4fbed1fbde23..29bd359bbf38 100644 --- a/vcl/inc/jsdialog/jsdialogbuilder.hxx +++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx @@ -13,7 +13,9 @@ #include <jsdialog/jsdialogmessages.hxx> #include <jsdialog/jsdialogsender.hxx> +#include <tools/stream.hxx> #include <utility> +#include <vcl/cvtgrf.hxx> #include <vcl/weld.hxx> #include <vcl/virdev.hxx> #include <salvtables.hxx> @@ -24,6 +26,8 @@ #include <com/sun/star/lang/XInitialization.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> + +#include <comphelper/base64.hxx> #include <comphelper/compbase.hxx> #include <list> @@ -256,6 +260,29 @@ class SAL_LOPLUGIN_ANNOTATE("crosscast") OnDemandRenderingHandler { public: virtual void render_entry(int pos, int dpix, int dpiy) = 0; + + static bool imageToActionData(const BitmapEx& rImage, sal_Int32 nPos, + jsdialog::ActionDataMap& rMap) + { + if (rImage.IsEmpty()) + return false; + + SvMemoryStream aOStm(65535, 65535); + + if (GraphicConverter::Export(aOStm, rImage, ConvertDataFormat::PNG) != ERRCODE_NONE) + return false; + + css::uno::Sequence<sal_Int8> aSeq(static_cast<sal_Int8 const*>(aOStm.GetData()), + aOStm.Tell()); + OUStringBuffer aBuffer("data:image/png;base64,"); + ::comphelper::Base64::encode(aBuffer, aSeq); + + rMap[ACTION_TYPE ""_ostr] = "rendered_entry"; + rMap["pos"_ostr] = OUString::number(nPos); + rMap["image"_ostr] = aBuffer; + + return true; + } }; template <class BaseInstanceClass, class VclClass> @@ -675,7 +702,8 @@ public: virtual void replace_selection(const OUString& rText) override; }; -class JSTreeView final : public JSWidget<SalInstanceTreeView, ::SvTabListBox> +class JSTreeView final : public JSWidget<SalInstanceTreeView, ::SvTabListBox>, + public OnDemandRenderingHandler { public: JSTreeView(JSDialogSender* pSender, ::SvTabListBox* pTextView, SalInstanceBuilder* pBuilder, @@ -721,6 +749,9 @@ public: void drag_start(); void drag_end(); + + // OnDemandRenderingHandler + virtual void render_entry(int pos, int dpix, int dpiy) override; }; class JSExpander final : public JSWidget<SalInstanceExpander, ::VclExpander> diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx index 3e2981446836..580d96a70826 100644 --- a/vcl/jsdialog/jsdialogbuilder.cxx +++ b/vcl/jsdialog/jsdialogbuilder.cxx @@ -9,9 +9,7 @@ #include <jsdialog/jsdialogbuilder.hxx> #include <sal/log.hxx> -#include <comphelper/base64.hxx> #include <iconview.hxx> -#include <utility> #include <vcl/menu.hxx> #include <vcl/svapp.hxx> #include <vcl/toolbox.hxx> @@ -26,8 +24,7 @@ #include <memory> #include <vcl/jsdialog/executor.hxx> #include <cppuhelper/supportsservice.hxx> -#include <tools/stream.hxx> -#include <vcl/cvtgrf.hxx> + #include <wizdlg.hxx> #include <jsdialog/enabled.hxx> @@ -1331,20 +1328,9 @@ void JSComboBox::render_entry(int pos, int dpix, int dpiy) BitmapEx aImage = pDevice->GetBitmapEx(Point(0, 0), aRenderSize); - SvMemoryStream aOStm(65535, 65535); - if (GraphicConverter::Export(aOStm, aImage, ConvertDataFormat::PNG) == ERRCODE_NONE) - { - css::uno::Sequence<sal_Int8> aSeq(static_cast<sal_Int8 const*>(aOStm.GetData()), - aOStm.Tell()); - OUStringBuffer aBuffer("data:image/png;base64,"); - ::comphelper::Base64::encode(aBuffer, aSeq); - - std::unique_ptr<jsdialog::ActionDataMap> pMap = std::make_unique<jsdialog::ActionDataMap>(); - (*pMap)[ACTION_TYPE ""_ostr] = "rendered_entry"; - (*pMap)["pos"_ostr] = OUString::number(pos); - (*pMap)["image"_ostr] = aBuffer; + std::unique_ptr<jsdialog::ActionDataMap> pMap = std::make_unique<jsdialog::ActionDataMap>(); + if (OnDemandRenderingHandler::imageToActionData(aImage, pos, *pMap)) sendAction(std::move(pMap)); - } } JSNotebook::JSNotebook(JSDialogSender* pSender, ::TabControl* pControl, @@ -1863,6 +1849,25 @@ void JSTreeView::collapse_row(const weld::TreeIter& rIter) sendUpdate(); } +void JSTreeView::render_entry(int pos, int dpix, int dpiy) +{ + ScopedVclPtrInstance<VirtualDevice> pDevice(DeviceFormat::WITHOUT_ALPHA); + pDevice->SetDPIX(96.0 * dpix / 100); + pDevice->SetDPIY(96.0 * dpiy / 100); + + SvTreeListEntry* rEntry = m_xTreeView->GetEntryAtAbsPos(pos); + + Size aRenderSize = signal_custom_get_size(*pDevice, get_id(pos)); + pDevice->SetOutputSize(aRenderSize); + m_xTreeView->DrawCustomEntry(*pDevice, tools::Rectangle(Point(0, 0), aRenderSize), *rEntry); + + BitmapEx aImage = pDevice->GetBitmapEx(Point(0, 0), aRenderSize); + + std::unique_ptr<jsdialog::ActionDataMap> pMap = std::make_unique<jsdialog::ActionDataMap>(); + if (OnDemandRenderingHandler::imageToActionData(aImage, pos, *pMap)) + sendAction(std::move(pMap)); +} + JSExpander::JSExpander(JSDialogSender* pSender, ::VclExpander* pExpander, SalInstanceBuilder* pBuilder, bool bTakeOwnership) : JSWidget<SalInstanceExpander, ::VclExpander>(pSender, pExpander, pBuilder, bTakeOwnership) diff --git a/vcl/source/treelist/svtabbx.cxx b/vcl/source/treelist/svtabbx.cxx index 97db9d8749b1..14dc8387d8ff 100644 --- a/vcl/source/treelist/svtabbx.cxx +++ b/vcl/source/treelist/svtabbx.cxx @@ -100,9 +100,11 @@ static void lcl_DumpEntryAndSiblings(tools::JsonWriter& rJsonWriter, rJsonWriter.put("text", pStringItem->GetText()); SvLBoxTab* pTab = pTabListBox->GetTab( pEntry, &rItem ); - if ( pTab ) { + if ( pTab ) rJsonWriter.put("editable", pTab->IsEditable()); - } + + if (pStringItem->IsCustomRender()) + rJsonWriter.put("customEntryRenderer", true); } } else if (rItem.GetType() == SvLBoxItemType::ContextBmp)
