143 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			143 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// This file is part of Desktop App Toolkit,
 | 
						|
// a set of libraries for developing nice desktop applications.
 | 
						|
//
 | 
						|
// For license and copyright information please follow this link:
 | 
						|
// https://github.com/desktop-app/legal/blob/master/LEGAL
 | 
						|
//
 | 
						|
#pragma once
 | 
						|
 | 
						|
#include "styles/style_widgets.h"
 | 
						|
#include "ui/rp_widget.h"
 | 
						|
#include "ui/round_rect.h"
 | 
						|
#include "ui/effects/animations.h"
 | 
						|
#include "ui/effects/panel_animation.h"
 | 
						|
#include "base/object_ptr.h"
 | 
						|
#include "base/timer.h"
 | 
						|
 | 
						|
namespace Ui {
 | 
						|
 | 
						|
class ScrollArea;
 | 
						|
 | 
						|
class InnerDropdown : public RpWidget {
 | 
						|
 | 
						|
public:
 | 
						|
	InnerDropdown(QWidget *parent, const style::InnerDropdown &st = st::defaultInnerDropdown);
 | 
						|
 | 
						|
	template <typename Widget>
 | 
						|
	QPointer<Widget> setOwnedWidget(object_ptr<Widget> widget) {
 | 
						|
		auto result = doSetOwnedWidget(std::move(widget));
 | 
						|
		return QPointer<Widget>(static_cast<Widget*>(result.data()));
 | 
						|
	}
 | 
						|
 | 
						|
	bool overlaps(const QRect &globalRect) {
 | 
						|
		if (isHidden() || _a_show.animating() || _a_opacity.animating()) return false;
 | 
						|
 | 
						|
		return rect().marginsRemoved(_st.padding).contains(QRect(mapFromGlobal(globalRect.topLeft()), globalRect.size()));
 | 
						|
	}
 | 
						|
 | 
						|
	void setAutoHiding(bool autoHiding) {
 | 
						|
		_autoHiding = autoHiding;
 | 
						|
	}
 | 
						|
	void setMaxHeight(int newMaxHeight);
 | 
						|
	void resizeToContent();
 | 
						|
 | 
						|
	void otherEnter();
 | 
						|
	void otherLeave();
 | 
						|
 | 
						|
	void setShowStartCallback(Fn<void()> callback) {
 | 
						|
		_showStartCallback = std::move(callback);
 | 
						|
	}
 | 
						|
	void setHideStartCallback(Fn<void()> callback) {
 | 
						|
		_hideStartCallback = std::move(callback);
 | 
						|
	}
 | 
						|
	void setHiddenCallback(Fn<void()> callback) {
 | 
						|
		_hiddenCallback = std::move(callback);
 | 
						|
	}
 | 
						|
 | 
						|
	bool isHiding() const {
 | 
						|
		return _hiding && _a_opacity.animating();
 | 
						|
	}
 | 
						|
 | 
						|
	enum class HideOption {
 | 
						|
		Default,
 | 
						|
		IgnoreShow,
 | 
						|
	};
 | 
						|
	void showAnimated();
 | 
						|
	void setOrigin(PanelAnimation::Origin origin);
 | 
						|
	void showAnimated(PanelAnimation::Origin origin);
 | 
						|
	void hideAnimated(HideOption option = HideOption::Default);
 | 
						|
	void finishAnimating();
 | 
						|
	void showFast();
 | 
						|
	void hideFast();
 | 
						|
 | 
						|
protected:
 | 
						|
	void resizeEvent(QResizeEvent *e) override;
 | 
						|
	void paintEvent(QPaintEvent *e) override;
 | 
						|
	void enterEventHook(QEnterEvent *e) override;
 | 
						|
	void leaveEventHook(QEvent *e) override;
 | 
						|
	bool eventFilter(QObject *obj, QEvent *e) override;
 | 
						|
 | 
						|
	int resizeGetHeight(int newWidth) override;
 | 
						|
 | 
						|
 | 
						|
private:
 | 
						|
	QPointer<RpWidget> doSetOwnedWidget(object_ptr<RpWidget> widget);
 | 
						|
	QImage grabForPanelAnimation();
 | 
						|
	void startShowAnimation();
 | 
						|
	void startOpacityAnimation(bool hiding);
 | 
						|
	void prepareCache();
 | 
						|
 | 
						|
	class Container;
 | 
						|
	void showAnimationCallback();
 | 
						|
	void opacityAnimationCallback();
 | 
						|
 | 
						|
	void hideFinished();
 | 
						|
	void showStarted();
 | 
						|
 | 
						|
	void updateHeight();
 | 
						|
 | 
						|
	void scrolled();
 | 
						|
 | 
						|
	const style::InnerDropdown &_st;
 | 
						|
 | 
						|
	RoundRect _roundRect;
 | 
						|
	PanelAnimation::Origin _origin = PanelAnimation::Origin::TopLeft;
 | 
						|
	std::unique_ptr<PanelAnimation> _showAnimation;
 | 
						|
	Animations::Simple _a_show;
 | 
						|
 | 
						|
	bool _autoHiding = true;
 | 
						|
	bool _hiding = false;
 | 
						|
	QPixmap _cache;
 | 
						|
	Animations::Simple _a_opacity;
 | 
						|
 | 
						|
	base::Timer _hideTimer;
 | 
						|
	bool _ignoreShowEvents = false;
 | 
						|
	Fn<void()> _showStartCallback;
 | 
						|
	Fn<void()> _hideStartCallback;
 | 
						|
	Fn<void()> _hiddenCallback;
 | 
						|
 | 
						|
	object_ptr<ScrollArea> _scroll;
 | 
						|
 | 
						|
	int _maxHeight = 0;
 | 
						|
 | 
						|
};
 | 
						|
 | 
						|
class InnerDropdown::Container : public TWidget {
 | 
						|
public:
 | 
						|
	Container(QWidget *parent, object_ptr<TWidget> child, const style::InnerDropdown &st);
 | 
						|
 | 
						|
	void resizeToContent();
 | 
						|
 | 
						|
protected:
 | 
						|
	int resizeGetHeight(int newWidth) override;
 | 
						|
	void visibleTopBottomUpdated(
 | 
						|
		int visibleTop,
 | 
						|
		int visibleBottom) override;
 | 
						|
 | 
						|
private:
 | 
						|
	object_ptr<TWidget> _child;
 | 
						|
	const style::InnerDropdown &_st;
 | 
						|
 | 
						|
};
 | 
						|
 | 
						|
} // namespace Ui
 |