summaryrefslogtreecommitdiff
path: root/vcl/source
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-04-03 19:30:00 +0100
committerCaolán McNamara <caolanm@redhat.com>2020-04-04 19:51:52 +0200
commit338403833ec43539728d7609e243ae6070aafb3f (patch)
treef2f779bfd2ebff714b74c953b76706fc46d40fd6 /vcl/source
parent6ff081689573217621a4ef012755fc5e351359af (diff)
add ability to have custom renderer treeview rows
Change-Id: Ia085242dee0aaa19f9aefa2a3cf71bc827fcca73 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91658 Tested-by: Jenkins Tested-by: Caolán McNamara <caolanm@redhat.com> Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/source')
-rw-r--r--vcl/source/app/salvtables.cxx52
-rw-r--r--vcl/source/treelist/svlbitm.cxx23
-rw-r--r--vcl/source/treelist/treelistbox.cxx10
-rw-r--r--vcl/source/window/builder.cxx19
4 files changed, 96 insertions, 8 deletions
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index d43dda8ffec1..1ae61d3ee21a 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -3263,6 +3263,8 @@ private:
// currently expanding parent that logically, but not currently physically,
// contain placeholders
o3tl::sorted_vector<SvTreeListEntry*> m_aExpandingPlaceHolderParents;
+ // which columns should be custom rendered
+ o3tl::sorted_vector<int> m_aCustomRenders;
bool m_bDisableCheckBoxAutoWidth;
int m_nSortColumn;
@@ -3283,6 +3285,8 @@ private:
DECL_LINK(CompareHdl, const SvSortData&, sal_Int32);
DECL_LINK(PopupMenuHdl, const CommandEvent&, bool);
DECL_LINK(TooltipHdl, const HelpEvent&, bool);
+ DECL_LINK(CustomRenderHdl, svtree_render_args, void);
+ DECL_LINK(CustomMeasureHdl, svtree_measure_args, Size);
bool IsDummyEntry(SvTreeListEntry* pEntry) const
{
@@ -3309,6 +3313,14 @@ private:
pEntry->SetTextColor(rColor);
}
+ void AddStringItem(SvTreeListEntry* pEntry, const OUString& rStr, int nCol)
+ {
+ auto xCell = std::make_unique<SvLBoxString>(rStr);
+ if (m_aCustomRenders.count(nCol))
+ xCell->SetCustomRender();
+ pEntry->AddItem(std::move(xCell));
+ }
+
public:
SalInstanceTreeView(SvTabListBox* pTreeView, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
: SalInstanceContainer(pTreeView, pBuilder, bTakeOwnership)
@@ -3325,6 +3337,8 @@ public:
m_xTreeView->SetDoubleClickHdl(LINK(this, SalInstanceTreeView, DoubleClickHdl));
m_xTreeView->SetExpandingHdl(LINK(this, SalInstanceTreeView, ExpandingHdl));
m_xTreeView->SetPopupMenuHdl(LINK(this, SalInstanceTreeView, PopupMenuHdl));
+ m_xTreeView->SetCustomRenderHdl(LINK(this, SalInstanceTreeView, CustomRenderHdl));
+ m_xTreeView->SetCustomMeasureHdl(LINK(this, SalInstanceTreeView, CustomMeasureHdl));
const long aTabPositions[] = { 0 };
m_xTreeView->SetTabs(SAL_N_ELEMENTS(aTabPositions), aTabPositions);
LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get());
@@ -3452,6 +3466,11 @@ public:
}
}
+ virtual void set_column_custom_renderer(int nColumn) override
+ {
+ m_aCustomRenders.insert(nColumn);
+ }
+
virtual void show() override
{
if (LclHeaderTabListBox* pHeaderBox = dynamic_cast<LclHeaderTabListBox*>(m_xTreeView.get()))
@@ -3496,7 +3515,7 @@ public:
pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(aDummy, aDummy, false));
}
if (pStr)
- pEntry->AddItem(std::make_unique<SvLBoxString>(*pStr));
+ AddStringItem(pEntry, *pStr, 0);
pEntry->SetUserData(pUserData);
m_xTreeView->Insert(pEntry, iter, nInsertPos);
@@ -3744,11 +3763,11 @@ public:
// blank out missing entries
for (int i = pEntry->ItemCount(); i < col; ++i)
- pEntry->AddItem(std::make_unique<SvLBoxString>(""));
+ AddStringItem(pEntry, "", i - 1);
if (static_cast<size_t>(col) == pEntry->ItemCount())
{
- pEntry->AddItem(std::make_unique<SvLBoxString>(rText));
+ AddStringItem(pEntry, rText, col - 1);
SvViewDataEntry* pViewData = m_xTreeView->GetViewDataEntry(pEntry);
m_xTreeView->InitViewData(pViewData, pEntry);
}
@@ -3833,7 +3852,7 @@ public:
// blank out missing entries
for (int i = pEntry->ItemCount(); i < col; ++i)
- pEntry->AddItem(std::make_unique<SvLBoxString>(""));
+ AddStringItem(pEntry, "", i - 1);
if (static_cast<size_t>(col) == pEntry->ItemCount())
{
@@ -3989,7 +4008,7 @@ public:
// blank out missing entries
for (int i = pEntry->ItemCount(); i < col; ++i)
- pEntry->AddItem(std::make_unique<SvLBoxString>(""));
+ AddStringItem(pEntry, "", i - 1);
if (static_cast<size_t>(col) == pEntry->ItemCount())
{
@@ -4598,6 +4617,8 @@ public:
m_xTreeView->SetDeselectHdl(Link<SvTreeListBox*, void>());
m_xTreeView->SetScrolledHdl(Link<SvTreeListBox*, void>());
m_xTreeView->SetTooltipHdl(Link<const HelpEvent&, bool>());
+ m_xTreeView->SetCustomRenderHdl(Link<svtree_render_args, void>());
+ m_xTreeView->SetCustomMeasureHdl(Link<svtree_measure_args, Size>());
}
};
@@ -4621,6 +4642,27 @@ IMPL_LINK(SalInstanceTreeView, TooltipHdl, const HelpEvent&, rHEvt, bool)
return true;
}
+IMPL_LINK(SalInstanceTreeView, CustomRenderHdl, svtree_render_args, payload, void)
+{
+ vcl::RenderContext& rRenderDevice = std::get<0>(payload);
+ const tools::Rectangle& rRect = std::get<1>(payload);
+ const SvTreeListEntry& rEntry = std::get<2>(payload);
+ const OUString* pId = static_cast<const OUString*>(rEntry.GetUserData());
+ if (!pId)
+ return;
+ signal_custom_render(rRenderDevice, rRect, m_xTreeView->IsSelected(&rEntry), *pId);
+}
+
+IMPL_LINK(SalInstanceTreeView, CustomMeasureHdl, svtree_measure_args, payload, Size)
+{
+ vcl::RenderContext& rRenderDevice = payload.first;
+ const SvTreeListEntry& rEntry = payload.second;
+ const OUString* pId = static_cast<const OUString*>(rEntry.GetUserData());
+ if (!pId)
+ return Size();
+ return signal_custom_get_size(rRenderDevice, *pId);
+}
+
IMPL_LINK(SalInstanceTreeView, CompareHdl, const SvSortData&, rSortData, sal_Int32)
{
const SvTreeListEntry* pLHS = rSortData.pLeft;
diff --git a/vcl/source/treelist/svlbitm.cxx b/vcl/source/treelist/svlbitm.cxx
index 20407f71af2b..8fff9071dcdb 100644
--- a/vcl/source/treelist/svlbitm.cxx
+++ b/vcl/source/treelist/svlbitm.cxx
@@ -174,6 +174,7 @@ bool SvLBoxButtonData::IsRadio() const {
SvLBoxString::SvLBoxString(const OUString& rStr)
: mbEmphasized(false)
+ , mbCustom(false)
, mfAlign(0.0)
, maText(rStr)
{
@@ -181,6 +182,7 @@ SvLBoxString::SvLBoxString(const OUString& rStr)
SvLBoxString::SvLBoxString()
: mbEmphasized(false)
+ , mbCustom(false)
, mfAlign(0.0)
{
}
@@ -235,7 +237,12 @@ void SvLBoxString::Paint(
rRenderContext.SetFont(aFont);
}
- rRenderContext.DrawText(tools::Rectangle(rPos, aSize), maText, nStyle);
+ tools::Rectangle aRect(rPos, aSize);
+
+ if (mbCustom)
+ rDev.DrawCustomEntry(rRenderContext, aRect, rEntry);
+ else
+ rRenderContext.DrawText(aRect, maText, nStyle);
if (mbEmphasized)
rRenderContext.Pop();
@@ -248,6 +255,7 @@ std::unique_ptr<SvLBoxItem> SvLBoxString::Clone(SvLBoxItem const * pSource) cons
const SvLBoxString* pOther = static_cast<const SvLBoxString*>(pSource);
pNew->maText = pOther->maText;
pNew->mbEmphasized = pOther->mbEmphasized;
+ pNew->mbCustom = pOther->mbCustom;
pNew->mfAlign = pOther->mfAlign;
return std::unique_ptr<SvLBoxItem>(pNew.release());
@@ -267,8 +275,17 @@ void SvLBoxString::InitViewData(
pView->Control::SetFont( aFont );
}
- pViewData->mnWidth = -1; // calc on demand
- pViewData->mnHeight = pView->GetTextHeight();
+ if (mbCustom)
+ {
+ Size aSize = pView->MeasureCustomEntry(*pView, *pEntry);
+ pViewData->mnWidth = aSize.Width();
+ pViewData->mnHeight = aSize.Height();
+ }
+ else
+ {
+ pViewData->mnWidth = -1; // calc on demand
+ pViewData->mnHeight = pView->GetTextHeight();
+ }
if (mbEmphasized)
pView->Pop();
diff --git a/vcl/source/treelist/treelistbox.cxx b/vcl/source/treelist/treelistbox.cxx
index a57b0e45b24e..f54e184356d4 100644
--- a/vcl/source/treelist/treelistbox.cxx
+++ b/vcl/source/treelist/treelistbox.cxx
@@ -2868,6 +2868,16 @@ void SvTreeListBox::PreparePaint(vcl::RenderContext& /*rRenderContext*/, SvTreeL
{
}
+void SvTreeListBox::DrawCustomEntry(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect, const SvTreeListEntry& rEntry)
+{
+ aCustomRenderHdl.Call(std::tuple<vcl::RenderContext&, const tools::Rectangle&, const SvTreeListEntry&>(rRenderContext, rRect, rEntry));
+}
+
+Size SvTreeListBox::MeasureCustomEntry(vcl::RenderContext& rRenderContext, const SvTreeListEntry& rEntry)
+{
+ return aCustomMeasureHdl.Call(std::pair<vcl::RenderContext&, const SvTreeListEntry&>(rRenderContext, rEntry));
+}
+
tools::Rectangle SvTreeListBox::GetFocusRect(const SvTreeListEntry* pEntry, long nLine )
{
pImpl->UpdateContextBmpWidthMax( pEntry );
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index f3ed31051d94..a7ea94053e7c 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -441,6 +441,25 @@ namespace weld
return nAbsPos;
}
+
+ bool IsEntryVisible(const weld::TreeView& rTreeView, const weld::TreeIter& rIter)
+ {
+ // short circuit for the common case
+ if (rTreeView.get_iter_depth(rIter) == 0)
+ return true;
+
+ std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator(&rIter));
+ bool bRetVal = false;
+ do
+ {
+ if (rTreeView.get_iter_depth(*xEntry) == 0)
+ {
+ bRetVal = true;
+ break;
+ }
+ } while (rTreeView.iter_parent(*xEntry) && rTreeView.get_row_expanded(*xEntry));
+ return bRetVal;
+ }
}
VclBuilder::VclBuilder(vcl::Window* pParent, const OUString& sUIDir, const OUString& sUIFile,