/* This file is part of Telegram Desktop, the official desktop version of Telegram messaging app, see https://telegram.org Telegram Desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. In addition, as a special exception, the copyright holders give permission to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #pragma once #include "ui/widgets/buttons.h" #include "styles/style_window.h" #include "styles/style_widgets.h" class PeerData; namespace Window { class Controller; } // namespace Window namespace FileDialog { struct OpenResult; } // namespace FileDialog namespace Ui { class HistoryDownButton : public RippleButton { public: HistoryDownButton(QWidget *parent, const style::TwoIconButton &st); void setUnreadCount(int unreadCount); int unreadCount() const { return _unreadCount; } protected: void paintEvent(QPaintEvent *e) override; QImage prepareRippleMask() const override; QPoint prepareRippleStartPosition() const override; private: const style::TwoIconButton &_st; int _unreadCount = 0; }; class EmojiButton : public RippleButton { public: EmojiButton(QWidget *parent, const style::IconButton &st); void setLoading(bool loading); void setColorOverrides(const style::icon *iconOverride, const style::color *colorOverride, const style::color *rippleOverride); protected: void paintEvent(QPaintEvent *e) override; void onStateChanged(State was, StateChangeSource source) override; QImage prepareRippleMask() const override; QPoint prepareRippleStartPosition() const override; private: void step_loading(TimeMs ms, bool timer) { if (timer) { update(); } } const style::IconButton &_st; bool _loading = false; Animation a_loading; BasicAnimation _a_loading; const style::icon *_iconOverride = nullptr; const style::color *_colorOverride = nullptr; const style::color *_rippleOverride = nullptr; }; class SendButton : public RippleButton { public: SendButton(QWidget *parent); enum class Type { Send, Save, Record, Cancel, }; Type type() const { return _type; } void setType(Type state); void setRecordActive(bool recordActive); void finishAnimating(); void setRecordStartCallback(base::lambda callback) { _recordStartCallback = std::move(callback); } void setRecordUpdateCallback(base::lambda callback) { _recordUpdateCallback = std::move(callback); } void setRecordStopCallback(base::lambda callback) { _recordStopCallback = std::move(callback); } void setRecordAnimationCallback(base::lambda callback) { _recordAnimationCallback = std::move(callback); } float64 recordActiveRatio() { return _a_recordActive.current(getms(), _recordActive ? 1. : 0.); } protected: void mouseMoveEvent(QMouseEvent *e) override; void paintEvent(QPaintEvent *e) override; void onStateChanged(State was, StateChangeSource source) override; QImage prepareRippleMask() const override; QPoint prepareRippleStartPosition() const override; private: void recordAnimationCallback(); QPixmap grabContent(); Type _type = Type::Send; bool _recordActive = false; QPixmap _contentFrom, _contentTo; Animation _a_typeChanged; Animation _a_recordActive; bool _recording = false; base::lambda _recordStartCallback; base::lambda _recordStopCallback; base::lambda _recordUpdateCallback; base::lambda _recordAnimationCallback; }; class UserpicButton : public RippleButton { public: enum class Role { ChangePhoto, OpenPhoto, OpenProfile, Custom, }; UserpicButton( QWidget *parent, PeerId peerForCrop, Role role, const style::UserpicButton &st); UserpicButton( QWidget *parent, not_null controller, not_null peer, Role role, const style::UserpicButton &st); void switchChangePhotoOverlay(bool enabled); QImage takeResultImage() { return std::move(_result); } protected: void paintEvent(QPaintEvent *e); QImage prepareRippleMask() const override; QPoint prepareRippleStartPosition() const override; private: void prepare(); void setImage(QImage &&image); void setupPeerViewers(); void startAnimation(); void processPeerPhoto(); void processNewPeerPhoto(); void startNewPhotoShowing(); void prepareUserpicPixmap(); QPoint countPhotoPosition() const; void grabOldUserpic(); void setClickHandlerByRole(); void openPeerPhoto(); void changePhotoLazy(); void suggestPhotoFile( const FileDialog::OpenResult &result); void suggestPhoto(const QImage &image); const style::UserpicButton &_st; Window::Controller *_controller = nullptr; PeerData *_peer = nullptr; PeerId _peerForCrop = 0; Role _role = Role::ChangePhoto; bool _notShownYet = true; bool _waiting = false; QPixmap _userpic, _oldUserpic; bool _userpicHasImage = false; bool _userpicCustom = false; StorageKey _userpicUniqueKey; Animation _a_appearance; QImage _result; }; } // namespace Ui