[Libreoffice-commits] core.git: sd/inc sd/Library_sd.mk sd/source sd/uiconfig solenv/clang-format solenv/sanitizers
Caolán McNamara (via logerrit)
logerrit at kemper.freedesktop.org
Mon Apr 6 19:25:20 UTC 2020
sd/Library_sd.mk | 1
sd/inc/strings.hrc | 1
sd/source/ui/animations/CategoryListBox.cxx | 93 -
sd/source/ui/animations/CategoryListBox.hxx | 45
sd/source/ui/animations/CustomAnimationDialog.cxx | 9
sd/source/ui/animations/CustomAnimationDialog.hxx | 8
sd/source/ui/animations/CustomAnimationList.cxx | 1116 ++++++++------------
sd/source/ui/animations/CustomAnimationList.hxx | 92 +
sd/source/ui/animations/CustomAnimationPane.cxx | 622 +++++------
sd/source/ui/animations/CustomAnimationPane.hxx | 67 -
sd/uiconfig/simpress/ui/customanimationfragment.ui | 6
sd/uiconfig/simpress/ui/customanimationspanel.ui | 212 ++-
sd/uiconfig/simpress/ui/customanimationtimingtab.ui | 14
sd/uiconfig/simpress/ui/effectmenu.ui | 10
sd/uiconfig/simpress/ui/slidetransitionspanel.ui | 38
solenv/clang-format/blacklist | 2
solenv/sanitizers/ui/modules/simpress.suppr | 1
17 files changed, 1097 insertions(+), 1240 deletions(-)
New commits:
commit 21e8ce9ab9a522d25e95773af59b7ccccaee4e54
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Mar 24 11:44:16 2020 +0000
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Mon Apr 6 21:24:40 2020 +0200
weld custom animation panel
and align animation panel and slide transitions panel padding/spacing
Change-Id: I25a1d10894de635ebb9c8a1cba358940886125c2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91006
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk
index 048a0c4f1edc..43b168be8d8c 100644
--- a/sd/Library_sd.mk
+++ b/sd/Library_sd.mk
@@ -183,7 +183,6 @@ $(eval $(call gb_Library_add_exception_objects,sd,\
sd/source/ui/accessibility/AccessibleSlideSorterView \
sd/source/ui/accessibility/AccessibleViewForwarder \
sd/source/ui/accessibility/SdShapeTypes \
- sd/source/ui/animations/CategoryListBox \
sd/source/ui/animations/CustomAnimationDialog \
sd/source/ui/animations/CustomAnimationList \
sd/source/ui/animations/CustomAnimationPane \
diff --git a/sd/inc/strings.hrc b/sd/inc/strings.hrc
index 26ec246e19b3..84cfea801a70 100644
--- a/sd/inc/strings.hrc
+++ b/sd/inc/strings.hrc
@@ -444,7 +444,6 @@
#define STR_CUSTOMANIMATION_BROWSE_SOUND NC_("STR_CUSTOMANIMATION_BROWSE_SOUND", "Other sound...")
#define STR_CUSTOMANIMATION_SAMPLE NC_("STR_CUSTOMANIMATION_SAMPLE", "Sample")
#define STR_CUSTOMANIMATION_TRIGGER NC_("STR_CUSTOMANIMATION_TRIGGER", "Trigger")
-#define STR_CUSTOMANIMATION_LIST_HELPTEXT NC_("STR_CUSTOMANIMATION_LIST_HELPTEXT", "First select the slide element and then click 'Add...' to add an animation effect.")
#define STR_CUSTOMANIMATION_USERPATH NC_("STR_CUSTOMANIMATION_USERPATH", "User paths")
#define STR_CUSTOMANIMATION_ENTRANCE NC_("STR_CUSTOMANIMATION_ENTRANCE", "Entrance: %1")
#define STR_CUSTOMANIMATION_EMPHASIS NC_("STR_CUSTOMANIMATION_EMPHASIS", "Emphasis: %1")
diff --git a/sd/source/ui/animations/CategoryListBox.cxx b/sd/source/ui/animations/CategoryListBox.cxx
deleted file mode 100644
index 054cb84acdcd..000000000000
--- a/sd/source/ui/animations/CategoryListBox.cxx
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include "CategoryListBox.hxx"
-#include <vcl/builderfactory.hxx>
-
-#include <vcl/event.hxx>
-
-namespace sd {
-
-CategoryListBox::CategoryListBox( vcl::Window* pParent )
-: ListBox( pParent, WB_TABSTOP | WB_BORDER )
-{
- EnableUserDraw( true );
- SetDoubleClickHdl( LINK( this, CategoryListBox, implDoubleClickHdl ) );
-}
-
-VCL_BUILDER_FACTORY(CategoryListBox)
-
-CategoryListBox::~CategoryListBox()
-{
-}
-
-void CategoryListBox::InsertCategory( const OUString& rStr )
-{
- sal_Int32 n = ListBox::InsertEntry( rStr );
- if( n != LISTBOX_ENTRY_NOTFOUND )
- ListBox::SetEntryFlags( n, ListBox::GetEntryFlags(n) | ListBoxEntryFlags::DisableSelection );
-}
-
-void CategoryListBox::UserDraw( const UserDrawEvent& rUDEvt )
-{
- const sal_uInt16 nItem = rUDEvt.GetItemId();
-
- if( ListBox::GetEntryFlags(nItem) & ListBoxEntryFlags::DisableSelection )
- {
- ::tools::Rectangle aOutRect( rUDEvt.GetRect() );
- vcl::RenderContext* pDev = rUDEvt.GetRenderContext();
-
- // fill the background
- Color aColor (GetSettings().GetStyleSettings().GetDialogColor());
-
- pDev->SetFillColor (aColor);
- pDev->SetLineColor ();
- pDev->DrawRect(aOutRect);
-
- // Erase the four corner pixels to make the rectangle appear rounded.
- pDev->SetLineColor( GetSettings().GetStyleSettings().GetWindowColor());
- pDev->DrawPixel( aOutRect.TopLeft());
- pDev->DrawPixel( Point(aOutRect.Right(), aOutRect.Top()));
- pDev->DrawPixel( Point(aOutRect.Left(), aOutRect.Bottom()));
- pDev->DrawPixel( Point(aOutRect.Right(), aOutRect.Bottom()));
-
- // draw the category title
- pDev->DrawText (aOutRect, GetEntry(nItem), DrawTextFlags::Center );
- }
- else
- {
- DrawEntry( rUDEvt );
- }
-}
-
-IMPL_LINK_NOARG(CategoryListBox, implDoubleClickHdl, ListBox&, void)
-{
- CaptureMouse();
-}
-
-void CategoryListBox::MouseButtonUp( const MouseEvent& rMEvt )
-{
- ReleaseMouse();
- if (!( rMEvt.IsLeft() && (rMEvt.GetClicks() == 2) ))
- {
- ListBox::MouseButtonUp( rMEvt );
- }
-}
-
-}
diff --git a/sd/source/ui/animations/CategoryListBox.hxx b/sd/source/ui/animations/CategoryListBox.hxx
deleted file mode 100644
index 8ae5af8365eb..000000000000
--- a/sd/source/ui/animations/CategoryListBox.hxx
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifndef INCLUDED_SD_SOURCE_UI_ANIMATIONS_CATEGORYLISTBOX_HXX
-#define INCLUDED_SD_SOURCE_UI_ANIMATIONS_CATEGORYLISTBOX_HXX
-
-#include <vcl/lstbox.hxx>
-
-namespace sd {
-
-class CategoryListBox : public ListBox
-{
-public:
- explicit CategoryListBox( vcl::Window* pParent );
- virtual ~CategoryListBox() override;
-
- virtual void MouseButtonUp( const MouseEvent& rMEvt ) override;
-
- void InsertCategory( const OUString& rStr );
-
- DECL_LINK(implDoubleClickHdl, ListBox&, void);
-
-private:
- virtual void UserDraw( const UserDrawEvent& rUDEvt ) override;
-};
-
-}
-
-#endif // INCLUDED_SD_SOURCE_UI_ANIMATIONS_CATEGORYLISTBOX_HXX
diff --git a/sd/source/ui/animations/CustomAnimationDialog.cxx b/sd/source/ui/animations/CustomAnimationDialog.cxx
index 3c60f179b493..c62a7381f3bf 100644
--- a/sd/source/ui/animations/CustomAnimationDialog.cxx
+++ b/sd/source/ui/animations/CustomAnimationDialog.cxx
@@ -163,6 +163,13 @@ PresetPropertyBox::~PresetPropertyBox()
mpControl.disposeAndClear();
}
+SdPropertySubControl::SdPropertySubControl(weld::Container* pParent)
+ : mxBuilder(Application::CreateBuilder(pParent, "modules/simpress/ui/customanimationfragment.ui"))
+ , mxContainer(mxBuilder->weld_container("EffectFragment"))
+ , mpParent(pParent)
+{
+}
+
Any PresetPropertyBox::getValue()
{
return makeAny( maPropertyValues[mpControl->GetSelectedEntryPos()] );
@@ -175,6 +182,7 @@ Control* PresetPropertyBox::getControl()
SdPropertySubControl::~SdPropertySubControl()
{
+ mpParent->move(mxContainer.get(), nullptr);
}
namespace {
@@ -221,6 +229,7 @@ void SdPresetPropertyBox::setValue( const Any& rValue, const OUString& rPresetId
mxControl->freeze();
mxControl->clear();
+ maPropertyValues.clear();
int nPos = -1;
const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets();
diff --git a/sd/source/ui/animations/CustomAnimationDialog.hxx b/sd/source/ui/animations/CustomAnimationDialog.hxx
index 46c81789deeb..1ed6972e76e4 100644
--- a/sd/source/ui/animations/CustomAnimationDialog.hxx
+++ b/sd/source/ui/animations/CustomAnimationDialog.hxx
@@ -116,12 +116,7 @@ private:
class SdPropertySubControl
{
public:
- explicit SdPropertySubControl(weld::Container* pParent)
- : mxBuilder(Application::CreateBuilder(pParent, "modules/simpress/ui/customanimationfragment.ui"))
- , mxContainer(mxBuilder->weld_container("EffectFragment"))
- {
- }
-
+ explicit SdPropertySubControl(weld::Container* pParent);
virtual ~SdPropertySubControl();
virtual css::uno::Any getValue() = 0;
@@ -139,6 +134,7 @@ public:
protected:
std::unique_ptr<weld::Builder> mxBuilder;
std::unique_ptr<weld::Container> mxContainer;
+ weld::Container* mpParent;
};
class PropertyControl : public ListBox
diff --git a/sd/source/ui/animations/CustomAnimationList.cxx b/sd/source/ui/animations/CustomAnimationList.cxx
index 4793d8aafcca..559ac92a6b5c 100644
--- a/sd/source/ui/animations/CustomAnimationList.cxx
+++ b/sd/source/ui/animations/CustomAnimationList.cxx
@@ -29,20 +29,18 @@
#include <com/sun/star/drawing/XDrawPage.hpp>
#include "CustomAnimationList.hxx"
#include <CustomAnimationPreset.hxx>
-#include <vcl/settings.hxx>
-#include <vcl/builderfactory.hxx>
#include <vcl/commandevent.hxx>
#include <vcl/event.hxx>
+#include <vcl/image.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weldutils.hxx>
#include <tools/debug.hxx>
+#include <tools/gen.hxx>
#include <osl/diagnose.h>
#include <sdresid.hxx>
-#include <vcl/svlbitm.hxx>
-#include <vcl/treelistentry.hxx>
-#include <vcl/viewdataentry.hxx>
-
-
#include <strings.hrc>
#include <bitmaps.hlst>
@@ -215,33 +213,35 @@ static OUString getDescription( const Any& rTarget, bool bWithText )
return aDescription;
}
-class CustomAnimationListEntryItem : public SvLBoxString
+class CustomAnimationListEntryItem
{
public:
CustomAnimationListEntryItem(const OUString& aDescription,
- const CustomAnimationEffectPtr& pEffect, CustomAnimationList* pParent);
- void InitViewData(SvTreeListBox*,SvTreeListEntry*,SvViewDataItem* = nullptr) override;
- virtual std::unique_ptr<SvLBoxItem> Clone(SvLBoxItem const * pSource) const override;
+ const CustomAnimationEffectPtr& pEffect);
+ const CustomAnimationEffectPtr& getEffect() const { return mpEffect; }
+
+ Size GetSize(vcl::RenderContext& rRenderContext);
+ void Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect, bool bSelected);
+ void PaintEffect(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect, bool bSelected);
+ void PaintTrigger(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect);
- virtual void Paint(const Point&, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext,
- const SvViewDataEntry* pView,const SvTreeListEntry& rEntry) override;
private:
- VclPtr<CustomAnimationList> mpParent;
OUString msDescription;
OUString msEffectName;
CustomAnimationEffectPtr mpEffect;
+
static const long nIconWidth = 19;
static const long nItemMinHeight = 38;
};
-CustomAnimationListEntryItem::CustomAnimationListEntryItem( const OUString& aDescription, const CustomAnimationEffectPtr& pEffect, CustomAnimationList* pParent )
-: SvLBoxString( aDescription )
-, mpParent( pParent )
-, msDescription( aDescription )
-, msEffectName( OUString() )
-, mpEffect(pEffect)
+CustomAnimationListEntryItem::CustomAnimationListEntryItem(const OUString& aDescription, const CustomAnimationEffectPtr& pEffect)
+ : msDescription(aDescription)
+ , msEffectName(OUString())
+ , mpEffect(pEffect)
{
- switch(mpEffect->getPresetClass())
+ if (!mpEffect)
+ return;
+ switch (mpEffect->getPresetClass())
{
case EffectPresetClass::ENTRANCE:
msEffectName = SdResId(STR_CUSTOMANIMATION_ENTRANCE); break;
@@ -257,30 +257,85 @@ CustomAnimationListEntryItem::CustomAnimationListEntryItem( const OUString& aDes
msEffectName = msEffectName.replaceFirst( "%1" , CustomAnimationPresets::getCustomAnimationPresets().getUINameForPresetId(mpEffect->getPresetId()));
}
-void CustomAnimationListEntryItem::InitViewData( SvTreeListBox* pView, SvTreeListEntry* pEntry, SvViewDataItem* pViewData )
+IMPL_STATIC_LINK(CustomAnimationList, CustomRenderHdl, weld::TreeView::render_args, aPayload, void)
{
- if( !pViewData )
- pViewData = pView->GetViewDataItem( pEntry, this );
-
- long width = pView->GetTextWidth( msDescription ) + nIconWidth;
- if( width < (pView->GetTextWidth( msEffectName ) + 2*nIconWidth))
- width = pView->GetTextWidth( msEffectName ) + 2*nIconWidth;
-
- Size aSize( width, pView->GetTextHeight() );
- if( aSize.Height() < nItemMinHeight )
- aSize.setHeight( nItemMinHeight );
- pViewData->mnWidth = aSize.Width();
- pViewData->mnHeight = aSize.Height();
+ vcl::RenderContext& rRenderContext = std::get<0>(aPayload);
+ const ::tools::Rectangle& rRect = std::get<1>(aPayload);
+ bool bSelected = std::get<2>(aPayload);
+ const OUString& rId = std::get<3>(aPayload);
+
+ CustomAnimationListEntryItem* pItem = reinterpret_cast<CustomAnimationListEntryItem*>(rId.toInt64());
+
+ pItem->Paint(rRenderContext, rRect, bSelected);
}
-void CustomAnimationListEntryItem::Paint(const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext,
- const SvViewDataEntry* /*pView*/, const SvTreeListEntry& rEntry)
+IMPL_STATIC_LINK(CustomAnimationList, CustomGetSizeHdl, weld::TreeView::get_size_args, aPayload, Size)
{
+ vcl::RenderContext& rRenderContext = aPayload.first;
+ const OUString& rId = aPayload.second;
+
+ CustomAnimationListEntryItem* pItem = reinterpret_cast<CustomAnimationListEntryItem*>(rId.toInt64());
+ return pItem->GetSize(rRenderContext);
+}
+
+Size CustomAnimationListEntryItem::GetSize(vcl::RenderContext& rRenderContext)
+{
+ auto width = rRenderContext.GetTextWidth( msDescription ) + nIconWidth;
+ if (width < (rRenderContext.GetTextWidth( msEffectName ) + 2*nIconWidth))
+ width = rRenderContext.GetTextWidth( msEffectName ) + 2*nIconWidth;
+
+ Size aSize(width, rRenderContext.GetTextHeight());
+ if (aSize.Height() < nItemMinHeight)
+ aSize.setHeight(nItemMinHeight);
+ return aSize;
+}
+
+void CustomAnimationListEntryItem::PaintTrigger(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect)
+{
+ Size aSize(rRect.GetSize());
+
+ ::tools::Rectangle aOutRect(rRect);
+
+ // fill the background
+ Color aColor(rRenderContext.GetSettings().GetStyleSettings().GetDialogColor());
+
+ rRenderContext.Push();
+ rRenderContext.SetFillColor(aColor);
+ rRenderContext.SetLineColor();
+ rRenderContext.DrawRect(aOutRect);
+
+ // Erase the four corner pixels to make the rectangle appear rounded.
+ rRenderContext.SetLineColor(rRenderContext.GetSettings().GetStyleSettings().GetWindowColor());
+ rRenderContext.DrawPixel(aOutRect.TopLeft());
+ rRenderContext.DrawPixel(Point(aOutRect.Right(), aOutRect.Top()));
+ rRenderContext.DrawPixel(Point(aOutRect.Left(), aOutRect.Bottom()));
+ rRenderContext.DrawPixel(Point(aOutRect.Right(), aOutRect.Bottom()));
+
+ // draw the category title
+
+ int nVertBorder = ((aSize.Height() - rRenderContext.GetTextHeight()) >> 1);
+ int nHorzBorder = rRenderContext.LogicToPixel(Size(3, 3), MapMode(MapUnit::MapAppFont)).Width();
+
+ aOutRect.AdjustLeft(nHorzBorder );
+ aOutRect.AdjustRight( -nHorzBorder );
+ aOutRect.AdjustTop( nVertBorder );
+ aOutRect.AdjustBottom( -nVertBorder );
- const SvViewDataItem* pViewData = mpParent->GetViewDataItem(&rEntry, this);
+ rRenderContext.DrawText(aOutRect, rRenderContext.GetEllipsisString(msDescription, aOutRect.GetWidth()));
+ rRenderContext.Pop();
+}
- Point aPos(rPos);
- int nItemHeight = pViewData->mnHeight;
+void CustomAnimationListEntryItem::PaintEffect(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect, bool bSelected)
+{
+ rRenderContext.Push(PushFlags::TEXTCOLOR);
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ if (bSelected)
+ rRenderContext.SetTextColor(rStyleSettings.GetHighlightTextColor());
+ else
+ rRenderContext.SetTextColor(rStyleSettings.GetDialogTextColor());
+
+ Point aPos(rRect.TopLeft());
+ int nItemHeight = rRect.GetHeight();
sal_Int16 nNodeType = mpEffect->getNodeType();
if (nNodeType == EffectNodeType::ON_CLICK )
@@ -296,12 +351,12 @@ void CustomAnimationListEntryItem::Paint(const Point& rPos, SvTreeListBox& rDev,
//FIXME With previous image not defined in CustomAnimation.src
}
- aPos.AdjustX(nIconWidth );
-
+ aPos.AdjustX(nIconWidth);
- rRenderContext.DrawText(aPos, rRenderContext.GetEllipsisString(msDescription, rDev.GetOutputSizePixel().Width() - aPos.X()));
+ //TODO, full width of widget ?
+ rRenderContext.DrawText(aPos, rRenderContext.GetEllipsisString(msDescription, rRect.GetWidth()));
- aPos.AdjustY(nIconWidth );
+ aPos.AdjustY(nIconWidth);
OUString sImage;
switch (mpEffect->getPresetClass())
@@ -341,369 +396,129 @@ void CustomAnimationListEntryItem::Paint(const Point& rPos, SvTreeListBox& rDev,
}
aPos.AdjustX(nIconWidth );
- aPos.AdjustY((nItemHeight/2 - rDev.GetTextHeight()) >> 1 );
-
- rRenderContext.DrawText(aPos, rRenderContext.GetEllipsisString(msEffectName, rDev.GetOutputSizePixel().Width() - aPos.X()));
-}
-
-std::unique_ptr<SvLBoxItem> CustomAnimationListEntryItem::Clone(SvLBoxItem const *) const
-{
- return nullptr;
-}
-
-namespace {
-
-class CustomAnimationListEntry : public SvTreeListEntry
-{
-public:
- CustomAnimationListEntry();
- explicit CustomAnimationListEntry(const CustomAnimationEffectPtr& pEffect);
-
- const CustomAnimationEffectPtr& getEffect() const { return mpEffect; }
-
-private:
- CustomAnimationEffectPtr mpEffect;
-};
+ aPos.AdjustY((nItemHeight/2 - rRenderContext.GetTextHeight()) >> 1 );
+ rRenderContext.DrawText(aPos, rRenderContext.GetEllipsisString(msEffectName, rRect.GetWidth()));
+ rRenderContext.Pop();
}
-CustomAnimationListEntry::CustomAnimationListEntry()
-{
-}
-
-CustomAnimationListEntry::CustomAnimationListEntry(const CustomAnimationEffectPtr& pEffect)
-: mpEffect( pEffect )
-{
-}
-
-namespace {
-
-class CustomAnimationTriggerEntryItem : public SvLBoxString
+void CustomAnimationListEntryItem::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect, bool bSelected)
{
-public:
- explicit CustomAnimationTriggerEntryItem( const OUString& aDescription );
-
- void InitViewData( SvTreeListBox*,SvTreeListEntry*,SvViewDataItem* = nullptr ) override;
- virtual std::unique_ptr<SvLBoxItem> Clone(SvLBoxItem const * pSource) const override;
- virtual void Paint(const Point& rPos, SvTreeListBox& rOutDev, vcl::RenderContext& rRenderContext,
- const SvViewDataEntry* pView, const SvTreeListEntry& rEntry) override;
-
-private:
- OUString msDescription;
- static const long nIconWidth = 19;
-};
-
+ if (mpEffect)
+ PaintEffect(rRenderContext, rRect, bSelected);
+ else
+ PaintTrigger(rRenderContext, rRect);
}
-CustomAnimationTriggerEntryItem::CustomAnimationTriggerEntryItem( const OUString& aDescription )
-: SvLBoxString( aDescription ), msDescription( aDescription )
+CustomAnimationList::CustomAnimationList(std::unique_ptr<weld::TreeView> xTreeView,
+ std::unique_ptr<weld::Label> xLabel,
+ std::unique_ptr<weld::Widget> xScrolledWindow)
+ : mxTreeView(std::move(xTreeView))
+ , maDropTargetHelper(*this)
+ , mxEmptyLabel(std::move(xLabel))
+ , mxEmptyLabelParent(std::move(xScrolledWindow))
+ , mbIgnorePaint(false)
+ , mpController(nullptr)
+ , mnLastGroupId(0)
+ , mnPostExpandEvent(nullptr)
+ , mnPostCollapseEvent(nullptr)
{
+ mxEmptyLabel->set_stack_background();
+
+ mxTreeView->set_selection_mode(SelectionMode::Multiple);
+ mxTreeView->set_column_custom_renderer(0);
+ mxTreeView->connect_changed(LINK(this, CustomAnimationList, SelectHdl));
+ mxTreeView->connect_key_press(LINK(this, CustomAnimationList, KeyInputHdl));
+ mxTreeView->connect_popup_menu(LINK(this, CustomAnimationList, CommandHdl));
+ mxTreeView->connect_row_activated(LINK(this, CustomAnimationList, DoubleClickHdl));
+ mxTreeView->connect_expanding(LINK(this, CustomAnimationList, ExpandHdl));
+ mxTreeView->connect_collapsing(LINK(this, CustomAnimationList, CollapseHdl));
+ mxTreeView->connect_drag_begin(LINK(this, CustomAnimationList, DragBeginHdl));
+ mxTreeView->connect_custom_get_size(LINK(this, CustomAnimationList, CustomGetSizeHdl));
+ mxTreeView->connect_custom_render(LINK(this, CustomAnimationList, CustomRenderHdl));
}
-void CustomAnimationTriggerEntryItem::InitViewData( SvTreeListBox* pView, SvTreeListEntry* pEntry, SvViewDataItem* pViewData )
+CustomAnimationListDropTarget::CustomAnimationListDropTarget(CustomAnimationList& rTreeView)
+ : DropTargetHelper(rTreeView.get_widget().get_drop_target())
+ , m_rTreeView(rTreeView)
{
- if( !pViewData )
- pViewData = pView->GetViewDataItem( pEntry, this );
-
- Size aSize(pView->GetTextWidth( msDescription ) + 2 * nIconWidth, pView->GetTextHeight() );
- if( aSize.Height() < nIconWidth )
- aSize.setHeight( nIconWidth );
- pViewData->mnWidth = aSize.Width();
- pViewData->mnHeight = aSize.Height();
}
-void CustomAnimationTriggerEntryItem::Paint(const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext,
- const SvViewDataEntry* /*pView*/, const SvTreeListEntry& /*rEntry*/)
+sal_Int8 CustomAnimationListDropTarget::AcceptDrop(const AcceptDropEvent& rEvt)
{
- Size aSize(rDev.GetOutputSizePixel().Width(), rDev.GetEntryHeight());
-
- Point aPos(0, rPos.Y());
-
- ::tools::Rectangle aOutRect(aPos, aSize);
-
- // fill the background
- Color aColor(rRenderContext.GetSettings().GetStyleSettings().GetDialogColor());
-
- rRenderContext.Push();
- rRenderContext.SetFillColor(aColor);
- rRenderContext.SetLineColor();
- rRenderContext.DrawRect(aOutRect);
-
- // Erase the four corner pixels to make the rectangle appear rounded.
- rRenderContext.SetLineColor(rRenderContext.GetSettings().GetStyleSettings().GetWindowColor());
- rRenderContext.DrawPixel(aOutRect.TopLeft());
- rRenderContext.DrawPixel(Point(aOutRect.Right(), aOutRect.Top()));
- rRenderContext.DrawPixel(Point(aOutRect.Left(), aOutRect.Bottom()));
- rRenderContext.DrawPixel(Point(aOutRect.Right(), aOutRect.Bottom()));
-
- // draw the category title
+ sal_Int8 nAccept = m_rTreeView.AcceptDrop(rEvt);
- int nVertBorder = ((aSize.Height() - rDev.GetTextHeight()) >> 1);
- int nHorzBorder = rRenderContext.LogicToPixel(Size(3, 3), MapMode(MapUnit::MapAppFont)).Width();
-
- aOutRect.AdjustLeft(nHorzBorder );
- aOutRect.AdjustRight( -nHorzBorder );
- aOutRect.AdjustTop( nVertBorder );
- aOutRect.AdjustBottom( -nVertBorder );
-
- rRenderContext.DrawText(aOutRect, rRenderContext.GetEllipsisString(msDescription, aOutRect.GetWidth()));
- rRenderContext.Pop();
-}
+ if (nAccept != DND_ACTION_NONE)
+ {
+ // to enable the autoscroll when we're close to the edges
+ weld::TreeView& rWidget = m_rTreeView.get_widget();
+ rWidget.get_dest_row_at_pos(rEvt.maPosPixel, nullptr);
+ }
-std::unique_ptr<SvLBoxItem> CustomAnimationTriggerEntryItem::Clone(SvLBoxItem const *) const
-{
- return nullptr;
+ return nAccept;
}
-CustomAnimationList::CustomAnimationList( vcl::Window* pParent )
- : SvTreeListBox( pParent, WB_TABSTOP | WB_BORDER | WB_HASLINES | WB_HASBUTTONS | WB_HASBUTTONSATROOT )
- , mbIgnorePaint(false)
- , mpController(nullptr)
- , mnLastGroupId(0)
- , mpLastParentEntry(nullptr)
- , mpDndEffectDragging(nullptr)
- , mpDndEffectInsertBefore(nullptr)
+sal_Int8 CustomAnimationListDropTarget::ExecuteDrop(const ExecuteDropEvent& rEvt)
{
- EnableContextMenuHandling();
- SetSelectionMode( SelectionMode::Multiple );
- SetOptimalImageIndent();
- SetNodeDefaultImages();
-
- SetDragDropMode(DragDropMode::CTRL_MOVE);
+ return m_rTreeView.ExecuteDrop(rEvt);
}
// D'n'D #1: Record selected effects for drag'n'drop.
-void CustomAnimationList::StartDrag( sal_Int8 nAction, const Point& rPosPixel )
+IMPL_LINK(CustomAnimationList, DragBeginHdl, bool&, rUnsetDragIcon, bool)
{
+ rUnsetDragIcon = false;
+
// Record which effects are selected:
// Since NextSelected(..) iterates through the selected items in the order they
// were selected, create a sorted list for simpler drag'n'drop algorithms.
mDndEffectsSelected.clear();
- for( SvTreeListEntry* pEntry = First(); pEntry; pEntry = Next(pEntry) )
- {
- if( IsSelected(pEntry) )
- {
- mDndEffectsSelected.push_back( pEntry );
- }
- }
-
- // Allow normal processing; this calls our NotifyStartDrag().
- SvTreeListBox::StartDrag( nAction, rPosPixel );
-}
-
-// D'n'D #2: Prepare selected element for moving.
-DragDropMode CustomAnimationList::NotifyStartDrag( TransferDataContainer& /*rData*/, SvTreeListEntry* pEntry )
-{
- // Restore selection for multiple selected effects.
- // Do it here to remove a flicker on the UI with effects being unselected and reselected.
- for( auto &pEffect : mDndEffectsSelected )
- SelectListEntry( pEffect, true);
+ mxTreeView->selected_foreach([this](weld::TreeIter& rEntry){
+ mDndEffectsSelected.emplace_back(mxTreeView->make_iterator(&rEntry));
+ return false;
+ });
// Note: pEntry is the effect with focus (if multiple effects are selected)
- mpDndEffectDragging = pEntry;
- mpDndEffectInsertBefore = pEntry;
+ mxDndEffectDragging = mxTreeView->make_iterator();
+ mxTreeView->get_cursor(mxDndEffectDragging.get());
+ mxDndEffectInsertBefore = mxTreeView->make_iterator(mxDndEffectDragging.get());
- return DragDropMode::CTRL_MOVE;
+ // Allow normal processing.
+ return false;
}
// D'n'D #3: Called each time mouse moves during drag
sal_Int8 CustomAnimationList::AcceptDrop( const AcceptDropEvent& rEvt )
{
- /*
- Don't call SvTreeListBox::AcceptDrop because it puts an unnecessary
- highlight via ImplShowTargetEmphasis()
- */
-
sal_Int8 ret = DND_ACTION_NONE;
- const bool bIsMove = ( DND_ACTION_MOVE == rEvt.mnAction );
- if( mpDndEffectDragging && !rEvt.mbLeaving && bIsMove )
- {
- SvTreeListEntry* pEntry = GetDropTarget( rEvt.maPosPixel );
-
- const bool bOverASelectedEffect =
- std::find( mDndEffectsSelected.begin(), mDndEffectsSelected.end(), pEntry ) != mDndEffectsSelected.end();
- if( pEntry && !bOverASelectedEffect )
- {
- ReparentChildrenDuringDrag();
-
- ReorderEffectsInUiDuringDragOver( pEntry );
- }
-
- // Return DND_ACTION_MOVE on internal drag'n'drops so that ExecuteDrop() is called.
- // Return MOVE even if we are over other dragged effect because dragged effect moves.
+ const bool bIsMove = DND_ACTION_MOVE == rEvt.mnAction;
+ if (mxDndEffectDragging && !rEvt.mbLeaving && bIsMove)
ret = DND_ACTION_MOVE;
- }
-
return ret;
}
-// D'n'D: For each dragged effect, re-parent (only in the UI) non-selected
-// visible children so they are not dragged with the parent.
-void CustomAnimationList::ReparentChildrenDuringDrag()
-{
- /*
- Re-parent (only in the UI!):
- a) the dragged effect's first non-selected child to the root, and
- b) the remaining non-selected children to that re-parented 1st child.
- */
- for( auto &pEffect : mDndEffectsSelected )
- {
- const bool bExpandedWithChildren = GetVisibleChildCount( pEffect ) > 0;
- if( bExpandedWithChildren )
- {
- SvTreeListEntry* pEntryParent = GetParent( pEffect );
-
- SvTreeListEntry* pFirstNonSelectedChild = nullptr;
- sal_uLong nInsertNextChildPos = 0;
-
- // Process all children of this effect
- SvTreeListEntry* pChild = FirstChild( pEffect );
- while( pChild && ( GetParent( pChild ) == pEffect ) )
- {
- // Start by finding next child because if pChild moves, we cannot then
- // ask it what the next child is because it's no longer with its siblings.
- SvTreeListEntry* pNextChild = Next( pChild );
-
- // Skip selected effects: they stay with their previous parent to be moved.
- // During drag, the IsSelected() set changes, so use mDndEffectsSelected instead
- const bool bIsSelected = std::find( mDndEffectsSelected.begin(), mDndEffectsSelected.end(), pChild ) != mDndEffectsSelected.end();
- if( !bIsSelected )
- {
- // Re-parent 1st non-selected child to root, below all the other children.
- if( !pFirstNonSelectedChild )
- {
- pFirstNonSelectedChild = pChild;
- sal_uLong nInsertAfterPos = SvTreeList::GetRelPos( pEffect ) + 1;
- pModel->Move( pFirstNonSelectedChild, pEntryParent, nInsertAfterPos );
- }
- else
- {
- // Re-parent remaining non-selected children to 1st child
- ++nInsertNextChildPos;
- pModel->Move( pChild, pFirstNonSelectedChild, nInsertNextChildPos );
- }
- }
-
- pChild = pNextChild;
- }
-
- // Expand all children (they were previously visible)
- if( pFirstNonSelectedChild )
- Expand( pFirstNonSelectedChild );
-
- }
- }
-}
-
-// D'n'D: Update UI to show where dragged event will appear if dropped now.
-void CustomAnimationList::ReorderEffectsInUiDuringDragOver( SvTreeListEntry* pOverEntry )
-{
- /*
- Update the order of effects in *just the UI* while the user is dragging.
- The model (MainSequence) will only be changed after the user drops
- the effect so that there is minimal work to do if the drag is canceled.
- Plus only one undo record should be created per drag, and changing
- the model recreates all effects (on a background timer) which invalidates
- all effect pointers.
- */
-
- // Compute new location in *UI*
- SvTreeListEntry* pNewParent = nullptr;
- sal_uLong nInsertAfterPos = 0;
-
- Point aPosOverEffect( GetEntryPosition(pOverEntry) );
- Point aPosDraggedEffect( GetEntryPosition(mpDndEffectDragging) );
- const bool bDraggingUp = (aPosDraggedEffect.Y() - aPosOverEffect.Y()) > 0;
-
- if( bDraggingUp )
- {
- // Drag up --> place above the element we are over
- pNewParent = GetParent( pOverEntry );
- nInsertAfterPos = SvTreeList::GetRelPos( pOverEntry );
- mpDndEffectInsertBefore = pOverEntry;
- }
- else
- {
- // Drag down --> place below the element we are over
- SvTreeListEntry* pNextVisBelowTarget = NextVisible( pOverEntry );
- if( pNextVisBelowTarget )
- {
- // Match parent of NEXT visible effect (works for sub-items too)
- pNewParent = GetParent( pNextVisBelowTarget );
- nInsertAfterPos = SvTreeList::GetRelPos( pNextVisBelowTarget );
- mpDndEffectInsertBefore = pNextVisBelowTarget;
- }
- else
- {
- // Over the last element: no next to work with
- pNewParent = GetParent( pOverEntry );
- nInsertAfterPos = SvTreeList::GetRelPos( pOverEntry ) + 1;
- mpDndEffectInsertBefore = nullptr;
- }
- }
-
- // Move each selected effect in *just* the UI to show where it would be if dropped.
- // This leaves the exist parent relationships in the non-dragged elements so that
- // the list does not seem to change structure during drag. Parent relationships will
- // be correctly recreated on drop.
- for( auto aItr = mDndEffectsSelected.rbegin();
- aItr != mDndEffectsSelected.rend();
- ++aItr)
- {
- SvTreeListEntry* pEffect = *aItr;
-
- // Move only effects whose parents is not selected because
- // they will automatically move when their parent is moved.
- const bool bParentIsSelected =
- std::find(mDndEffectsSelected.begin(), mDndEffectsSelected.end(), GetParent(pEffect)) != mDndEffectsSelected.end();
-
- if( !bParentIsSelected )
- {
- // If the current effect is being moved down, the insert position must be decremented
- // after move if it will have the same parent as it currently does because it moves
- // from above the insertion point to below it, hence changing its index.
- // Must decide move-up vs move-down for each effect being dragged because we may be
- // processing a discontinuous set of selected effects (some below, some above insertion point)
- Point aCurPosOverEffect( GetEntryPosition( pOverEntry ) );
- Point aCurPosMovedEffect( GetEntryPosition( pEffect ) );
- const bool bCurDraggingDown = ( aCurPosMovedEffect.Y() - aCurPosOverEffect.Y() ) < 0;
- const bool bWillHaveSameParent = ( pNewParent == GetParent(pEffect) );
-
- pModel->Move( pEffect, pNewParent, nInsertAfterPos );
-
- if( bCurDraggingDown && bWillHaveSameParent )
- --nInsertAfterPos;
- }
- }
-
- // Restore selection (calling Select() is slow; SelectListEntry() is faster)
- for( auto &pEffect : mDndEffectsSelected )
- SelectListEntry( pEffect, true);
-}
-
// D'n'D #5: Tell model to update effect order.
-sal_Int8 CustomAnimationList::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ )
+sal_Int8 CustomAnimationList::ExecuteDrop(const ExecuteDropEvent& rEvt)
{
- // NOTE: We cannot just override NotifyMoving() because it's not called
- // since we dynamically reorder effects during drag.
-
- sal_Int8 ret = DND_ACTION_NONE;
+ if (!mxTreeView->get_dest_row_at_pos(rEvt.maPosPixel, mxDndEffectInsertBefore.get()))
+ mxDndEffectInsertBefore.reset();
- const bool bMovingEffect = ( mpDndEffectDragging != nullptr );
- const bool bMoveNotSelf = ( mpDndEffectInsertBefore != mpDndEffectDragging );
+ const bool bMovingEffect = ( mxDndEffectDragging != nullptr );
+ const bool bMoveNotSelf = !mxDndEffectInsertBefore || (mxDndEffectDragging && mxTreeView->iter_compare(*mxDndEffectInsertBefore, *mxDndEffectDragging) != 0);
const bool bHaveSequence = ( mpMainSequence.get() != nullptr );
if( bMovingEffect && bMoveNotSelf && bHaveSequence )
{
- CustomAnimationListEntry* pTarget = static_cast< CustomAnimationListEntry* >( mpDndEffectInsertBefore );
+ CustomAnimationListEntryItem* pTarget = mxDndEffectInsertBefore ?
+ reinterpret_cast<CustomAnimationListEntryItem*>(mxTreeView->get_id(*mxDndEffectInsertBefore).toInt64()) :
+ nullptr;
// Build list of effects
std::vector< CustomAnimationEffectPtr > aEffects;
for( const auto &pEntry : mDndEffectsSelected )
{
- CustomAnimationListEntry* pCustomAnimationEffect = static_cast< CustomAnimationListEntry* >( pEntry );
- aEffects.push_back( pCustomAnimationEffect->getEffect() );
+ CustomAnimationListEntryItem* pCustomAnimationEffect = reinterpret_cast<CustomAnimationListEntryItem*>(mxTreeView->get_id(*pEntry).toInt64());
+ aEffects.push_back(pCustomAnimationEffect->getEffect());
}
// Callback to observer to have it update the model.
@@ -713,90 +528,82 @@ sal_Int8 CustomAnimationList::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ )
pTarget ? pTarget->getEffect() : nullptr );
// Reset selection
- Select( mpDndEffectDragging );
-
- ret = DND_ACTION_MOVE;
+ mxTreeView->select(*mxDndEffectDragging);
+ Select();
}
- // NOTE: Don't call SvTreeListBox::ExecuteDrop(...) because all required
+ // NOTE: Don't call default handler because all required
// move operations have been completed here to update the model.
- return ret;
-}
-
-// D'n'D #6: Cleanup (regardless of if we were target of drop or not)
-void CustomAnimationList::DragFinished( sal_Int8 /*nDropAction*/ )
-{
- mpDndEffectDragging = nullptr;
- mpDndEffectInsertBefore = nullptr;
- mDndEffectsSelected.clear();
-
- // Rebuild because we may have re-parented the dragged effect's first child.
- // Can hit this without running ExecuteDrop(...) when drag canceled.
- mpMainSequence->rebuild();
-
- // Note: Don't call SvTreeListBox::DragFinished(...) because we don't call
- // SvTreeListBox::ExecuteDrop(...) which sets variables that are
- // needed in its DragFinished(...) method.
+ return DND_ACTION_NONE;
}
-VCL_BUILDER_FACTORY(CustomAnimationList)
-
CustomAnimationList::~CustomAnimationList()
{
- disposeOnce();
-}
+ if (mnPostExpandEvent)
+ {
+ Application::RemoveUserEvent(mnPostExpandEvent);
+ mnPostExpandEvent = nullptr;
+ }
+
+ if (mnPostCollapseEvent)
+ {
+ Application::RemoveUserEvent(mnPostCollapseEvent);
+ mnPostCollapseEvent = nullptr;
+ }
-void CustomAnimationList::dispose()
-{
if( mpMainSequence.get() )
mpMainSequence->removeListener( this );
clear();
-
- mxMenu.disposeAndClear();
- mxBuilder.reset();
-
- SvTreeListBox::dispose();
}
-void CustomAnimationList::KeyInput( const KeyEvent& rKEvt )
+IMPL_LINK(CustomAnimationList, KeyInputHdl, const KeyEvent&, rKEvt, bool)
{
const int nKeyCode = rKEvt.GetKeyCode().GetCode();
- switch( nKeyCode )
+ switch (nKeyCode)
{
case KEY_DELETE:
mpController->onContextMenu("remove");
- return;
+ return true;
case KEY_INSERT:
mpController->onContextMenu("create");
- return;
+ return true;
case KEY_SPACE:
+ {
+ std::unique_ptr<weld::TreeIter> xEntry = mxTreeView->make_iterator();
+ if (mxTreeView->get_cursor(xEntry.get()))
{
- const Point aPos;
- const CommandEvent aCEvt( aPos, CommandEventId::ContextMenu );
- Command( aCEvt );
- return;
+ auto aRect = mxTreeView->get_row_area(*xEntry);
+ const Point aPos(aRect.getWidth() / 2, aRect.getHeight() / 2);
+ const CommandEvent aCEvt(aPos, CommandEventId::ContextMenu);
+ CommandHdl(aCEvt);
+ return true;
}
-
+ }
}
-
- ::SvTreeListBox::KeyInput( rKEvt );
+ return false;
}
/** selects or deselects the given effect.
Selections of other effects are not changed */
void CustomAnimationList::select( const CustomAnimationEffectPtr& pEffect )
{
- CustomAnimationListEntry* pEntry = static_cast< CustomAnimationListEntry* >(First());
- while( pEntry )
+ CustomAnimationListEntryItem* pEntry = nullptr;
+
+ std::unique_ptr<weld::TreeIter> xEntry = mxTreeView->make_iterator();
+ if (mxTreeView->get_iter_first(*xEntry))
{
- if( pEntry->getEffect() == pEffect )
+ do
{
- Select( pEntry );
- MakeVisible( pEntry );
- break;
- }
- pEntry = static_cast< CustomAnimationListEntry* >(Next( pEntry ));
+ CustomAnimationListEntryItem* pTestEntry = reinterpret_cast<CustomAnimationListEntryItem*>(mxTreeView->get_id(*xEntry).toInt64());
+ if (pTestEntry->getEffect() == pEffect)
+ {
+ mxTreeView->select(*xEntry);
+ mxTreeView->scroll_to_row(*xEntry);
+ pEntry = pTestEntry;
+ break;
+ }
+ } while (mxTreeView->iter_next(*xEntry));
}
if( !pEntry )
@@ -808,9 +615,13 @@ void CustomAnimationList::select( const CustomAnimationEffectPtr& pEffect )
void CustomAnimationList::clear()
{
- Clear();
+ mxEntries.clear();
+ mxTreeView->clear();
- mpLastParentEntry = nullptr;
+ mxEmptyLabelParent->show();
+ mxTreeView->hide();
+
+ mxLastParentEntry.reset();
mxLastTargetShape = nullptr;
}
@@ -841,9 +652,6 @@ void stl_append_effect_func::operator()(const CustomAnimationEffectPtr& pEffect)
void CustomAnimationList::update()
{
mbIgnorePaint = true;
- SetUpdateMode( false );
-
- CustomAnimationListEntry* pEntry = nullptr;
std::vector< CustomAnimationEffectPtr > aVisible;
std::vector< CustomAnimationEffectPtr > aSelected;
@@ -856,62 +664,77 @@ void CustomAnimationList::update()
long nFirstSelOld = -1;
long nLastSelOld = -1;
+ std::unique_ptr<weld::TreeIter> xEntry = mxTreeView->make_iterator();
+
if( mpMainSequence.get() )
{
- // save scroll position
- pEntry = static_cast<CustomAnimationListEntry*>(GetFirstEntryInView());
- if( pEntry )
- nFirstVis = GetAbsPos( pEntry );
+ std::unique_ptr<weld::TreeIter> xLastSelectedEntry;
+ std::unique_ptr<weld::TreeIter> xLastVisibleEntry;
- pEntry = static_cast<CustomAnimationListEntry*>(GetLastEntryInView());
- if( pEntry )
- nLastVis = GetAbsPos( pEntry );
+ // save selection, current, and expand (visible) states
+ mxTreeView->all_foreach([this, &aVisible, &nFirstVis, &xLastVisibleEntry,
+ &aSelected, &nFirstSelOld, &pFirstSelEffect, &xLastSelectedEntry](weld::TreeIter& rEntry){
+ CustomAnimationListEntryItem* pEntry = reinterpret_cast<CustomAnimationListEntryItem*>(mxTreeView->get_id(rEntry).toInt64());
+ CustomAnimationEffectPtr pEffect(pEntry->getEffect());
+ if (pEffect.get())
+ {
+ if (weld::IsEntryVisible(*mxTreeView, rEntry))
+ {
+ aVisible.push_back(pEffect);
+ // save scroll position
+ if (nFirstVis == -1)
+ nFirstVis = weld::GetAbsPos(*mxTreeView, rEntry);
+ if (!xLastVisibleEntry)
+ xLastVisibleEntry = mxTreeView->make_iterator(&rEntry);
+ else
+ mxTreeView->copy_iterator(rEntry, *xLastVisibleEntry);
+ }
- pEntry = static_cast<CustomAnimationListEntry*>(FirstSelected());
- if( pEntry )
- {
- pFirstSelEffect = pEntry->getEffect();
- nFirstSelOld = GetAbsPos( pEntry );
- }
+ if (mxTreeView->is_selected(rEntry))
+ {
+ aSelected.push_back(pEffect);
+ if (nFirstSelOld == -1)
+ {
+ pFirstSelEffect = pEffect;
+ nFirstSelOld = weld::GetAbsPos(*mxTreeView, rEntry);
+ }
+ if (!xLastSelectedEntry)
+ xLastSelectedEntry = mxTreeView->make_iterator(&rEntry);
+ else
+ mxTreeView->copy_iterator(rEntry, *xLastSelectedEntry);
+ }
+ }
+
+ return false;
+ });
- pEntry = static_cast<CustomAnimationListEntry*>(LastSelected());
- if( pEntry )
+ if (xLastSelectedEntry)
{
+ CustomAnimationListEntryItem* pEntry = reinterpret_cast<CustomAnimationListEntryItem*>(mxTreeView->get_id(*xLastSelectedEntry).toInt64());
pLastSelEffect = pEntry->getEffect();
- nLastSelOld = GetAbsPos( pEntry );
+ nLastSelOld = weld::GetAbsPos(*mxTreeView, *xLastSelectedEntry);
}
- // save selection, current, and expand (visible) states
- pEntry = static_cast<CustomAnimationListEntry*>(First());
+ if (xLastVisibleEntry)
+ nLastVis = weld::GetAbsPos(*mxTreeView, *xLastVisibleEntry);
- while( pEntry )
+ if (mxTreeView->get_cursor(xEntry.get()))
{
- CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
- if( pEffect.get() )
- {
- if( IsEntryVisible( pEntry ) )
- aVisible.push_back( pEffect );
-
- if( IsSelected( pEntry ) )
- aSelected.push_back( pEffect );
- }
-
- pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry ));
- }
-
- pEntry = static_cast<CustomAnimationListEntry*>(GetCurEntry());
- if( pEntry )
+ CustomAnimationListEntryItem* pEntry = reinterpret_cast<CustomAnimationListEntryItem*>(mxTreeView->get_id(*xEntry).toInt64());
aCurrent = pEntry->getEffect();
+ }
}
// rebuild list
+
+ mxTreeView->freeze();
+
clear();
- if( mpMainSequence.get() )
+
+ if (mpMainSequence.get())
{
- long nFirstSelNew = -1;
- long nLastSelNew = -1;
std::for_each( mpMainSequence->getBegin(), mpMainSequence->getEnd(), stl_append_effect_func( *this ) );
- mpLastParentEntry = nullptr;
+ mxLastParentEntry.reset();
auto rInteractiveSequenceVector = mpMainSequence->getInteractiveSequenceVector();
@@ -920,54 +743,76 @@ void CustomAnimationList::update()
Reference< XShape > xShape( pIS->getTriggerShape() );
if( xShape.is() )
{
- SvTreeListEntry* pLBoxEntry = new CustomAnimationListEntry;
- pLBoxEntry->AddItem(std::make_unique<SvLBoxContextBmp>(Image(), Image(), false));
OUString aDescription = SdResId(STR_CUSTOMANIMATION_TRIGGER) + ": " +
getShapeDescription( xShape, false );
- pLBoxEntry->AddItem(std::make_unique<CustomAnimationTriggerEntryItem>(aDescription));
- Insert( pLBoxEntry );
- SvViewDataEntry* pViewData = GetViewData( pLBoxEntry );
- if( pViewData )
- pViewData->SetSelectable(false);
+ mxEntries.emplace_back(std::make_unique<CustomAnimationListEntryItem>(aDescription, nullptr));
+
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(mxEntries.back().get())));
+ mxTreeView->insert(nullptr, -1, &aDescription, &sId, nullptr, nullptr, nullptr, false, nullptr);
std::for_each( pIS->getBegin(), pIS->getEnd(), stl_append_effect_func( *this ) );
- mpLastParentEntry = nullptr;
+ mxLastParentEntry.reset();
}
}
+ }
- // restore selection state, expand state, and current-entry (under cursor)
- pEntry = static_cast<CustomAnimationListEntry*>(First());
+ mxTreeView->thaw();
- while( pEntry )
+ if (mxTreeView->n_children())
+ {
+ mxEmptyLabelParent->hide();
+ mxTreeView->show();
+ }
+
+ if (mpMainSequence.get())
+ {
+ long nFirstSelNew = -1;
+ long nLastSelNew = -1;
+
+ std::vector<std::unique_ptr<weld::TreeIter>> aNewSelection;
+
+ // restore selection state, expand state, and current-entry (under cursor)
+ if (mxTreeView->get_iter_first(*xEntry))
{
- CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
- if( pEffect.get() )
+ do
{
- // Any effects that were visible should still be visible, so expand their parents.
- // (a previously expanded parent may have moved leaving a child to now be the new parent to expand)
- if( std::find( aVisible.begin(), aVisible.end(), pEffect ) != aVisible.end() )
- {
- if( GetParent(pEntry) )
- Expand( GetParent(pEntry) );
- }
+ CustomAnimationListEntryItem* pEntry = reinterpret_cast<CustomAnimationListEntryItem*>(mxTreeView->get_id(*xEntry).toInt64());
- if( std::find( aSelected.begin(), aSelected.end(), pEffect ) != aSelected.end() )
- Select( pEntry );
+ CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
+ if (pEffect.get())
+ {
+ // Any effects that were visible should still be visible, so expand their parents.
+ // (a previously expanded parent may have moved leaving a child to now be the new parent to expand)
+ if( std::find( aVisible.begin(), aVisible.end(), pEffect ) != aVisible.end() )
+ {
+ if (mxTreeView->get_iter_depth(*xEntry))
+ {
+ std::unique_ptr<weld::TreeIter> xParentEntry = mxTreeView->make_iterator(xEntry.get());
+ mxTreeView->iter_parent(*xParentEntry);
+ mxTreeView->expand_row(*xParentEntry);
+ }
+ }
- // Restore the cursor; don't use SetCurEntry() as it may deselect other effects
- if( pEffect == aCurrent )
- SetCursor( pEntry );
+ if( std::find( aSelected.begin(), aSelected.end(), pEffect ) != aSelected.end() )
+ aNewSelection.emplace_back(mxTreeView->make_iterator(xEntry.get()));
- if( pEffect == pFirstSelEffect )
- nFirstSelNew = GetAbsPos( pEntry );
+ // Restore the cursor, as it may deselect other effects wait until
+ // after the loop to reset the selection
+ if( pEffect == aCurrent )
+ mxTreeView->set_cursor(*xEntry);
- if( pEffect == pLastSelEffect )
- nLastSelNew = GetAbsPos( pEntry );
- }
+ if (pEffect == pFirstSelEffect)
+ nFirstSelNew = weld::GetAbsPos(*mxTreeView, *xEntry);
- pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry ));
+ if (pEffect == pLastSelEffect)
+ nLastSelNew = weld::GetAbsPos(*mxTreeView, *xEntry);
+ }
+ } while (mxTreeView->iter_next(*xEntry));
}
+ for (const auto& rEntry : aNewSelection)
+ mxTreeView->select(*rEntry);
+
// Scroll to a selected entry, depending on where the selection moved.
const bool bMoved = nFirstSelNew != nFirstSelOld;
const bool bMovedUp = nFirstSelNew < nFirstSelOld;
@@ -981,103 +826,104 @@ void CustomAnimationList::update()
{
// The entries in the selection range can't fit in view.
// Scroll so the last selected entry is last in view.
- ScrollToAbsPos( nLastSelNew - (nLastVis - nFirstVis) );
+ mxTreeView->vadjustment_set_value(nLastSelNew - (nLastVis - nFirstVis));
}
else
- ScrollToAbsPos( nFirstSelNew );
+ mxTreeView->vadjustment_set_value(nFirstSelNew);
}
else if( bMoved && nFirstSelOld > nLastVis && nFirstSelNew > nLastVis )
{
// The selection is below the visible area.
// Scroll down to the first few selected entries.
- ScrollToAbsPos( nFirstSelNew );
+ mxTreeView->vadjustment_set_value(nFirstSelNew);
}
else if( bMovedUp && nFirstSelOld <= nFirstVis )
{
// A visible entry has moved up out of view; scroll up one.
- ScrollToAbsPos( nFirstVis - 1 );
+ mxTreeView->vadjustment_set_value(nFirstVis - 1);
}
else if( bMovedDown && nLastSelOld >= nLastVis )
{
// An entry has moved down out of view; scroll down one.
- ScrollToAbsPos( nFirstVis + 1 );
+ mxTreeView->vadjustment_set_value(nFirstVis + 1);
}
else if ( nFirstVis != -1 )
{
// The selection is still in view, or it hasn't moved.
- ScrollToAbsPos( nFirstVis );
+ mxTreeView->vadjustment_set_value(nFirstVis);
}
}
mbIgnorePaint = false;
- SetUpdateMode( true );
- Invalidate();
+
+ Select();
}
void CustomAnimationList::append( CustomAnimationEffectPtr pEffect )
{
- // create a ui description
- OUString aDescription;
-
Any aTarget( pEffect->getTarget() );
if( !aTarget.hasValue() )
return;
try
{
- aDescription = getDescription( aTarget, pEffect->getTargetSubItem() != ShapeAnimationSubType::ONLY_BACKGROUND );
+ // create a ui description
+ OUString aDescription = getDescription(aTarget, pEffect->getTargetSubItem() != ShapeAnimationSubType::ONLY_BACKGROUND);
- SvTreeListEntry* pParentEntry = nullptr;
+ std::unique_ptr<weld::TreeIter> xParentEntry;
Reference< XShape > xTargetShape( pEffect->getTargetShape() );
sal_Int32 nGroupId = pEffect->getGroupId();
// if this effect has the same target and group-id as the last root effect,
// the last root effect is also this effects parent
- if( mpLastParentEntry && (nGroupId != -1) && (mxLastTargetShape == xTargetShape) && (mnLastGroupId == nGroupId) )
- pParentEntry = mpLastParentEntry;
+ if (mxLastParentEntry && nGroupId != -1 && mxLastTargetShape == xTargetShape && mnLastGroupId == nGroupId)
+ xParentEntry = mxTreeView->make_iterator(mxLastParentEntry.get());
// create an entry for the effect
- SvTreeListEntry* pEntry = new CustomAnimationListEntry( pEffect );
+ std::unique_ptr<weld::TreeIter> xEntry = mxTreeView->make_iterator();
+
+ mxEntries.emplace_back(std::make_unique<CustomAnimationListEntryItem>(aDescription, pEffect));
- pEntry->AddItem(std::make_unique<SvLBoxContextBmp>(Image(), Image(), false));
- pEntry->AddItem(std::make_unique<CustomAnimationListEntryItem>(aDescription, pEffect, this));
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(mxEntries.back().get())));
- if( pParentEntry )
+ if (xParentEntry)
{
// add a subentry
- Insert( pEntry, pParentEntry );
+ mxTreeView->insert(xParentEntry.get(), -1, &aDescription, &sId, nullptr, nullptr, nullptr, false, xEntry.get());
}
else
{
// add a root entry
- Insert( pEntry );
+ mxTreeView->insert(nullptr, -1, &aDescription, &sId, nullptr, nullptr, nullptr, false, xEntry.get());
// and the new root entry becomes the possible next group header
mxLastTargetShape = xTargetShape;
mnLastGroupId = nGroupId;
- mpLastParentEntry = pEntry;
+ mxLastParentEntry = std::move(xEntry);
}
}
- catch( Exception& )
+ catch (const Exception&)
{
OSL_FAIL("sd::CustomAnimationList::append(), exception caught!" );
}
}
-static void selectShape( SvTreeListBox* pTreeList, const Reference< XShape >& xShape )
+static void selectShape(weld::TreeView* pTreeList, const Reference< XShape >& xShape )
{
- CustomAnimationListEntry* pEntry = static_cast< CustomAnimationListEntry* >(pTreeList->First());
- while( pEntry )
+ std::unique_ptr<weld::TreeIter> xEntry = pTreeList->make_iterator();
+ if (pTreeList->get_iter_first(*xEntry))
{
- CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
- if( pEffect.get() )
+ do
{
- if( pEffect->getTarget() == xShape )
- pTreeList->Select( pEntry );
- }
-
- pEntry = static_cast< CustomAnimationListEntry* >(pTreeList->Next( pEntry ));
+ CustomAnimationListEntryItem* pEntry = reinterpret_cast<CustomAnimationListEntryItem*>(pTreeList->get_id(*xEntry).toInt64());
+ CustomAnimationEffectPtr pEffect(pEntry->getEffect());
+ if (pEffect)
+ {
+ if (pEffect->getTarget() == xShape)
+ pTreeList->select(*xEntry);
+ }
+ } while (pTreeList->iter_next(*xEntry));
}
}
@@ -1085,7 +931,7 @@ void CustomAnimationList::onSelectionChanged(const Any& rSelection)
{
try
{
- SelectAll(false);
+ mxTreeView->unselect_all();
if (rSelection.hasValue())
{
@@ -1098,18 +944,18 @@ void CustomAnimationList::onSelectionChanged(const Any& rSelection)
{
Reference< XShape > xShape( xShapes->getByIndex( nIndex ), UNO_QUERY );
if( xShape.is() )
- selectShape( this, xShape );
+ selectShape(mxTreeView.get(), xShape);
}
}
else
{
Reference< XShape > xShape(rSelection, UNO_QUERY);
if( xShape.is() )
- selectShape( this, xShape );
+ selectShape(mxTreeView.get(), xShape);
}
}
- SelectHdl();
+ Select();
}
catch( Exception& )
{
@@ -1117,170 +963,186 @@ void CustomAnimationList::onSelectionChanged(const Any& rSelection)
}
}
-// Notify controller to refresh UI when we are notified of selection change from base class
-void CustomAnimationList::SelectHdl()
+IMPL_LINK_NOARG(CustomAnimationList, SelectHdl, weld::TreeView&, void)
{
- if( mbIgnorePaint )
- return;
- SvTreeListBox::SelectHdl();
- mpController->onSelect();
+ Select();
}
// Notify controller to refresh UI when we are notified of selection change from base class
-void CustomAnimationList::DeselectHdl()
+void CustomAnimationList::Select()
{
if( mbIgnorePaint )
return;
- SvTreeListBox::DeselectHdl();
mpController->onSelect();
}
-
-bool CustomAnimationList::Expand( SvTreeListEntry* pParent )
+IMPL_LINK_NOARG(CustomAnimationList, PostExpandHdl, void*, void)
{
- bool result = SvTreeListBox::Expand( pParent );
-
- // If expanded entry is selected, then select its children too.
- if( IsSelected( pParent )) {
- for( auto pChild = FirstChild( pParent ); pChild; pChild = pChild->NextSibling() )
+ std::unique_ptr<weld::TreeIter> xEntry = mxTreeView->make_iterator();
+ if (mxTreeView->get_selected(xEntry.get()))
+ {
+ for (bool bChild = mxTreeView->iter_children(*xEntry); bChild; bChild = mxTreeView->iter_next_sibling(*xEntry))
{
- if( !IsSelected( pChild ) )
- {
- SelectListEntry( pChild, true );
- }
+ if (!mxTreeView->is_selected(*xEntry))
+ mxTreeView->select(*xEntry);
}
}
// Notify controller that selection has changed (it should update the UI)
mpController->onSelect();
- return result;
+ mnPostExpandEvent = nullptr;
}
-bool CustomAnimationList::Collapse( SvTreeListEntry* pParent )
+IMPL_LINK(CustomAnimationList, ExpandHdl, const weld::TreeIter&, rParent, bool)
{
- // SvTreeListBox::Collapse(..) discards multi-selection state
- // of list entries, so first save current selection state
- std::vector< SvTreeListEntry* > selectedEntries;
- for( auto pEntry = FirstSelected(); pEntry; pEntry = NextSelected( pEntry ))
- {
- selectedEntries.push_back( pEntry );
+ // If expanded entry is selected, then select its children too afterwards.
+ if (mxTreeView->is_selected(rParent) && !mnPostExpandEvent) {
+ mnPostExpandEvent = Application::PostUserEvent(LINK(this, CustomAnimationList, PostExpandHdl));
}
- // Execute collapse on base class
- bool result = SvTreeListBox::Collapse( pParent );
+ return true;
+}
+IMPL_LINK_NOARG(CustomAnimationList, PostCollapseHdl, void*, void)
+{
// Deselect all entries as SvTreeListBox::Collapse selects the last
// entry to have focus (or its parent), which is not desired
- for( auto pEntry = FirstSelected(); pEntry; pEntry = NextSelected( pEntry ))
- {
- SelectListEntry( pEntry, false );
- }
+ mxTreeView->unselect_all();
// Restore selection state for entries which are still visible
- for( auto &pEntry : selectedEntries )
+ for (auto &pEntry : lastSelectedEntries)
{
- if( IsEntryVisible( pEntry ))
- {
- SelectListEntry( pEntry, true );
- }
+ if (weld::IsEntryVisible(*mxTreeView, *pEntry))
+ mxTreeView->select(*pEntry);
}
+ lastSelectedEntries.clear();
+
// Notify controller that selection has changed (it should update the UI)
mpController->onSelect();
- return result;
+ mnPostCollapseEvent = nullptr;
}
-bool CustomAnimationList::isExpanded( const CustomAnimationEffectPtr& pEffect ) const
+IMPL_LINK_NOARG(CustomAnimationList, CollapseHdl, const weld::TreeIter&, bool)
{
- CustomAnimationListEntry* pEntry = static_cast<CustomAnimationListEntry*>(First());
-
- while( pEntry )
+ if (!mnPostCollapseEvent)
{
- if( pEntry->getEffect() == pEffect )
- break;
-
- pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry ));
+ // weld::TreeView::collapse() discards multi-selection state
+ // of list entries, so first save current selection state
+ mxTreeView->selected_foreach([this](weld::TreeIter& rEntry){
+ lastSelectedEntries.emplace_back(mxTreeView->make_iterator(&rEntry));
+ return false;
+ });
+
+ mnPostCollapseEvent = Application::PostUserEvent(LINK(this, CustomAnimationList, PostCollapseHdl));
}
- if( pEntry )
- pEntry = static_cast<CustomAnimationListEntry*>(GetParent( pEntry ));
-
- return (pEntry == nullptr) || IsExpanded( pEntry );
+ // Execute collapse on base class
+ return true;
}
-bool CustomAnimationList::isVisible( const CustomAnimationEffectPtr& pEffect ) const
+bool CustomAnimationList::isExpanded( const CustomAnimationEffectPtr& pEffect ) const
{
- CustomAnimationListEntry* pEntry = static_cast<CustomAnimationListEntry*>(First());
+ bool bExpanded = true; // we assume expanded by default
- while( pEntry )
+ std::unique_ptr<weld::TreeIter> xEntry = mxTreeView->make_iterator();
+ if (mxTreeView->get_iter_first(*xEntry))
{
- if( pEntry->getEffect() == pEffect )
- break;
-
- pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry ));
+ do
+ {
+ CustomAnimationListEntryItem* pEntry =
+ reinterpret_cast<CustomAnimationListEntryItem*>(mxTreeView->get_id(*xEntry).toInt64());
+ if (pEntry->getEffect() == pEffect)
+ {
+ if (mxTreeView->get_iter_depth(*xEntry)) // no parent, keep expanded default of true
+ {
+ std::unique_ptr<weld::TreeIter> xParentEntry = mxTreeView->make_iterator(xEntry.get());
+ if (mxTreeView->iter_parent(*xParentEntry))
+ bExpanded = mxTreeView->get_row_expanded(*xParentEntry);
+ }
+ break;
+ }
+ } while (mxTreeView->iter_next(*xEntry));
}
- return (pEntry == nullptr) || IsEntryVisible( pEntry );
+ return bExpanded;
+}
+
+bool CustomAnimationList::isVisible(const CustomAnimationEffectPtr& pEffect) const
+{
+ std::unique_ptr<weld::TreeIter> xEntry = mxTreeView->make_iterator();
+ if (mxTreeView->get_iter_first(*xEntry))
+ {
+ do
+ {
+ CustomAnimationListEntryItem* pTestEntry = reinterpret_cast<CustomAnimationListEntryItem*>(mxTreeView->get_id(*xEntry).toInt64());
+ if (pTestEntry->getEffect() == pEffect)
+ return weld::IsEntryVisible(*mxTreeView, *xEntry);
+ } while (mxTreeView->iter_next(*xEntry));
+ }
+ return true;
}
EffectSequence CustomAnimationList::getSelection() const
{
EffectSequence aSelection;
- CustomAnimationListEntry* pEntry = dynamic_cast< CustomAnimationListEntry* >(FirstSelected());
- while( pEntry )
- {
- CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
- if( pEffect.get() )
- aSelection.push_back( pEffect );
+ mxTreeView->selected_foreach([this, &aSelection](weld::TreeIter& rEntry){
+ CustomAnimationListEntryItem* pEntry = reinterpret_cast<CustomAnimationListEntryItem*>(mxTreeView->get_id(rEntry).toInt64());
+ CustomAnimationEffectPtr pEffect(pEntry->getEffect());
+ if (pEffect)
+ aSelection.push_back(pEffect);
// if the selected effect is not expanded and has children
// we say that the children are automatically selected
- if( !IsExpanded( pEntry ) )
+ if (!mxTreeView->get_row_expanded(rEntry) && mxTreeView->iter_has_child(rEntry))
{
- CustomAnimationListEntry* pChild = dynamic_cast< CustomAnimationListEntry* >( FirstChild( pEntry ) );
- while( pChild )
+ std::unique_ptr<weld::TreeIter> xChild = mxTreeView->make_iterator(&rEntry);
+ mxTreeView->iter_children(*xChild);
+
+ do
{
- if( !IsSelected( pChild ) )
+ if (!mxTreeView->is_selected(*xChild))
{
+ CustomAnimationListEntryItem* pChild = reinterpret_cast<CustomAnimationListEntryItem*>(mxTreeView->get_id(*xChild).toInt64());
const CustomAnimationEffectPtr& pChildEffect( pChild->getEffect() );
if( pChildEffect.get() )
aSelection.push_back( pChildEffect );
}
-
- pChild = dynamic_cast< CustomAnimationListEntry* >( pChild->NextSibling() );
- }
+ } while (mxTreeView->iter_next_sibling(*xChild));
}
- pEntry = static_cast< CustomAnimationListEntry* >(NextSelected( pEntry ));
- }
+ return false;
+ });
return aSelection;
}
-bool CustomAnimationList::DoubleClickHdl()
+IMPL_LINK_NOARG(CustomAnimationList, DoubleClickHdl, weld::TreeView&, bool)
{
mpController->onDoubleClick();
return false;
}
-VclPtr<PopupMenu> CustomAnimationList::CreateContextMenu()
+IMPL_LINK(CustomAnimationList, CommandHdl, const CommandEvent&, rCEvt, bool)
{
- mxMenu.disposeAndClear();
- mxBuilder.reset(new VclBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "modules/simpress/ui/effectmenu.ui", ""));
- mxMenu.set(mxBuilder->get_menu("menu"));
+ if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
+ return false;
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(mxTreeView.get(), "modules/simpress/ui/effectmenu.ui"));
+ std::unique_ptr<weld::Menu> xMenu = xBuilder->weld_menu("menu");
sal_Int16 nNodeType = -1;
sal_Int16 nEntries = 0;
- CustomAnimationListEntry* pEntry = static_cast< CustomAnimationListEntry* >(FirstSelected());
- while( pEntry )
- {
+ mxTreeView->selected_foreach([this, &nNodeType, &nEntries](weld::TreeIter& rEntry){
+ CustomAnimationListEntryItem* pEntry = reinterpret_cast<CustomAnimationListEntryItem*>(mxTreeView->get_id(rEntry).toInt64());
+ CustomAnimationEffectPtr pEffect(pEntry->getEffect());
+
nEntries++;
- CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
- if( pEffect.get() )
+ if (pEffect.get())
{
if( nNodeType == -1 )
{
@@ -1291,26 +1153,30 @@ VclPtr<PopupMenu> CustomAnimationList::CreateContextMenu()
if( nNodeType != pEffect->getNodeType() )
{
nNodeType = -1;
- break;
+ return true;
}
}
}
- pEntry = static_cast< CustomAnimationListEntry* >(NextSelected( pEntry ));
- }
+ return false;
+ });
+
+ xMenu->set_active("onclick", nNodeType == EffectNodeType::ON_CLICK);
+ xMenu->set_active("withprev", nNodeType == EffectNodeType::WITH_PREVIOUS);
+ xMenu->set_active("afterprev", nNodeType == EffectNodeType::AFTER_PREVIOUS);
+ xMenu->set_sensitive("options", nEntries == 1);
+ xMenu->set_sensitive("timing", nEntries == 1);
- mxMenu->CheckItem("onclick", nNodeType == EffectNodeType::ON_CLICK);
- mxMenu->CheckItem("withprev", nNodeType == EffectNodeType::WITH_PREVIOUS);
- mxMenu->CheckItem("afterprev", nNodeType == EffectNodeType::AFTER_PREVIOUS);
- mxMenu->EnableItem(mxMenu->GetItemId("options"), nEntries == 1);
- mxMenu->EnableItem(mxMenu->GetItemId("timing"), nEntries == 1);
+ OString sCommand = xMenu->popup_at_rect(mxTreeView.get(), ::tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1)));
+ if (!sCommand.isEmpty())
+ ExecuteContextMenuAction(sCommand);
- return mxMenu;
+ return true;
}
-void CustomAnimationList::ExecuteContextMenuAction( sal_uInt16 nSelectedPopupEntry )
+void CustomAnimationList::ExecuteContextMenuAction(const OString& rIdent)
{
- mpController->onContextMenu(mxMenu->GetItemIdent(nSelectedPopupEntry));
+ mpController->onContextMenu(rIdent);
}
void CustomAnimationList::notify_change()
@@ -1319,34 +1185,6 @@ void CustomAnimationList::notify_change()
mpController->onSelect();
}
-void CustomAnimationList::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect)
-{
- if( mbIgnorePaint )
- return;
-
- SvTreeListBox::Paint(rRenderContext, rRect);
-
- // draw help text if list box is still empty
- if( First() != nullptr )
- return;
-
- Color aOldColor(rRenderContext.GetTextColor());
- rRenderContext.SetTextColor(rRenderContext.GetSettings().GetStyleSettings().GetDisableColor());
- ::Point aOffset(rRenderContext.LogicToPixel(Point(6, 6), MapMode(MapUnit::MapAppFont)));
-
- ::tools::Rectangle aRect(Point(0,0), GetOutputSizePixel());
-
- aRect.AdjustLeft(aOffset.X() );
- aRect.AdjustTop(aOffset.Y() );
- aRect.AdjustRight( -(aOffset.X()) );
- aRect.AdjustBottom( -(aOffset.Y()) );
-
- rRenderContext.DrawText(aRect, SdResId(STR_CUSTOMANIMATION_LIST_HELPTEXT),
- DrawTextFlags::MultiLine | DrawTextFlags::WordBreak | DrawTextFlags::Center | DrawTextFlags::VCenter );
-
- rRenderContext.SetTextColor(aOldColor);
-}
-
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/animations/CustomAnimationList.hxx b/sd/source/ui/animations/CustomAnimationList.hxx
index 9b738188c962..398793840187 100644
--- a/sd/source/ui/animations/CustomAnimationList.hxx
+++ b/sd/source/ui/animations/CustomAnimationList.hxx
@@ -24,7 +24,8 @@
#include <memory>
-#include <vcl/treelistbox.hxx>
+#include <vcl/transfer.hxx>
+#include <vcl/weld.hxx>
#include <CustomAnimationEffect.hxx>
namespace com { namespace sun { namespace star { namespace drawing { class XShape; } } } }
@@ -45,15 +46,31 @@ public:
virtual ~ICustomAnimationListController() {}
};
-class CustomAnimationList : public SvTreeListBox, public ISequenceListener
+class CustomAnimationList;
+class CustomAnimationListEntryItem;
+
+class CustomAnimationListDropTarget : public DropTargetHelper
+{
+private:
+ CustomAnimationList& m_rTreeView;
+
+ virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override;
+ virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override;
+
+public:
+ CustomAnimationListDropTarget(CustomAnimationList& rTreeView);
+};
+
+class CustomAnimationList : public ISequenceListener
{
friend class CustomAnimationListEntryItem;
friend struct stl_append_effect_func;
public:
- explicit CustomAnimationList( vcl::Window* pParent );
- virtual ~CustomAnimationList() override;
- virtual void dispose() override;
+ explicit CustomAnimationList(std::unique_ptr<weld::TreeView> xTreeView,
+ std::unique_ptr<weld::Label> xLabel,
+ std::unique_ptr<weld::Widget> xScrolledWindow);
+ virtual ~CustomAnimationList();
// methods
@@ -71,22 +88,10 @@ public:
// events
void onSelectionChanged(const css::uno::Any& rSelection);
- // overrides
- virtual void SelectHdl() override;
- virtual void DeselectHdl() override;
- virtual bool DoubleClickHdl() override;
-
- virtual void Paint( vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect ) override;
-
- virtual VclPtr<PopupMenu> CreateContextMenu() override;
- virtual void ExecuteContextMenuAction( sal_uInt16 nSelectedPopupEntry ) override;
-
- virtual void KeyInput( const KeyEvent& rKEvt ) override;
+ void Select();
virtual void notify_change() override;
- virtual bool Expand( SvTreeListEntry* pParent ) override;
- virtual bool Collapse( SvTreeListEntry* pParent ) override;
bool isExpanded( const CustomAnimationEffectPtr& pEffect ) const;
bool isVisible( const CustomAnimationEffectPtr& pEffect ) const;
@@ -98,23 +103,41 @@ public:
mpController = pController;
};
+ sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt);
+ sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt);
-protected:
- // drag & drop
- virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel ) override;
- virtual DragDropMode NotifyStartDrag( TransferDataContainer& rData, SvTreeListEntry* pEntry ) override;
- virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override;
- void ReparentChildrenDuringDrag();
- void ReorderEffectsInUiDuringDragOver( SvTreeListEntry* pOverEntry);
- virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override;
- virtual void DragFinished( sal_Int8 nDropAction ) override;
+ void set_sensitive(bool bSensitive) { mxTreeView->set_sensitive(bSensitive); }
+ int get_height_rows(int nRows) { return mxTreeView->get_height_rows(nRows); }
+ int get_approximate_digit_width() const { return mxTreeView->get_approximate_digit_width(); }
+ void set_size_request(int nWidth, int nHeight) { mxTreeView->set_size_request(nWidth, nHeight); }
+ void unselect_all() { mxTreeView->unselect_all(); }
+ weld::TreeView& get_widget() { return *mxTreeView; }
+
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+ DECL_LINK(ExpandHdl, const weld::TreeIter&, bool);
+ DECL_LINK(PostExpandHdl, void*, void);
+ DECL_LINK(CollapseHdl, const weld::TreeIter&, bool);
+ DECL_LINK(PostCollapseHdl, void*, void);
private:
- std::unique_ptr<VclBuilder> mxBuilder;
- VclPtr<PopupMenu> mxMenu;
+ std::unique_ptr<weld::TreeView> mxTreeView;
+ CustomAnimationListDropTarget maDropTargetHelper;
+ std::unique_ptr<weld::Label> mxEmptyLabel;
+ std::unique_ptr<weld::Widget> mxEmptyLabelParent;
+ std::vector<std::unique_ptr<CustomAnimationListEntryItem>> mxEntries;
+ std::vector<std::unique_ptr<weld::TreeIter>> lastSelectedEntries;
bool mbIgnorePaint;
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(CommandHdl, const CommandEvent&, bool);
+ DECL_LINK(DoubleClickHdl, weld::TreeView&, bool);
+ DECL_LINK(DragBeginHdl, bool&, bool);
+ DECL_STATIC_LINK(CustomAnimationList, CustomRenderHdl, weld::TreeView::render_args, void);
+ DECL_STATIC_LINK(CustomAnimationList, CustomGetSizeHdl, weld::TreeView::get_size_args, Size);
+
+ void ExecuteContextMenuAction(const OString& rSelectedPopupEntry);
+
/** appends the given effect to the list*/
void append( CustomAnimationEffectPtr pEffect );
@@ -124,12 +147,15 @@ private:
css::uno::Reference< css::drawing::XShape > mxLastTargetShape;
sal_Int32 mnLastGroupId;
- SvTreeListEntry* mpLastParentEntry;
+ ImplSVEvent* mnPostExpandEvent;
+ ImplSVEvent* mnPostCollapseEvent;
+
+ std::unique_ptr<weld::TreeIter> mxLastParentEntry;
// drag & drop
- SvTreeListEntry* mpDndEffectDragging;
- SvTreeListEntry* mpDndEffectInsertBefore;
- std::vector< SvTreeListEntry* > mDndEffectsSelected;
+ std::unique_ptr<weld::TreeIter> mxDndEffectDragging;
+ std::unique_ptr<weld::TreeIter> mxDndEffectInsertBefore;
+ std::vector<std::unique_ptr<weld::TreeIter>> mDndEffectsSelected;
};
OUString getPropertyName( sal_Int32 nPropertyType );
diff --git a/sd/source/ui/animations/CustomAnimationPane.cxx b/sd/source/ui/animations/CustomAnimationPane.cxx
index 5b4ff943ec2e..15dde73e15ab 100644
--- a/sd/source/ui/animations/CustomAnimationPane.cxx
+++ b/sd/source/ui/animations/CustomAnimationPane.cxx
@@ -46,10 +46,6 @@
#include "motionpathtag.hxx"
#include <CustomAnimationPreset.hxx>
#include <createcustomanimationpanel.hxx>
-#include <vcl/lstbox.hxx>
-#include <vcl/fixed.hxx>
-
-#include <vcl/button.hxx>
#include <comphelper/lok.hxx>
#include <comphelper/sequence.hxx>
@@ -123,81 +119,68 @@ void fillRepeatComboBox(weld::ComboBox& rBox)
CustomAnimationPane::CustomAnimationPane( Window* pParent, ViewShellBase& rBase,
const css::uno::Reference<css::frame::XFrame>& rxFrame )
-: PanelLayout( pParent, "CustomAnimationsPanel", "modules/simpress/ui/customanimationspanel.ui", rxFrame ),
- mrBase( rBase ),
- mnPropertyType( nPropertyTypeNone ),
- mnCurvePathPos( LISTBOX_ENTRY_NOTFOUND ),
- mnPolygonPathPos( LISTBOX_ENTRY_NOTFOUND ),
- mnFreeformPathPos( LISTBOX_ENTRY_NOTFOUND ),
- maLateInitTimer()
+ : PanelLayout(pParent, "CustomAnimationsPanel", "modules/simpress/ui/customanimationspanel.ui", rxFrame, true)
+ , mrBase(rBase)
+ // load resources
+ , mxFTAnimation(m_xBuilder->weld_label("effectlabel"))
+ , mxCustomAnimationList(new CustomAnimationList(m_xBuilder->weld_tree_view("custom_animation_list"),
+ m_xBuilder->weld_label("custom_animation_label"),
+ m_xBuilder->weld_widget("custom_animation_label_parent")))
+ , mxPBAddEffect(m_xBuilder->weld_button("add_effect"))
+ , mxPBRemoveEffect(m_xBuilder->weld_button("remove_effect"))
+ , mxPBMoveUp(m_xBuilder->weld_button("move_up"))
+ , mxPBMoveDown(m_xBuilder->weld_button("move_down"))
+ , mxFTCategory(m_xBuilder->weld_label("categorylabel"))
+ , mxLBCategory(m_xBuilder->weld_combo_box("categorylb"))
+ , mxFTEffect(m_xBuilder->weld_label("effect_label"))
+ , mxLBAnimation(m_xBuilder->weld_tree_view("effect_list"))
+ , mxFTStart(m_xBuilder->weld_label("start_effect"))
+ , mxLBStart(m_xBuilder->weld_combo_box("start_effect_list"))
+ , mxFTProperty(m_xBuilder->weld_label("effect_property"))
+ , mxPlaceholderBox(m_xBuilder->weld_container("placeholder"))
+ , mxPBPropertyMore(m_xBuilder->weld_button("more_properties"))
+ , mxFTDuration(m_xBuilder->weld_label("effect_duration"))
+ , mxCBXDuration(m_xBuilder->weld_metric_spin_button("anim_duration", FieldUnit::SECOND))
+ , mxFTStartDelay(m_xBuilder->weld_label("delay_label"))
+ , mxMFStartDelay(m_xBuilder->weld_metric_spin_button("delay_value", FieldUnit::SECOND))
+ , mxCBAutoPreview(m_xBuilder->weld_check_button("auto_preview"))
+ , mxPBPlay(m_xBuilder->weld_button("play"))
+ , mnLastSelectedAnimation(-1)
+ , mnPropertyType(nPropertyTypeNone)
+ , mnCurvePathPos(-1)
+ , mnPolygonPathPos(-1)
+ , mnFreeformPathPos(-1)
+ , maLateInitTimer()
{
initialize();
}
void CustomAnimationPane::initialize()
{
- // load resources
- get(mpPBAddEffect, "add_effect");
- get(mpPBRemoveEffect, "remove_effect");
-
- get(mpFTEffect, "effect_label");
-
- get(mpFTStart, "start_effect");
- get(mpLBStart, "start_effect_list");
- get(mpFTProperty, "effect_property");
- get(mpPlaceholderBox, "placeholder");
- get(mpLBProperty, "effect_property_list");
- get(mpPBPropertyMore, "more_properties");
-
- get(mpFTDuration, "effect_duration");
- get(mpCBXDuration, "anim_duration");
- get(mpFTCategory, "categorylabel");
- get(mpLBCategory, "categorylb");
- get(mpFTAnimation, "effectlabel");
- get(mpLBAnimation, "effect_list");
- get(mpFTStartDelay, "delay_label");
- get(mpMFStartDelay, "delay_value");
-
- mpLBAnimation->SetSelectHdl(LINK(this, CustomAnimationPane, AnimationSelectHdl));
- get(mpCustomAnimationList, "custom_animation_list");
- mpCustomAnimationList->setController( dynamic_cast<ICustomAnimationListController*> ( this ) );
- mpCustomAnimationList->set_width_request(mpCustomAnimationList->approximate_digit_width() * 15);
- mpCustomAnimationList->set_height_request(mpCustomAnimationList->GetTextHeight() * 8);
-
- mpLBAnimation->set_width_request(mpLBAnimation->approximate_digit_width() * 15);
- mpLBAnimation->set_height_request(mpLBAnimation->GetTextHeight() * 8);
-
- get(mpPBMoveUp, "move_up");
- get(mpPBMoveDown, "move_down");
- get(mpPBPlay, "play");
- get(mpCBAutoPreview,"auto_preview");
-
- maStrProperty = mpFTProperty->GetText();
-
- //fillDurationMetricComboBox
- mpCBXDuration->InsertValue(50, FieldUnit::CUSTOM);
- mpCBXDuration->InsertValue(100, FieldUnit::CUSTOM);
- mpCBXDuration->InsertValue(200, FieldUnit::CUSTOM);
- mpCBXDuration->InsertValue(300, FieldUnit::CUSTOM);
- mpCBXDuration->InsertValue(500, FieldUnit::CUSTOM);
- mpCBXDuration->AdaptDropDownLineCountToMaximum();
-
-
- mpPBAddEffect->SetClickHdl( LINK( this, CustomAnimationPane, implClickHdl ) );
- mpPBRemoveEffect->SetClickHdl( LINK( this, CustomAnimationPane, implClickHdl ) );
- mpLBStart->SetSelectHdl( LINK( this, CustomAnimationPane, implControlListBoxHdl ) );
- mpCBXDuration->SetModifyHdl(LINK( this, CustomAnimationPane, DurationModifiedHdl));
- mpPBPropertyMore->SetClickHdl( LINK( this, CustomAnimationPane, implClickHdl ) );
- mpPBMoveUp->SetClickHdl( LINK( this, CustomAnimationPane, implClickHdl ) );
- mpPBMoveDown->SetClickHdl( LINK( this, CustomAnimationPane, implClickHdl ) );
- mpPBPlay->SetClickHdl( LINK( this, CustomAnimationPane, implClickHdl ) );
- mpCBAutoPreview->SetClickHdl( LINK( this, CustomAnimationPane, implClickHdl ) );
- mpLBCategory->SetSelectHdl( LINK(this, CustomAnimationPane, UpdateAnimationLB) );
- mpMFStartDelay->SetModifyHdl( LINK(this, CustomAnimationPane, DelayModifiedHdl) );
- mpMFStartDelay->SetLoseFocusHdl(LINK( this, CustomAnimationPane, DelayLoseFocusHdl));
-
-
- maStrModify = mpFTEffect->GetText();
+ mxLBAnimation->connect_changed(LINK(this, CustomAnimationPane, AnimationSelectHdl));
+ mxCustomAnimationList->setController( dynamic_cast<ICustomAnimationListController*> ( this ) );
+ mxCustomAnimationList->set_size_request(mxCustomAnimationList->get_approximate_digit_width() * 15,
+ mxCustomAnimationList->get_height_rows(8));
+
+ mxLBAnimation->set_size_request(mxLBAnimation->get_approximate_digit_width() * 15,
+ mxLBAnimation->get_height_rows(8));
+
+ maStrProperty = mxFTProperty->get_label();
+
+ mxPBAddEffect->connect_clicked( LINK( this, CustomAnimationPane, implClickHdl ) );
+ mxPBRemoveEffect->connect_clicked( LINK( this, CustomAnimationPane, implClickHdl ) );
+ mxLBStart->connect_changed( LINK( this, CustomAnimationPane, implControlListBoxHdl ) );
+ mxCBXDuration->connect_value_changed(LINK( this, CustomAnimationPane, DurationModifiedHdl));
+ mxPBPropertyMore->connect_clicked( LINK( this, CustomAnimationPane, implClickHdl ) );
+ mxPBMoveUp->connect_clicked( LINK( this, CustomAnimationPane, implClickHdl ) );
+ mxPBMoveDown->connect_clicked( LINK( this, CustomAnimationPane, implClickHdl ) );
+ mxPBPlay->connect_clicked( LINK( this, CustomAnimationPane, implClickHdl ) );
+ mxCBAutoPreview->connect_clicked( LINK( this, CustomAnimationPane, implClickHdl ) );
+ mxLBCategory->connect_changed( LINK(this, CustomAnimationPane, UpdateAnimationLB) );
+ mxMFStartDelay->connect_value_changed( LINK(this, CustomAnimationPane, DelayModifiedHdl) );
+ mxMFStartDelay->connect_focus_out(LINK( this, CustomAnimationPane, DelayLoseFocusHdl));
+
+ maStrModify = mxFTEffect->get_label();
// get current controller and initialize listeners
try
@@ -237,28 +220,28 @@ void CustomAnimationPane::dispose()
for (auto const& tag : aTags)
tag->Dispose();
- mpPBAddEffect.clear();
- mpPBRemoveEffect.clear();
- mpFTEffect.clear();
- mpFTStart.clear();
- mpLBStart.clear();
- mpFTProperty.clear();
- mpPlaceholderBox.clear();
- mpLBProperty.clear();
- mpPBPropertyMore.clear();
- mpFTDuration.clear();
- mpCBXDuration.clear();
- mpFTStartDelay.clear();
- mpMFStartDelay.clear();
- mpCustomAnimationList.clear();
- mpPBMoveUp.clear();
- mpPBMoveDown.clear();
- mpPBPlay.clear();
- mpCBAutoPreview.clear();
- mpFTCategory.clear();
- mpLBCategory.clear();
- mpFTAnimation.clear();
- mpLBAnimation.clear();
+ mxPBAddEffect.reset();
+ mxPBRemoveEffect.reset();
+ mxFTEffect.reset();
+ mxFTStart.reset();
+ mxLBStart.reset();
+ mxLBSubControl.reset();
+ mxFTProperty.reset();
+ mxPlaceholderBox.reset();
+ mxPBPropertyMore.reset();
+ mxFTDuration.reset();
+ mxCBXDuration.reset();
+ mxFTStartDelay.reset();
+ mxMFStartDelay.reset();
+ mxCustomAnimationList.reset();
+ mxPBMoveUp.reset();
+ mxPBMoveDown.reset();
+ mxPBPlay.reset();
+ mxCBAutoPreview.reset();
+ mxFTCategory.reset();
+ mxLBCategory.reset();
+ mxFTAnimation.reset();
+ mxLBAnimation.reset();
PanelLayout::dispose();
}
@@ -284,8 +267,8 @@ void CustomAnimationPane::StateChanged( StateChangedType nStateChange )
void CustomAnimationPane::KeyInput( const KeyEvent& rKEvt )
{
- if( mpCustomAnimationList )
- mpCustomAnimationList->KeyInput( rKEvt );
+ if (mxCustomAnimationList)
+ mxCustomAnimationList->KeyInputHdl(rKEvt);
}
void CustomAnimationPane::addListener()
@@ -340,8 +323,8 @@ IMPL_LINK(CustomAnimationPane,EventMultiplexerListener,
onChangeCurrentPage();
break;
case EventMultiplexerEventId::EndTextEdit:
- if( mpMainSequence.get() && rEvent.mpUserData )
- mpCustomAnimationList->update( mpMainSequence );
+ if (mpMainSequence.get() && rEvent.mpUserData)
+ mxCustomAnimationList->update( mpMainSequence );
break;
default: break;
}
@@ -470,70 +453,74 @@ OUString getPropertyName( sal_Int32 nPropertyType )
void CustomAnimationPane::updateControls()
{
- mpFTDuration->Enable( mxView.is() );
- mpCBXDuration->Enable( mxView.is() );
- mpCustomAnimationList->Enable( mxView.is() );
+ mxFTDuration->set_sensitive(mxView.is());
+ mxCBXDuration->set_sensitive(mxView.is());
+ mxCustomAnimationList->set_sensitive(mxView.is());
if (comphelper::LibreOfficeKit::isActive())
{
- mpPBPlay->Hide();
- mpCBAutoPreview->Check(false);
- mpCBAutoPreview->Hide();
+ mxPBPlay->hide();
+ mxCBAutoPreview->set_active(false);
+ mxCBAutoPreview->hide();
}
else
{
- mpPBPlay->Enable( mxView.is() );
- mpCBAutoPreview->Enable( mxView.is() );
- }
-
- if( !mxView.is() )
- {
- mpPBAddEffect->Enable( false );
- mpPBRemoveEffect->Enable( false );
- mpFTStart->Enable( false );
- mpLBStart->Enable( false );
- mpPBPropertyMore->Enable( false );
- mpLBProperty->Enable( false );
- mpFTProperty->Enable( false );
- mpFTCategory->Disable();
- mpLBCategory->Disable();
- mpFTAnimation->Disable();
- mpLBAnimation->Disable();
- mpFTStartDelay->Disable();
- mpMFStartDelay->Disable();
- mpLBAnimation->Clear();
- mpCustomAnimationList->clear();
+ mxPBPlay->set_sensitive(mxView.is());
+ mxCBAutoPreview->set_sensitive(mxView.is());
+ }
+
+ if (!mxView.is())
+ {
+ mxPBAddEffect->set_sensitive(false);
+ mxPBRemoveEffect->set_sensitive(false);
+ mxFTStart->set_sensitive(false);
+ mxLBStart->set_sensitive(false);
+ mxPBPropertyMore->set_sensitive(false);
+ mxPlaceholderBox->set_sensitive(false);
+ mxFTProperty->set_sensitive(false);
+ mxFTCategory->set_sensitive(false);
+ mxLBCategory->set_sensitive(false);
+ mxFTAnimation->set_sensitive(false);
+ mxLBAnimation->set_sensitive(false);
+ mxFTStartDelay->set_sensitive(false);
+ mxMFStartDelay->set_sensitive(false);
+ mxLBAnimation->clear();
+ mnLastSelectedAnimation = -1;
+ mxCustomAnimationList->clear();
return;
}
const int nSelectionCount = maListSelection.size();
- mpPBAddEffect->Enable( maViewSelection.hasValue() );
- mpPBRemoveEffect->Enable(nSelectionCount != 0);
+ mxPBAddEffect->set_sensitive( maViewSelection.hasValue() );
+ mxPBRemoveEffect->set_sensitive(nSelectionCount != 0);
bool bIsSelected = (nSelectionCount == 1);
if(bIsSelected)
{
- mpFTAnimation->Enable();
- mpLBAnimation->Enable();
+ mxFTAnimation->set_sensitive(true);
+ mxLBAnimation->set_sensitive(true);
}
else
{
- mpFTAnimation->Disable();
- mpLBAnimation->Disable();
- mpLBAnimation->Clear();
+ mxFTAnimation->set_sensitive(false);
+ mxLBAnimation->set_sensitive(false);
+ mxLBAnimation->clear();
+ mnLastSelectedAnimation = -1;
}
- mpLBCategory->Enable(bIsSelected);
- mpFTCategory->Enable(bIsSelected);
+ mxLBCategory->set_sensitive(bIsSelected);
+ mxFTCategory->set_sensitive(bIsSelected);
- mpFTStart->Enable(nSelectionCount > 0);
- mpLBStart->Enable(nSelectionCount > 0);
- mpLBProperty->Enable(nSelectionCount > 0);
- mpPBPropertyMore->Enable(nSelectionCount > 0);
- mpFTStartDelay->Enable(nSelectionCount > 0);
- mpMFStartDelay->Enable(nSelectionCount > 0);
+ mxFTStart->set_sensitive(nSelectionCount > 0);
+ mxLBStart->set_sensitive(nSelectionCount > 0);
+ mxPlaceholderBox->set_sensitive(nSelectionCount > 0);
+ mxPBPropertyMore->set_sensitive(nSelectionCount > 0);
+ mxFTStartDelay->set_sensitive(nSelectionCount > 0);
+ mxMFStartDelay->set_sensitive(nSelectionCount > 0);
- mpFTProperty->SetText( maStrProperty );
+ mxFTProperty->set_label(maStrProperty);
+
+ sal_Int32 nOldPropertyType = mnPropertyType;
mnPropertyType = nPropertyTypeNone;
@@ -548,59 +535,50 @@ void CustomAnimationPane::updateControls()
if( !aUIName.isEmpty() )
{
aTemp += " " + aUIName;
- mpFTEffect->SetText( aTemp );
+ mxFTEffect->set_label( aTemp );
}
+ Any aValue;
CustomAnimationPresetPtr pDescriptor = CustomAnimationPresets::getCustomAnimationPresets().getEffectDescriptor( pEffect->getPresetId() );
- if( pDescriptor.get() )
+ if (pDescriptor.get())
{
- PropertySubControl* pSubControl = nullptr;
-
- Any aValue;
-
std::vector<OUString> aProperties( pDescriptor->getProperties() );
if( !aProperties.empty() )
{
mnPropertyType = getPropertyType( aProperties.front() );
- mpFTProperty->SetText( getPropertyName( mnPropertyType ) );
+ mxFTProperty->set_label( getPropertyName( mnPropertyType ) );
aValue = getProperty1Value( mnPropertyType, pEffect );
}
+ }
- if( aValue.hasValue() )
- {
- pSubControl = mpLBProperty->getSubControl();
- if( !pSubControl || (pSubControl->getControlType() != mnPropertyType) )
- {
- auto pNewControl = PropertySubControl::create( mnPropertyType, mpPlaceholderBox, aValue, pEffect->getPresetId(), LINK( this, CustomAnimationPane, implPropertyHdl ) );
- pSubControl = pNewControl.get();
- mpLBProperty->setSubControl( std::move(pNewControl) );
- }
- else
- {
- pSubControl->setValue( aValue, pEffect->getPresetId() );
- }
- }
- else
- {
- mpLBProperty->setSubControl( nullptr );
- }
+ sal_Int32 nNewPropertyType = mnPropertyType;
+ // if there is no value, then the control will be disabled, just show a disabled Direction box in that
+ // case to have something to fill the space
+ if (!aValue.hasValue())
+ nNewPropertyType = nPropertyTypeDirection;
- bool bEnable = (pSubControl != nullptr) && (pSubControl->getControl()->IsEnabled());
- mpLBProperty->Enable( bEnable );
- mpFTProperty->Enable( bEnable );
+ if (!mxLBSubControl || nOldPropertyType != nNewPropertyType)
+ {
+ mxLBSubControl = SdPropertySubControl::create(nNewPropertyType, mxFTProperty.get(), mxPlaceholderBox.get(), GetFrameWeld(), aValue, pEffect->getPresetId(), LINK(this, CustomAnimationPane, implPropertyHdl));
}
else
{
- mpLBProperty->setSubControl( nullptr );
- mpFTProperty->Enable( false );
- mpLBProperty->Enable( false );
- mpPBPropertyMore->Enable( false );
- mpFTStartDelay->Enable( false );
- mpMFStartDelay->Enable( false );
+ mxLBSubControl->setValue(aValue, pEffect->getPresetId());
+ }
+
+ bool bEnable = aValue.hasValue();
+ mxPlaceholderBox->set_sensitive( bEnable );
+ mxFTProperty->set_sensitive( bEnable );
+
+ if (!pDescriptor.get())
+ {
+ mxPBPropertyMore->set_sensitive( false );
+ mxFTStartDelay->set_sensitive( false );
+ mxMFStartDelay->set_sensitive( false );
}
- sal_uInt32 nCategoryPos = LISTBOX_ENTRY_NOTFOUND;
+ sal_Int32 nCategoryPos = -1;
switch(pEffect->getPresetClass())
{
case EffectPresetClass::ENTRANCE: nCategoryPos = 0; break;
@@ -619,19 +597,22 @@ void CustomAnimationPane::updateControls()
default:
break;
}
- mpLBCategory->SelectEntryPos(nCategoryPos);
+ mxLBCategory->set_active(nCategoryPos);
+
fillAnimationLB( pEffect->hasText() );
+
OUString rsPresetId = pEffect->getPresetId();
- sal_Int32 nAnimationPos = mpLBAnimation->GetEntryCount();
+ sal_Int32 nAnimationPos = mxLBAnimation->n_children();
while( nAnimationPos-- )
{
- void* pEntryData = mpLBAnimation->GetEntryData( nAnimationPos );
- if( pEntryData )
+ auto nEntryData = mxLBAnimation->get_id(nAnimationPos).toInt64();
+ if (nEntryData)
{
- CustomAnimationPresetPtr& pPtr = *static_cast< CustomAnimationPresetPtr* >(pEntryData);
+ CustomAnimationPresetPtr& pPtr = *reinterpret_cast<CustomAnimationPresetPtr*>(nEntryData);
if( pPtr.get() && pPtr->getPresetId() == rsPresetId )
{
- mpLBAnimation->SelectEntryPos( nAnimationPos );
+ mxLBAnimation->select( nAnimationPos );
+ mnLastSelectedAnimation = nAnimationPos;
break;
}
}
@@ -641,11 +622,20 @@ void CustomAnimationPane::updateControls()
if (nAnimationPos < 0 && nCategoryPos == 3)
{
if (rsPresetId == "libo-motionpath-curve")
- mpLBAnimation->SelectEntryPos(mnCurvePathPos);
+ {
+ mxLBAnimation->select(mnCurvePathPos);
+ mnLastSelectedAnimation = mnCurvePathPos;
+ }
else if (rsPresetId == "libo-motionpath-polygon")
- mpLBAnimation->SelectEntryPos(mnPolygonPathPos);
+ {
+ mxLBAnimation->select(mnPolygonPathPos);
+ mnLastSelectedAnimation = mnPolygonPathPos;
+ }
else if (rsPresetId == "libo-motionpath-freeform-line")
- mpLBAnimation->SelectEntryPos(mnFreeformPathPos);
+ {
+ mxLBAnimation->select(mnFreeformPathPos);
+ mnLastSelectedAnimation = mnFreeformPathPos;
+ }
}
sal_uInt16 nPos = 0xffff;
@@ -658,38 +648,39 @@ void CustomAnimationPane::updateControls()
case EffectNodeType::AFTER_PREVIOUS: nPos = 2; break;
}
- mpLBStart->SelectEntryPos( nPos );
+ mxLBStart->set_active( nPos );
double fDuration = pEffect->getDuration();
const bool bHasSpeed = fDuration > 0.001;
- mpFTDuration->Enable(bHasSpeed);
- mpCBXDuration->Enable(bHasSpeed);
+ mxFTDuration->set_sensitive(bHasSpeed);
+ mxCBXDuration->set_sensitive(bHasSpeed);
if( bHasSpeed )
{
- mpCBXDuration->SetValue( fDuration*100.0 );
+ mxCBXDuration->set_value(fDuration*100.0, FieldUnit::NONE);
}
- mpPBPropertyMore->Enable();
+ mxPBPropertyMore->set_sensitive(true);
- mpFTStartDelay->Enable();
- mpMFStartDelay->Enable();
+ mxFTStartDelay->set_sensitive(true);
+ mxMFStartDelay->set_sensitive(true);
double fBegin = pEffect->getBegin();
- mpMFStartDelay->SetValue(fBegin*10.0);
+ mxMFStartDelay->set_value(fBegin*10.0, FieldUnit::NONE);
}
else
{
- mpLBProperty->setSubControl( nullptr );
- mpFTProperty->Enable( false );
- mpLBProperty->Enable( false );
- mpFTStartDelay->Enable( false );
- mpMFStartDelay->Enable( false );
- mpPBPropertyMore->Enable( false );
- mpFTDuration->Enable(false);
- mpCBXDuration->Enable(false);
- mpCBXDuration->SetNoSelection();
- mpFTEffect->SetText( maStrModify );
+ // use an empty direction box to fill the space
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list