From 356b48bccae0f3b30c72484db250d47a79471bc1 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 11 Jul 2016 21:05:46 +0300 Subject: [PATCH] Started video player UI in MediaView. --- Telegram/Resources/basic_types.style | 14 ++ .../Resources/icons/media_fullscreen_from.png | Bin 0 -> 405 bytes .../icons/media_fullscreen_from@2x.png | Bin 0 -> 1847 bytes .../Resources/icons/media_fullscreen_to.png | Bin 0 -> 388 bytes .../icons/media_fullscreen_to@2x.png | Bin 0 -> 1749 bytes Telegram/Resources/icons/media_pause.png | Bin 0 -> 98 bytes Telegram/Resources/icons/media_pause@2x.png | Bin 0 -> 133 bytes Telegram/Resources/icons/media_play.png | Bin 0 -> 281 bytes Telegram/Resources/icons/media_play@2x.png | Bin 0 -> 375 bytes Telegram/Resources/icons/media_volume.png | Bin 0 -> 148 bytes Telegram/Resources/icons/media_volume@2x.png | Bin 0 -> 209 bytes Telegram/SourceFiles/application.cpp | 6 + Telegram/SourceFiles/application.h | 1 + .../SourceFiles/codegen/style/generator.cpp | 31 +++- .../SourceFiles/codegen/style/generator.h | 1 + Telegram/SourceFiles/codegen/style/module.h | 6 +- .../media/view/media_clip_controller.cpp | 116 ++++++++++++++ .../media/view/media_clip_controller.h | 82 ++++++++++ .../media/view/media_clip_playback.cpp | 131 ++++++++++++++++ .../media/view/media_clip_playback.h | 69 +++++++++ .../view/media_clip_volume_controller.cpp | 85 +++++++++++ .../media/view/media_clip_volume_controller.h | 59 ++++++++ .../SourceFiles/media/view/mediaview.style | 74 +++++++++ Telegram/SourceFiles/mediaview.cpp | 143 +++++++++++++++--- Telegram/SourceFiles/mediaview.h | 49 ++++-- Telegram/SourceFiles/ui/animation.h | 1 - .../SourceFiles/ui/buttons/icon_button.cpp | 56 +++++++ Telegram/SourceFiles/ui/buttons/icon_button.h | 51 +++++++ .../SourceFiles/ui/effects/fade_animation.cpp | 99 ++++++++++++ .../SourceFiles/ui/effects/fade_animation.h | 57 +++++++ .../SourceFiles/ui/widgets/label_simple.cpp | 52 +++++++ .../SourceFiles/ui/widgets/label_simple.h | 48 ++++++ Telegram/SourceFiles/ui/widgets/widgets.style | 34 +++++ Telegram/Telegram.vcxproj | 93 ++++++++++++ Telegram/Telegram.vcxproj.filters | 90 +++++++++++ 35 files changed, 1407 insertions(+), 41 deletions(-) create mode 100644 Telegram/Resources/icons/media_fullscreen_from.png create mode 100644 Telegram/Resources/icons/media_fullscreen_from@2x.png create mode 100644 Telegram/Resources/icons/media_fullscreen_to.png create mode 100644 Telegram/Resources/icons/media_fullscreen_to@2x.png create mode 100644 Telegram/Resources/icons/media_pause.png create mode 100644 Telegram/Resources/icons/media_pause@2x.png create mode 100644 Telegram/Resources/icons/media_play.png create mode 100644 Telegram/Resources/icons/media_play@2x.png create mode 100644 Telegram/Resources/icons/media_volume.png create mode 100644 Telegram/Resources/icons/media_volume@2x.png create mode 100644 Telegram/SourceFiles/media/view/media_clip_controller.cpp create mode 100644 Telegram/SourceFiles/media/view/media_clip_controller.h create mode 100644 Telegram/SourceFiles/media/view/media_clip_playback.cpp create mode 100644 Telegram/SourceFiles/media/view/media_clip_playback.h create mode 100644 Telegram/SourceFiles/media/view/media_clip_volume_controller.cpp create mode 100644 Telegram/SourceFiles/media/view/media_clip_volume_controller.h create mode 100644 Telegram/SourceFiles/media/view/mediaview.style create mode 100644 Telegram/SourceFiles/ui/buttons/icon_button.cpp create mode 100644 Telegram/SourceFiles/ui/buttons/icon_button.h create mode 100644 Telegram/SourceFiles/ui/effects/fade_animation.cpp create mode 100644 Telegram/SourceFiles/ui/effects/fade_animation.h create mode 100644 Telegram/SourceFiles/ui/widgets/label_simple.cpp create mode 100644 Telegram/SourceFiles/ui/widgets/label_simple.h create mode 100644 Telegram/SourceFiles/ui/widgets/widgets.style diff --git a/Telegram/Resources/basic_types.style b/Telegram/Resources/basic_types.style index ca5392b13..55b11e353 100644 --- a/Telegram/Resources/basic_types.style +++ b/Telegram/Resources/basic_types.style @@ -449,3 +449,17 @@ OutlineButton { font: font; padding: margins; } + +IconButton { + width: pixels; + height: pixels; + + opacity: double; + overOpacity: double; + + icon: icon; + iconPosition: point; + downIconPosition: point; + + duration: int; +} diff --git a/Telegram/Resources/icons/media_fullscreen_from.png b/Telegram/Resources/icons/media_fullscreen_from.png new file mode 100644 index 0000000000000000000000000000000000000000..6d241d992ee22bf7b8ed463ec966277bc2c0aa73 GIT binary patch literal 405 zcmV;G0c!q0H7$UZG5oe%_xa5ma z9LL5B{538cHhh#sMBtn|A+BrOh4dAYMcUsARK8-ew?Oh zXxhO`YMO?sssOm%ZaO+T=u?RI0aSXf(IV`^%O(a}+Y!65Q!j6V!{LoF5ym6esK zs!BKWf?io zcJE}zHL{oz`Fl>Mlb)U)a=9EYUc4ZkPVZA;_wVxZa_-)}OJ83fZnvA-+FDE|6QU?m zUS5tUikM6$*4NiBMuCco3OYMGv0ANcZf-I?JF@6+olY|~HANzkDDeE{%a`fy z?#AcyasB#rj7DS8wM0>*qM`y-RnJ#}JS0iNX0z!^Y;A3!sw!{az9kxsA_xMtwY7A0 zb>a1T>FDSvFh1|xJOn{Nk|ZQa+E3s-lu#6fR4N64&1R#mtqnmCP!xsn@o@|W16^HR zJbd_&*49=G2E#sscmJQwW=SLxWV6|eQ9#o)ve_&EvMl5AcqlI~M^#lMNy20@(cj-s zdwYA)u-O}yzkmPc)2B~FqtSy2oRty>8DY2EX>V_*v9S?R6uEZo+CI-8gjg)b?CdPx zzkk0N1&YCFG~#l(aJgJZekPSl5ekJE8yjPCa+3M^`NIjERteaz#z_$hg?Rq_Im5%l z1cSlCWAtxEGMQv$Wd*Mj`^$ifZcBA)~#D)G8uBY9MjX& ztgf!Iv$Lc36K6)?Pp6ckC@0DV`MUqcjT^|ajKN^w<;$0>t*z;u-I*&;ESv;EIIuMS z6Y^DOeSJOk_4OEyMr2uLYHEr|Btj;WxtI`=Wtp2E0qsHTLmX?-?$K$|%#n<%oG|_1EM26?%T@VD4$z(x4 zEm$lTt*NPr`}gnD(a}L^X{lbT=bP-Ko*?;gfk1%Aj~^2V1c3i~+{VU6Y&P483FQA2 zMIjc85s5_h*Ftu?oz~V?WchTFRZ&sF(9n?ndvkM>xw*Mh%~=ehC?ct<`Y4r35ex=d zU0ua$wbI<&e5#3m{rbiD_&CeU%V%Wje(1-jq9`O12@;6}u~-aMRmo&Bw6?Z#<;oRA zQ9SZq$j4>=oGy0nED6A#M3zV-c>Ve{nM{Vk!9nbHJ7%+452?d4?(WI=hT&P)P`-YO(V~(cQYSvBAW|1Xin+nwpwp6VNn`TrT&=F=y3Z z6n)xau~1f4MrmoOo)?Y-P1E!v_`Fe6f#&9B9z1w}*XyOezFs%#I5=wVIPKmjAW&9T zMngjb0|NsL3=GiH(sHcH{vRkH;BvVb92~^w^HEn zJ9qGSJoNST?eqNZ7qz=Ry|S{x!omWIqR`mbNL^jsiR%5cfIKiTfYa&3>2ww~9typi z$z=HO;R8>fK4p7*8?V<(Z*MQPwY3G$pBMHjBKP$4U@#a88jgcJzr4ImAP``9c$krq z5pua4s;VN2B5iGLT)ldgl9CciN=h#51(;k}S*aUa>_b8x*=&|TAi&Vj5Hm9~dZzvO z@gt%rqN*xYRaN>2xsxQo6A@5VwV>nK3r*7qg+hG&`W3(5&#PCjh{a<1{b)4G%*+gu zBw@8$>FVktkw{!zCJu+gn9XJ!4o6V}*=&}%xjCLad&cbStllQ>MmnA5-Me=fjYckA zy2RGj7U^{QBJ4+MYHE5Ei9`@Z5wqEhrfKZ#>=2K~Sy))${rmTfjEpcgHbx{8DVo$Y zO(U615)OyaG>u>|$lTlrvVttjSglr6Rb^vigP%WtGC4WP=;$bK z-n`M9oj*ZQ6xP<(n4g~~8jb3omCh6Lj~_qS+1Vi+4ik^ZF`Lb7Z*LQe#aLWi zL8`(q6ouhSiX~D4g5U-eK`6LTU4;;E4Hk<--GL6pVZpg#`QPMKTB~i+2JZBH2{~6p z1mB6Gh$KnK^SpJW3m_tBt(}n0fGg4q5E0@y=J9y^29#1Lr8Z?0Zq{Hc>EfkBneRzvDs|gflowh{WW~Q-=nogL{Lh-5eb5z75Ib> zheIuVI2=|kQXmop0mZl?yRld-y!WLB{0g7X=T0s22Fl^CRdxoR&nL^}vQ}Ylr0E4|nqrLU ihqV1cZ=?v)6pzT5GSp_BH@26+&BE8xI~lpr@w? zuh)y!Y6U=1l%j1)ecrHa5|kRih>{r1&gR?3TcQ$ zB1}$Bl1`_QWf`~Ijmcy}5QKtlRWt(o5sSrGU0p>{6dVo*cDtQp$Bq@8O8=VxfOtGk zFc?G>MSMOVb#-+B1qmoTW@UugY{ubmV6|HH$y_L;gLzj*Ok$hOMq^_m_wL=Judk1@XV2=-3U%Ni0hNfzsZ*yI7#N_px0m|*`Xj%k@yW)c zq7ks$?KCwtarf?BdV70mX=%y&?mYNer}f$r{ZZr{Fr$n$?AuP6$kP>6+v1r$Z0si}z*Cr%(ql3uYCMJZfBF%j{2 zJox>7{C+=PuQw-ofMhbs+}s>bo;)FuNYK;M!}aUe^|eAnMIumJTT5qWCmkIf8TYf1 zUs+ip5C||lJk0p`IEtc>NF*>A479hmbMD+ZeN4#$a#acVlR|E{J1_FdWRh>+zA-d3 z#LJg2_4ht~`h?MF1fZs-29L*69s&74Q50lZ&bartiMqD7Mj#MiWMqUFFJ2IdMD%CT zXq1_m8U6pIOPBC^y-3<@E~XbhiqL)!N25{J*Vm66pGu_&1Of~V4ILt{As&zO;ll?+ zQKYJ>iZf@my=kpPd$NBN&2gzg-;81U_5f?=fm&-**M+cpqopg0|=>j5=2wtxjlgY%) z%nTbF8^mHUU5KJ6q*5tDp^z@{Ac{Gi5Fb5y^w{BWu)Msihfwp52JN@Y<>Kben+yyL zaN)uQnwy(3o6Sg)gw<-rY&KI{TZ=5qghC;E zse&M={7EbQG8&Dl$Kz2SK76Q7PEM+cL_*DmbULjL4i2hqZEgB^K@jxopzTsG$>;Oo zbUI0;QpmE*yLa!{+1beuSzTRCcXu~^eSNgHwqi1wvN}W*Me6G6^h2wI$YjtN%r`g)tA{L8PtQwVkuw^tFX>Dyq6h&+{8?RoyVt#&JZ%wj^C|4xP r(zLr=E_^;8r%#{8X0w&UWZw7(pQ$nDq_{7y00000NkvXXu0mjfJbXW) literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/media_pause.png b/Telegram/Resources/icons/media_pause.png new file mode 100644 index 0000000000000000000000000000000000000000..2ae4e1ebb69de0bc1e2f3a32d31a558481f4c75c GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^fA%3x2-L*j>FVdQ&MBb@0Gl=&H~;_u literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/media_pause@2x.png b/Telegram/Resources/icons/media_pause@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ffba955adad7822958388d65b21a4c71af6e3481 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^NpqRoT>4clgRp4Rw@7%L;Ezn#BPgg&e IbxsLQ0C({#KL7v# literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/media_play.png b/Telegram/Resources/icons/media_play.png new file mode 100644 index 0000000000000000000000000000000000000000..018ef78e96366e19500683c384501efd5bcd8c4c GIT binary patch literal 281 zcmV+!0p|XRP)*6vpwl2Ac;kh{XdKtzs6NcnPz?6KEEjN3aayB_@bx&}26ZBA>;9?QdZB53l}U zn3+dH2qZ}YBI3_=T>yY#7!U*j55rf-aiFeiIF7@|bnChz&vP@FZk}gEQDg=K0HqYV zu7l@!d`!3RJIbLHnX;c f5QyWLhrIIuPCk#_;6oj+00000NkvXXu0mjf12S~i literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/media_play@2x.png b/Telegram/Resources/icons/media_play@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..44805a939c74bdca7447dc57fa813ffe0108a18e GIT binary patch literal 375 zcmV--0f_#IP)sl|k+<1LpM@T6Yl6cc`}SGlF`(OQ4!?+pMH5$n3D zX`0k~ZjnF9eSP;BV{T7LZW(|u{FKiH-2+QEl0pbvLp;WazVEqe4_#4o&T&=i5CYd{ zg!21ljN$t5I_FST)$4`MiiHrkmMWBMsE0a|>TC(otvV@}!*uKPEDPYRbGVKqIv;7B VNc6w!cEkVx002ovPDHLkV1gn^tc3so literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/media_volume.png b/Telegram/Resources/icons/media_volume.png new file mode 100644 index 0000000000000000000000000000000000000000..1b64a994d797e160c2950d833111543ee2f339e6 GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^IzY_B!3HEHHR8>IRJ5myV~9uR)vFu%4k&QAUi5xk zFT8IKU)h%4W2-(av!1s>p1Lv9>u-aV%bq3tad5Stf@W0`r!TpVGYv{ yr5$ijuze7)Vf(k`P6<}Olx|*Xbhhc6cz4OByC0`zg}wn=!{F)a=d#Wzp$PyTx;icZ literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/media_volume@2x.png b/Telegram/Resources/icons/media_volume@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..91c9d60376de8995bed56a1dd9c73195ba9de41d GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^5kM@#!3HGj&RT&uGdx`!LoyoQ-gM+Upupi0n6c;o z)VG^_t$NpXDV@8&Nm2hzfZ)kPXS_CxcSM}KepYD5M(bs(?4Ggw3*;1beK0-CAdqER z-Ha7)8*~i=7dE;lFFM3feZWPR^NpzRQ@ILNpDEf8t{MhjZct8I)W-0>sq+=z9%Hpt zoHJ%TwPP0EtjFPVrcO2KR@s?2g(?=az5~YuZ&--#d+Te>xX{kR&&#{P8t6s_Pgg&e IbxsLQ02V<|761SM literal 0 HcmV?d00001 diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index f26bbb6e3..62ba8e2d4 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -533,6 +533,12 @@ namespace Sandbox { } } + void removeEventFilter(QObject *filter) { + if (Application *a = application()) { + a->removeEventFilter(filter); + } + } + void execExternal(const QString &cmd) { DEBUG_LOG(("Application Info: executing external command '%1'").arg(cmd)); if (cmd == "show") { diff --git a/Telegram/SourceFiles/application.h b/Telegram/SourceFiles/application.h index 4b6023131..78983d070 100644 --- a/Telegram/SourceFiles/application.h +++ b/Telegram/SourceFiles/application.h @@ -114,6 +114,7 @@ namespace Sandbox { bool isSavingSession(); void installEventFilter(QObject *filter); + void removeEventFilter(QObject *filter); void execExternal(const QString &cmd); diff --git a/Telegram/SourceFiles/codegen/style/generator.cpp b/Telegram/SourceFiles/codegen/style/generator.cpp index 84aa5e57e..286cd7cfc 100644 --- a/Telegram/SourceFiles/codegen/style/generator.cpp +++ b/Telegram/SourceFiles/codegen/style/generator.cpp @@ -327,8 +327,11 @@ bool Generator::writeHeaderStyleNamespace() { header_->stream() << "void init_" << baseName_ << "();\n\n"; header_->popNamespace(); } + bool wroteForwardDeclarations = writeStructsForwardDeclarations(); if (module_.hasStructs()) { - header_->newline(); + if (!wroteForwardDeclarations) { + header_->newline(); + } if (!writeStructsDefinitions()) { return false; } @@ -338,6 +341,32 @@ bool Generator::writeHeaderStyleNamespace() { return true; } +bool Generator::writeStructsForwardDeclarations() { + bool hasNoExternalStructs = module_.enumVariables([this](const Variable &value) -> bool { + if (value.value.type().tag == structure::TypeTag::Struct) { + if (!module_.findStructInModule(value.value.type().name, module_)) { + return false; + } + } + return true; + }); + if (hasNoExternalStructs) { + return false; + } + + header_->newline(); + bool result = module_.enumVariables([this](const Variable &value) -> bool { + if (value.value.type().tag == structure::TypeTag::Struct) { + if (!module_.findStructInModule(value.value.type().name, module_)) { + header_->stream() << "struct " << value.value.type().name.back() << ";\n"; + } + } + return true; + }); + header_->newline(); + return result; +} + bool Generator::writeStructsDefinitions() { if (!module_.hasStructs()) { return true; diff --git a/Telegram/SourceFiles/codegen/style/generator.h b/Telegram/SourceFiles/codegen/style/generator.h index 0c5bf2151..4d7319dae 100644 --- a/Telegram/SourceFiles/codegen/style/generator.h +++ b/Telegram/SourceFiles/codegen/style/generator.h @@ -47,6 +47,7 @@ private: QString valueAssignmentCode(structure::Value value) const; bool writeHeaderStyleNamespace(); + bool writeStructsForwardDeclarations(); bool writeStructsDefinitions(); bool writeRefsDeclarations(); diff --git a/Telegram/SourceFiles/codegen/style/module.h b/Telegram/SourceFiles/codegen/style/module.h index f8a043286..3c2df33ca 100644 --- a/Telegram/SourceFiles/codegen/style/module.h +++ b/Telegram/SourceFiles/codegen/style/module.h @@ -94,6 +94,9 @@ public: return !fullpath_.isEmpty(); } + const Struct *findStructInModule(const FullName &name, const Module &module) const; + const Variable *findVariableInModule(const FullName &name, const Module &module) const; + private: QString fullpath_; std::vector> included_; @@ -102,9 +105,6 @@ private: QMap structsByName_; QMap variablesByName_; - const Struct *findStructInModule(const FullName &name, const Module &module) const; - const Variable *findVariableInModule(const FullName &name, const Module &module) const; - }; } // namespace structure diff --git a/Telegram/SourceFiles/media/view/media_clip_controller.cpp b/Telegram/SourceFiles/media/view/media_clip_controller.cpp new file mode 100644 index 000000000..f784e7e62 --- /dev/null +++ b/Telegram/SourceFiles/media/view/media_clip_controller.cpp @@ -0,0 +1,116 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "media/view/media_clip_controller.h" + +#include "media/view/media_clip_playback.h" +#include "media/view/media_clip_volume_controller.h" +#include "styles/style_mediaview.h" +#include "ui/widgets/label_simple.h" +#include "ui/effects/fade_animation.h" +#include "ui/buttons/icon_button.h" +#include "media/media_audio.h" + +namespace Media { +namespace Clip { + +Controller::Controller(QWidget *parent) : TWidget(parent) +, _playPauseResume(this, st::mediaviewPlayButton) +, _playback(this) +, _volumeController(this) +, _fullScreenToggle(this, st::mediaviewFullScreenButton) +, _playedAlready(this, st::mediaviewPlayProgressLabel) +, _toPlayLeft(this, st::mediaviewPlayProgressLabel) +, _fadeAnimation(std_::make_unique(this)) { + _fadeAnimation->show(); + connect(_playPauseResume, SIGNAL(clicked()), this, SIGNAL(playPressed())); + connect(_fullScreenToggle, SIGNAL(clicked()), this, SIGNAL(toFullScreenPressed())); + connect(_playback, SIGNAL(seekProgress(int64)), this, SLOT(onSeekProgress(int64))); + connect(_playback, SIGNAL(seekFinished(int64)), this, SLOT(onSeekFinished(int64))); + connect(_volumeController, SIGNAL(volumeChanged(float64)), this, SIGNAL(volumeChanged(float64))); +} + +void Controller::onSeekProgress(int64 position) { + _seekPosition = position; + emit seekProgress(position); +} + +void Controller::onSeekFinished(int64 position) { + _seekPosition = -1; + emit seekFinished(position); +} + +void Controller::showAnimated() { + _fadeAnimation->fadeIn(st::mvShowDuration); +} + +void Controller::hideAnimated() { + _fadeAnimation->fadeOut(st::mvHideDuration); +} + +void Controller::updatePlayback(const AudioPlaybackState &playbackState) { + bool showPause = (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming); + if (showPause != _showPause) { + disconnect(_playPauseResume, SIGNAL(clicked()), this, _showPause ? SIGNAL(pausePressed()) : SIGNAL(playPressed())); + _showPause = showPause; + connect(_playPauseResume, SIGNAL(clicked()), this, _showPause ? SIGNAL(pausePressed()) : SIGNAL(playPressed())); + + _playPauseResume->setIcon(_showPause ? &st::mediaviewPauseIcon : nullptr); + } + + _playback->updateState(playbackState); +} + +void Controller::setInFullScreen(bool inFullScreen) { + _fullScreenToggle->setIcon(inFullScreen ? &st::mediaviewFullScreenOutIcon : nullptr); + disconnect(_fullScreenToggle, SIGNAL(clicked()), this, SIGNAL(toFullScreenPressed())); + disconnect(_fullScreenToggle, SIGNAL(clicked()), this, SIGNAL(fromFullScreenPressed())); + + auto handler = inFullScreen ? SIGNAL(fromFullScreenPressed()) : SIGNAL(toFullScreenPressed()); + connect(_fullScreenToggle, SIGNAL(clicked()), this, handler); +} + +void Controller::resizeEvent(QResizeEvent *e) { + int playTop = (height() - _playPauseResume->height()) / 2; + _playPauseResume->moveToLeft(playTop, playTop); + _playedAlready->moveToLeft(playTop + _playPauseResume->width() + playTop, 0); + + int fullScreenTop = (height() - _fullScreenToggle->height()) / 2; + _fullScreenToggle->moveToRight(fullScreenTop, fullScreenTop); + _toPlayLeft->moveToRight(fullScreenTop + _fullScreenToggle->width() + fullScreenTop, 0); + + _volumeController->moveToRight(fullScreenTop + _fullScreenToggle->width() + fullScreenTop, (height() - _volumeController->height()) / 2); + _playback->resize(width() - playTop - _playPauseResume->width() - playTop - fullScreenTop - _volumeController->width() - fullScreenTop - _fullScreenToggle->width() - fullScreenTop, _volumeController->height()); + _playback->moveToLeft(playTop + _playPauseResume->width() + playTop, (height() - _playback->height()) / 2); +} + +void Controller::paintEvent(QPaintEvent *e) { + Painter p(this); + + if (_fadeAnimation->paint(p)) { + return; + } + + App::roundRect(p, rect(), st::medviewSaveMsg, MediaviewSaveCorners); +} + +} // namespace Clip +} // namespace Media diff --git a/Telegram/SourceFiles/media/view/media_clip_controller.h b/Telegram/SourceFiles/media/view/media_clip_controller.h new file mode 100644 index 000000000..13bf40dd8 --- /dev/null +++ b/Telegram/SourceFiles/media/view/media_clip_controller.h @@ -0,0 +1,82 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +namespace Ui { +class LabelSimple; +class FadeAnimation; +class IconButton; +} // namespace Ui + +struct AudioPlaybackState; + +namespace Media { +namespace Clip { + +class Playback; +class VolumeController; + +class Controller : public TWidget { + Q_OBJECT + +public: + Controller(QWidget *parent); + + void showAnimated(); + void hideAnimated(); + + void updatePlayback(const AudioPlaybackState &playbackState); + void setInFullScreen(bool inFullScreen); + +signals: + void playPressed(); + void pausePressed(); + void seekProgress(int64 position); + void seekFinished(int64 position); + void volumeChanged(float64 volume); + void toFullScreenPressed(); + void fromFullScreenPressed(); + +private slots: + void onSeekProgress(int64 position); + void onSeekFinished(int64 position); + +protected: + void resizeEvent(QResizeEvent *e) override; + void paintEvent(QPaintEvent *e) override; + +private: + bool _showPause = false; + int64 _seekPosition = -1; + + ChildWidget _playPauseResume; + ChildWidget _playback; + ChildWidget _volumeController; + ChildWidget _fullScreenToggle; + ChildWidget _playedAlready; + ChildWidget _toPlayLeft; + + std_::unique_ptr _fadeAnimation; + +}; + +} // namespace Clip +} // namespace Media diff --git a/Telegram/SourceFiles/media/view/media_clip_playback.cpp b/Telegram/SourceFiles/media/view/media_clip_playback.cpp new file mode 100644 index 000000000..a80b9b554 --- /dev/null +++ b/Telegram/SourceFiles/media/view/media_clip_playback.cpp @@ -0,0 +1,131 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "media/view/media_clip_playback.h" + +#include "styles/style_mediaview.h" +#include "media/media_audio.h" + +namespace Media { +namespace Clip { + +Playback::Playback(QWidget *parent) : TWidget(parent) +, _a_progress(animation(this, &Playback::step_progress)) { + setCursor(style::cur_pointer); +} + +void Playback::updateState(const AudioPlaybackState &playbackState) { + qint64 position = 0, duration = playbackState.duration; + + if (!(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) { + position = playbackState.position; + } else if (playbackState.state == AudioPlayerStoppedAtEnd) { + position = playbackState.duration; + } else { + position = 0; + } + + float64 progress = 0.; + if (duration) { + progress = duration ? snap(float64(position) / duration, 0., 1.) : 0.; + } + if (duration != _duration || position != _position) { + if (duration && _duration) { + a_progress.start(progress); + _a_progress.start(); + } else { + a_progress = anim::fvalue(progress, progress); + _a_progress.stop(); + } + _position = position; + _duration = duration; + } +} + +void Playback::step_progress(float64 ms, bool timer) { + float64 dt = ms / (2 * AudioVoiceMsgUpdateView); + if (_duration && dt >= 1) { + _a_progress.stop(); + a_progress.finish(); + } else { + a_progress.update(qMin(dt, 1.), anim::linear); + } + if (timer) update(); +} + +void Playback::paintEvent(QPaintEvent *e) { + Painter p(this); + + int radius = st::mediaviewPlaybackWidth / 2; + p.setPen(Qt::NoPen); + p.setRenderHint(QPainter::HighQualityAntialiasing); + + auto over = _a_over.current(getms(), _over ? 1. : 0.); + int skip = (st::mediaviewSeekSize.width() / 2); + int length = (width() - st::mediaviewSeekSize.width()); + float64 prg = _mouseDown ? _downProgress : a_progress.current(); + int32 from = skip, mid = qRound(from + prg * length), end = from + length; + if (mid > from) { + p.setClipRect(0, 0, mid, height()); + p.setOpacity(over * st::mediaviewActiveOpacity + (1. - over) * st::mediaviewInactiveOpacity); + p.setBrush(st::mediaviewPlaybackActive); + p.drawRoundedRect(0, (height() - st::mediaviewPlaybackWidth) / 2, mid + radius, st::mediaviewPlaybackWidth, radius, radius); + } + if (end > mid) { + p.setClipRect(mid, 0, width() - mid, height()); + p.setOpacity(1.); + p.setBrush(st::mediaviewPlaybackInactive); + p.drawRoundedRect(mid - radius, (height() - st::mediaviewPlaybackWidth) / 2, width() - (mid - radius), st::mediaviewPlaybackWidth, radius, radius); + } + int x = mid - skip; + p.setClipRect(rect()); + p.setOpacity(over * st::mediaviewActiveOpacity + (1. - over) * st::mediaviewInactiveOpacity); + p.setBrush(st::mediaviewPlaybackActive); + p.drawRoundedRect(x, (height() - st::mediaviewSeekSize.height()) / 2, st::mediaviewSeekSize.width(), st::mediaviewSeekSize.height(), st::mediaviewSeekSize.width() / 2, st::mediaviewSeekSize.width() / 2); +} + +void Playback::mouseMoveEvent(QMouseEvent *e) { +} + +void Playback::mousePressEvent(QMouseEvent *e) { +} + +void Playback::mouseReleaseEvent(QMouseEvent *e) { +} + +void Playback::enterEvent(QEvent *e) { + setOver(true); +} + +void Playback::leaveEvent(QEvent *e) { + setOver(false); +} + +void Playback::setOver(bool over) { + if (_over == over) return; + + _over = over; + auto from = _over ? 0. : 1., to = _over ? 1. : 0.; + START_ANIMATION(_a_over, func(this, &Playback::updateCallback), from, to, st::mediaviewOverDuration, anim::linear); +} + +} // namespace Clip +} // namespace Media diff --git a/Telegram/SourceFiles/media/view/media_clip_playback.h b/Telegram/SourceFiles/media/view/media_clip_playback.h new file mode 100644 index 000000000..d362d770e --- /dev/null +++ b/Telegram/SourceFiles/media/view/media_clip_playback.h @@ -0,0 +1,69 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +struct AudioPlaybackState; + +namespace Media { +namespace Clip { + +class Playback : public TWidget { + Q_OBJECT + +public: + Playback(QWidget *parent); + + void updateState(const AudioPlaybackState &playbackState); + +signals: + void seekProgress(int64 position); + void seekFinished(int64 position); + +protected: + void paintEvent(QPaintEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void enterEvent(QEvent *e) override; + void leaveEvent(QEvent *e) override; + +private: + void step_progress(float64 ms, bool timer); + void updateCallback() { + update(); + } + void setOver(bool over); + + bool _over = false; + FloatAnimation _a_over; + + int64 _position = 0; + int64 _duration = 0; + anim::fvalue a_progress = { 0., 0. }; + Animation _a_progress; + + bool _mouseDown = false; + float64 _downProgress = 0.; + +}; + +} // namespace Clip +} // namespace Media diff --git a/Telegram/SourceFiles/media/view/media_clip_volume_controller.cpp b/Telegram/SourceFiles/media/view/media_clip_volume_controller.cpp new file mode 100644 index 000000000..57021db79 --- /dev/null +++ b/Telegram/SourceFiles/media/view/media_clip_volume_controller.cpp @@ -0,0 +1,85 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "media/view/media_clip_volume_controller.h" + +#include "styles/style_mediaview.h" + +namespace Media { +namespace Clip { + +VolumeController::VolumeController(QWidget *parent) : TWidget(parent) { + resize(st::mediaviewVolumeSize); + setCursor(style::cur_pointer); +} + +void VolumeController::setVolume(float64 volume) { + _volume = volume; + update(); +} + +void VolumeController::paintEvent(QPaintEvent *e) { + Painter p(this); + + int32 top = (height() - st::mediaviewVolumeIcon.height()) / 2; + int32 left = (width() - st::mediaviewVolumeIcon.width()) / 2; + int32 mid = left + qRound(st::mediaviewVolumeIcon.width() * _volume); + int32 right = left + st::mediaviewVolumeIcon.width(); + + if (mid > left) { + auto over = _a_over.current(getms(), _over ? 1. : 0.); + p.setOpacity(over * st::mediaviewActiveOpacity + (1. - over) * st::mediaviewInactiveOpacity); + p.setClipRect(rtlrect(left, top, mid - left, st::mediaviewVolumeIcon.height(), width())); + st::mediaviewVolumeOnIcon.paint(p, QPoint(left, top), width()); + } + if (right > mid) { + p.setClipRect(rtlrect(mid, top, right - mid, st::mediaviewVolumeIcon.height(), width())); + st::mediaviewVolumeIcon.paint(p, QPoint(left, top), width()); + } +} + +void VolumeController::mouseMoveEvent(QMouseEvent *e) { +} + +void VolumeController::mousePressEvent(QMouseEvent *e) { +} + +void VolumeController::mouseReleaseEvent(QMouseEvent *e) { +} + +void VolumeController::enterEvent(QEvent *e) { + setOver(true); +} + +void VolumeController::leaveEvent(QEvent *e) { + setOver(false); +} + +void VolumeController::setOver(bool over) { + if (_over == over) return; + + _over = over; + auto from = _over ? 0. : 1., to = _over ? 1. : 0.; + START_ANIMATION(_a_over, func(this, &VolumeController::updateCallback), from, to, st::mediaviewOverDuration, anim::linear); +} + +} // namespace Clip +} // namespace Media diff --git a/Telegram/SourceFiles/media/view/media_clip_volume_controller.h b/Telegram/SourceFiles/media/view/media_clip_volume_controller.h new file mode 100644 index 000000000..6d891d321 --- /dev/null +++ b/Telegram/SourceFiles/media/view/media_clip_volume_controller.h @@ -0,0 +1,59 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +namespace Media { +namespace Clip { + +class VolumeController : public TWidget { + Q_OBJECT + +public: + VolumeController(QWidget *parent); + + void setVolume(float64 volume); + +signals: + void volumeChanged(float64 volume); + +protected: + void paintEvent(QPaintEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void enterEvent(QEvent *e) override; + void leaveEvent(QEvent *e) override; + +private: + void updateCallback() { + update(); + } + void setOver(bool over); + + float64 _volume = 0.; + + bool _over = false; + FloatAnimation _a_over; + +}; + +} // namespace Clip +} // namespace Media diff --git a/Telegram/SourceFiles/media/view/mediaview.style b/Telegram/SourceFiles/media/view/mediaview.style new file mode 100644 index 000000000..7540b269b --- /dev/null +++ b/Telegram/SourceFiles/media/view/mediaview.style @@ -0,0 +1,74 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ + +using "basic.style"; +using "ui/widgets/widgets.style"; + +mediaviewActiveOpacity: 1.; +mediaviewInactiveOpacity: 0.78; +mediaviewOverDuration: 150; + +mediaviewControllerSize: size(600px, 50px); +mediaviewPlayProgressLabel: LabelSimple(defaultLabelSimple) { + textFg: #ffffffc7; +} +mediaviewPlayButton: IconButton { + width: 25px; + height: 24px; + + opacity: mediaviewInactiveOpacity; + overOpacity: mediaviewActiveOpacity; + + icon: icon { + { "media_play", #ffffff, point(0px, 0px) }, + }; + iconPosition: point(3px, 1px); + downIconPosition: point(3px, 1px); + + duration: mediaviewOverDuration; +} +mediaviewPauseIcon: icon { + { "media_pause", #ffffff, point(1px, 1px) } +}; + +mediaviewFullScreenButton: IconButton(mediaviewPlayButton) { + icon: icon { + { "media_fullscreen_to", #ffffff, point(0px, 0px) }, + }; + iconPosition: point(0px, 0px); + downIconPosition: point(0px, 0px); +} +mediaviewFullScreenOutIcon: icon { + { "media_fullscreen_from", #ffffff, point(0px, 0px) }, +}; + +mediaviewPlaybackActive: #ffffff; +mediaviewPlaybackInactive: #474747; +mediaviewPlaybackWidth: 3px; +mediaviewSeekSize: size(2px, 13px); + +mediaviewVolumeSize: size(44px, 12px); +mediaviewVolumeIcon: icon { + { "media_volume", mediaviewPlaybackInactive, point(0px, 0px) }, +}; +mediaviewVolumeOnIcon: icon { + { "media_volume", mediaviewPlaybackActive, point(0px, 0px) }, +}; diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 834da50ce..4134d7503 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -27,6 +27,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "application.h" #include "ui/filedialog.h" #include "media/media_clip_reader.h" +#include "media/view/media_clip_controller.h" +#include "styles/style_mediaview.h" namespace { @@ -228,8 +230,9 @@ bool MediaView::gifShown() const { } void MediaView::stopGif() { - delete _gif; _gif = nullptr; + _clipController.destroy(); + Sandbox::removeEventFilter(this); } void MediaView::documentUpdated(DocumentData *doc) { @@ -364,6 +367,7 @@ void MediaView::updateControls() { } else { _leftNavVisible = _rightNavVisible = false; } + if (!_caption.isEmpty()) { int32 skipw = qMax(_dateNav.left() + _dateNav.width(), _headerNav.left() + _headerNav.width()); int32 maxw = qMin(qMax(width() - 2 * skipw - st::mvCaptionPadding.left() - st::mvCaptionPadding.right() - 2 * st::mvCaptionMargin.width(), int(st::msgMinWidth)), _caption.maxWidth()); @@ -372,6 +376,9 @@ void MediaView::updateControls() { } else { _captionRect = QRect(); } + if (_clipController) { + setClipControllerGeometry(); + } updateOver(mapFromGlobal(QCursor::pos())); update(); } @@ -519,7 +526,6 @@ void MediaView::clearData() { } MediaView::~MediaView() { - deleteAndMark(_gif); deleteAndMark(_menu); } @@ -551,6 +557,9 @@ void MediaView::activateControls() { a_cOpacity.start(1); if (!_a_state.animating()) _a_state.start(); } + if (_clipController) { + _clipController->showAnimated(); + } } void MediaView::onHideControls(bool force) { @@ -560,6 +569,9 @@ void MediaView::onHideControls(bool force) { _controlsAnimStarted = getms(); a_cOpacity.start(0); if (!_a_state.animating()) _a_state.start(); + if (_clipController) { + _clipController->hideAnimated(); + } } void MediaView::onDropdownHiding() { @@ -1072,24 +1084,11 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty } else { _doc->automaticLoad(item); - const FileLocation &location(_doc->location(true)); - if (!_doc->data().isEmpty() && (_doc->isAnimation() || _doc->isVideo())) { - if (!_gif) { - if (_doc->dimensions.width() && _doc->dimensions.height()) { - _current = _doc->thumb->pixNoCache(_doc->dimensions.width(), _doc->dimensions.height(), ImagePixSmooth | ImagePixBlurred, _doc->dimensions.width(), _doc->dimensions.height()); - } - _gif = new Media::Clip::Reader(location, _doc->data(), func(this, &MediaView::clipCallback)); - } - } else if (location.accessEnable()) { - if (_doc->isAnimation() || _doc->isVideo()) { - if (!_gif) { - if (_doc->dimensions.width() && _doc->dimensions.height()) { - _current = _doc->thumb->pixNoCache(_doc->dimensions.width(), _doc->dimensions.height(), ImagePixSmooth | ImagePixBlurred, _doc->dimensions.width(), _doc->dimensions.height()); - } - auto mode = _doc->isVideo() ? Media::Clip::Reader::Mode::Video : Media::Clip::Reader::Mode::Gif; - _gif = new Media::Clip::Reader(location, _doc->data(), func(this, &MediaView::clipCallback), mode); - } - } else { + if (_doc->isAnimation() || _doc->isVideo()) { + initAnimation(); + } else { + const FileLocation &location(_doc->location(true)); + if (location.accessEnable()) { if (QImageReader(location.name()).canRead()) { _current = QPixmap::fromImage(App::readImage(location.name(), 0, false), Qt::ColorOnly); } @@ -1202,6 +1201,94 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty } } +void MediaView::initAnimation() { + t_assert(_doc != nullptr); + t_assert(_doc->isAnimation() || _doc->isVideo()); + + auto &location = _doc->location(true); + if (!_doc->data().isEmpty()) { + createClipReader(); + } else if (location.accessEnable()) { + createClipReader(); + location.accessDisable(); + } +} + +void MediaView::createClipReader() { + if (_gif) return; + + t_assert(_doc != nullptr); + t_assert(_doc->isAnimation() || _doc->isVideo()); + + if (_doc->dimensions.width() && _doc->dimensions.height()) { + _current = _doc->thumb->pixNoCache(_doc->dimensions.width(), _doc->dimensions.height(), ImagePixSmooth | ImagePixBlurred, _doc->dimensions.width(), _doc->dimensions.height()); + } + auto mode = _doc->isVideo() ? Media::Clip::Reader::Mode::Video : Media::Clip::Reader::Mode::Gif; + _gif = std_::make_unique(_doc->location(), _doc->data(), func(this, &MediaView::clipCallback), mode); + + createClipController(); +} + +void MediaView::createClipController() { + if (!_doc->isVideo()) return; + + _clipController.destroy(); + _clipController = new Media::Clip::Controller(this); + setClipControllerGeometry(); + _clipController->show(); + + connect(_clipController, SIGNAL(playPressed()), this, SLOT(onVideoPlay())); + connect(_clipController, SIGNAL(pausePressed()), this, SLOT(onVideoPause())); + connect(_clipController, SIGNAL(seekProgress(int64)), this, SLOT(onVideoSeekProgress(int64))); + connect(_clipController, SIGNAL(seekFinished(int64)), this, SLOT(onVideoSeekFinished(int64))); + connect(_clipController, SIGNAL(volumeChanged(float64)), this, SLOT(onVideoVolumeChanged(float64))); + connect(_clipController, SIGNAL(toFullScreenPressed()), this, SLOT(onVideoToFullScreen())); + connect(_clipController, SIGNAL(fromFullScreenPressed()), this, SLOT(onVideoFromFullScreen())); + + Sandbox::removeEventFilter(this); + Sandbox::installEventFilter(this); +} + +void MediaView::setClipControllerGeometry() { + t_assert(_clipController != nullptr); + + int controllerBottom = _captionRect.isEmpty() ? height() : _captionRect.y(); + _clipController->setGeometry( + (width() - _clipController->width()) / 2, + controllerBottom - _clipController->height() - st::mvCaptionPadding.bottom() - st::mvCaptionMargin.height(), + st::mediaviewControllerSize.width(), + st::mediaviewControllerSize.height()); + myEnsureResized(_clipController); +} + +void MediaView::onVideoPlay() { + +} + +void MediaView::onVideoPause() { + +} + +void MediaView::onVideoSeekProgress(int64 position) { + +} + +void MediaView::onVideoSeekFinished(int64 position) { + +} + +void MediaView::onVideoVolumeChanged(float64 volume) { + +} + +void MediaView::onVideoToFullScreen() { + +} + +void MediaView::onVideoFromFullScreen() { + +} + void MediaView::paintEvent(QPaintEvent *e) { QRect r(e->rect()); QRegion region(e->region()); @@ -1833,9 +1920,6 @@ void MediaView::snapXY() { } void MediaView::mouseMoveEvent(QMouseEvent *e) { - bool moved = (e->pos() != _lastMouseMovePos); - _lastMouseMovePos = e->pos(); - updateOver(e->pos()); if (_lastAction.x() >= 0 && (e->pos() - _lastAction).manhattanLength() >= st::mvDeltaFromLastAction) { _lastAction = QPoint(-st::mvDeltaFromLastAction, -st::mvDeltaFromLastAction); @@ -1858,7 +1942,6 @@ void MediaView::mouseMoveEvent(QMouseEvent *e) { update(); } } - if (moved) activateControls(); } void MediaView::updateOverRect(OverState state) { @@ -2105,6 +2188,18 @@ bool MediaView::event(QEvent *e) { return QWidget::event(e); } +bool MediaView::eventFilter(QObject *obj, QEvent *e) { + if (e->type() == QEvent::MouseMove && obj->isWidgetType()) { + if (isAncestorOf(static_cast(obj))) { + auto mousePosition = mapFromGlobal(static_cast(e)->globalPos()); + bool moved = (mousePosition != _lastMouseMovePos); + _lastMouseMovePos = mousePosition; + if (moved) activateControls(); + } + } + return TWidget::eventFilter(obj, e); +} + void MediaView::hide() { _controlsHideTimer.stop(); _controlsState = ControlsShown; diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index 34c94617d..03ff51eb7 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -22,23 +22,18 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "dropdown.h" +namespace Media { +namespace Clip { +class Controller; +} // namespace Clip +} // namespace Media + class MediaView : public TWidget, public RPCSender, public ClickHandlerHost { Q_OBJECT public: MediaView(); - void paintEvent(QPaintEvent *e) override; - - void keyPressEvent(QKeyEvent *e) override; - void mousePressEvent(QMouseEvent *e) override; - void mouseMoveEvent(QMouseEvent *e) override; - void mouseReleaseEvent(QMouseEvent *e) override; - void contextMenuEvent(QContextMenuEvent *e) override; - void touchEvent(QTouchEvent *e); - - bool event(QEvent *e) override; - void hide(); void updateOver(QPoint mpos); @@ -106,12 +101,40 @@ public slots: void updateImage(); +protected: + void paintEvent(QPaintEvent *e) override; + + void keyPressEvent(QKeyEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void contextMenuEvent(QContextMenuEvent *e) override; + void touchEvent(QTouchEvent *e); + + bool event(QEvent *e) override; + bool eventFilter(QObject *obj, QEvent *e) override; + +private slots: + void onVideoPlay(); + void onVideoPause(); + void onVideoSeekProgress(int64 position); + void onVideoSeekFinished(int64 position); + void onVideoVolumeChanged(float64 volume); + void onVideoToFullScreen(); + void onVideoFromFullScreen(); + private: void displayPhoto(PhotoData *photo, HistoryItem *item); void displayDocument(DocumentData *doc, HistoryItem *item); void findCurrent(); void loadBack(); + void createClipController(); + void setClipControllerGeometry(); + + void initAnimation(); + void createClipReader(); + // Radial animation interface. float64 radialProgress() const; bool radialLoading() const; @@ -154,6 +177,8 @@ private: QString _dateText; QString _headerText; + ChildWidget _clipController = { nullptr }; + Text _caption; QRect _captionRect; @@ -168,7 +193,7 @@ private: bool _pressed = false; int32 _dragging = 0; QPixmap _current; - Media::Clip::Reader *_gif = nullptr; + std_::unique_ptr _gif; int32 _full = -1; // -1 - thumb, 0 - medium, 1 - full bool fileShown() const; diff --git a/Telegram/SourceFiles/ui/animation.h b/Telegram/SourceFiles/ui/animation.h index 3482ef0e9..8fc5201cf 100644 --- a/Telegram/SourceFiles/ui/animation.h +++ b/Telegram/SourceFiles/ui/animation.h @@ -486,7 +486,6 @@ using FloatAnimation = SimpleAnimation; using IntAnimation = SimpleAnimation; using ColorAnimation = SimpleAnimation; - // Macro allows us to lazily create updateCallback. #define ENSURE_ANIMATION(animation, updateCallback, from) \ if ((animation).isNull()) { \ diff --git a/Telegram/SourceFiles/ui/buttons/icon_button.cpp b/Telegram/SourceFiles/ui/buttons/icon_button.cpp new file mode 100644 index 000000000..43498c7cc --- /dev/null +++ b/Telegram/SourceFiles/ui/buttons/icon_button.cpp @@ -0,0 +1,56 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "ui/buttons/icon_button.h" + +namespace Ui { + +IconButton::IconButton(QWidget *parent, const style::IconButton &st) : Button(parent) +, _st(st) { + resize(_st.width, _st.height); + setCursor(style::cur_pointer); +} + +void IconButton::setIcon(const style::icon *icon) { + _iconOverride = icon; + update(); +} + +void IconButton::paintEvent(QPaintEvent *e) { + Painter p(this); + + auto over = _a_over.current(getms(), (_state & StateOver) ? 1. : 0.); + p.setOpacity(over * _st.overOpacity + (1. - over) * _st.opacity); + + auto position = (_state & StateDown) ? _st.downIconPosition : _st.iconPosition; + (_iconOverride ? _iconOverride : &_st.icon)->paint(p, position, width()); +} + +void IconButton::onStateChanged(int oldState, ButtonStateChangeSource source) { + auto over = (_state & StateOver); + if (over != (oldState & StateOver)) { + auto from = over ? 0. : 1.; + auto to = over ? 1. : 0.; + START_ANIMATION(_a_over, func(this, &IconButton::updateCallback), from, to, _st.duration, anim::linear); + } +} + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/buttons/icon_button.h b/Telegram/SourceFiles/ui/buttons/icon_button.h new file mode 100644 index 000000000..758c59567 --- /dev/null +++ b/Telegram/SourceFiles/ui/buttons/icon_button.h @@ -0,0 +1,51 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "ui/button.h" + +namespace Ui { + +class IconButton : public Button { +public: + IconButton(QWidget *parent, const style::IconButton &st); + + // Pass nullptr to restore the default icon. + void setIcon(const style::icon *icon); + +protected: + void paintEvent(QPaintEvent *e) override; + + void onStateChanged(int oldState, ButtonStateChangeSource source) override; + +private: + void updateCallback() { + update(); + } + + const style::IconButton &_st; + const style::icon *_iconOverride = nullptr; + + FloatAnimation _a_over; + +}; + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/effects/fade_animation.cpp b/Telegram/SourceFiles/ui/effects/fade_animation.cpp new file mode 100644 index 000000000..29da4c50d --- /dev/null +++ b/Telegram/SourceFiles/ui/effects/fade_animation.cpp @@ -0,0 +1,99 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "ui/effects/fade_animation.h" + +namespace Ui { + +FadeAnimation::FadeAnimation(TWidget *widget) : _widget(widget) { +} + +bool FadeAnimation::paint(Painter &p) { + if (_cache.isNull()) return false; + + bool animating = _animation.animating(getms()); + + p.setOpacity(_animation.current(_visible ? 1. : 0.)); + p.drawPixmap(0, 0, _cache); + if (!animating) { + stopAnimation(); + } + return true; +} + +void FadeAnimation::setFinishedCallback(FinishedCallback &&callback) { + _finishedCallback = std_::move(callback); +} + +void FadeAnimation::show() { + _visible = true; + stopAnimation(); +} + +void FadeAnimation::hide() { + _visible = false; + stopAnimation(); +} + +void FadeAnimation::stopAnimation() { + _animation.finish(); + if (!_cache.isNull()) { + _cache = QPixmap(); + updateCallback(); + _widget->showChildren(); + _finishedCallback.call(); + } + if (_visible == _widget->isHidden()) { + _widget->setVisible(_visible); + } +} + +void FadeAnimation::fadeIn(int duration) { + if (_visible) return; + + _visible = true; + startAnimation(duration); +} + +void FadeAnimation::fadeOut(int duration) { + if (!_visible) return; + + _visible = false; + startAnimation(duration); +} + +void FadeAnimation::startAnimation(int duration) { + if (_cache.isNull()) { + _cache = myGrab(_widget); + _widget->hideChildren(); + } + START_ANIMATION(_animation, func(this, &FadeAnimation::updateCallback), _visible ? 0. : 1., _visible ? 1. : 0., duration, anim::linear); + updateCallback(); + if (_widget->isHidden()) { + _widget->show(); + } +} + +void FadeAnimation::updateCallback() { + _widget->update(); +} + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/effects/fade_animation.h b/Telegram/SourceFiles/ui/effects/fade_animation.h new file mode 100644 index 000000000..cc5793bef --- /dev/null +++ b/Telegram/SourceFiles/ui/effects/fade_animation.h @@ -0,0 +1,57 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +class TWidget; + +namespace Ui { + +class FadeAnimation { +public: + FadeAnimation(TWidget *widget); + + bool paint(Painter &p); + + using FinishedCallback = Function; + void setFinishedCallback(FinishedCallback &&callback); + + void show(); + void hide(); + + void fadeIn(int duration); + void fadeOut(int duration); + +private: + void startAnimation(int duration); + void stopAnimation(); + + void updateCallback(); + + TWidget *_widget; + FloatAnimation _animation; + QPixmap _cache; + bool _visible = false; + + FinishedCallback _finishedCallback; + +}; + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/widgets/label_simple.cpp b/Telegram/SourceFiles/ui/widgets/label_simple.cpp new file mode 100644 index 000000000..13ae9eb4f --- /dev/null +++ b/Telegram/SourceFiles/ui/widgets/label_simple.cpp @@ -0,0 +1,52 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "ui/widgets/label_simple.h" + +namespace Ui { + +LabelSimple::LabelSimple(QWidget *parent, const style::LabelSimple &st, const QString &value) : TWidget(parent) +, _st(st) { + setText(value); +} + +void LabelSimple::setText(const QString &value) { + _fullText = value; + _fullTextWidth = _st.font->width(_fullText); + if (!_st.maxWidth || _fullTextWidth <= _st.maxWidth) { + _text = _fullText; + _textWidth = _fullTextWidth; + } else { + _text = _st.font->elided(_fullText, _st.maxWidth); + _textWidth = _st.font->width(_text); + } + resize(_textWidth, _st.font->height); +} + +void LabelSimple::paintEvent(QPaintEvent *e) { + Painter p(this); + + p.setFont(_st.font); + p.setPen(_st.textFg); + p.drawTextLeft(0, 0, width(), _text, _textWidth); +} + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/widgets/label_simple.h b/Telegram/SourceFiles/ui/widgets/label_simple.h new file mode 100644 index 000000000..6317da344 --- /dev/null +++ b/Telegram/SourceFiles/ui/widgets/label_simple.h @@ -0,0 +1,48 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "styles/style_widgets.h" + +namespace Ui { + +class LabelSimple : public TWidget { +public: + LabelSimple(QWidget *parent, const style::LabelSimple &st = st::defaultLabelSimple, const QString &value = QString()); + + // This method also resizes the label. + void setText(const QString &newText); + +protected: + void paintEvent(QPaintEvent *e) override; + +private: + QString _fullText; + int _fullTextWidth; + + QString _text; + int _textWidth; + + const style::LabelSimple &_st; + +}; + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/widgets/widgets.style b/Telegram/SourceFiles/ui/widgets/widgets.style new file mode 100644 index 000000000..9b9af8124 --- /dev/null +++ b/Telegram/SourceFiles/ui/widgets/widgets.style @@ -0,0 +1,34 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ + +using "basic.style"; + +LabelSimple { + font: font; + maxWidth: pixels; + textFg: color; +} + +defaultLabelSimple: LabelSimple { + font: normalFont; + maxWidth: 0px; + textFg: windowTextFg; +} diff --git a/Telegram/Telegram.vcxproj b/Telegram/Telegram.vcxproj index 42dc178c9..e060ac8f8 100644 --- a/Telegram/Telegram.vcxproj +++ b/Telegram/Telegram.vcxproj @@ -375,10 +375,22 @@ true true + + true + true + + + true + true + true true + + true + true + true true @@ -713,10 +725,22 @@ true true + + true + true + + + true + true + true true + + true + true + true true @@ -1082,10 +1106,22 @@ true true + + true + true + + + true + true + true true + + true + true + true true @@ -1211,8 +1247,10 @@ + + @@ -1282,6 +1320,9 @@ + + + @@ -1388,10 +1429,12 @@ + + @@ -1416,6 +1459,7 @@ + @@ -1491,8 +1535,10 @@ + + $(QTDIR)\bin\moc.exe;%(FullPath) @@ -1588,6 +1634,48 @@ + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing media_clip_controller.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/media/view/media_clip_controller.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing media_clip_controller.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/media/view/media_clip_controller.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl_debug\Debug\include" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing media_clip_controller.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/media/view/media_clip_controller.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" + + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing media_clip_playback.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/media/view/media_clip_playback.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing media_clip_playback.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/media/view/media_clip_playback.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl_debug\Debug\include" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing media_clip_playback.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/media/view/media_clip_playback.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" + + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing media_clip_volume_controller.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/media/view/media_clip_volume_controller.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing media_clip_volume_controller.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/media/view/media_clip_volume_controller.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl_debug\Debug\include" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing media_clip_volume_controller.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/media/view/media_clip_volume_controller.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" + $(QTDIR)\bin\moc.exe;%(FullPath) @@ -1934,9 +2022,11 @@ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" "-fstdafx.h" "-f../../SourceFiles/ui/countryinput.h" + + @@ -2119,6 +2209,7 @@ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/window/section_widget.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" + @@ -2929,6 +3020,8 @@ true true + + Document "$(SolutionDir)$(Platform)\codegen\$(Configuration)\codegen_style.exe" "-I.\Resources" "-I.\SourceFiles" "-o.\GeneratedFiles\styles" %(FullPath) diff --git a/Telegram/Telegram.vcxproj.filters b/Telegram/Telegram.vcxproj.filters index 6993d85e1..247d35253 100644 --- a/Telegram/Telegram.vcxproj.filters +++ b/Telegram/Telegram.vcxproj.filters @@ -115,6 +115,15 @@ {a281888a-8b70-4e95-9b03-ebcb02837df4} + + {1937d8d7-6dd1-4147-8afb-6f03daff4f0e} + + + {59996402-fc66-481c-9a12-5619112c60a5} + + + {4fdf499d-a1be-46ce-9f17-af007a72e915} + @@ -1389,6 +1398,57 @@ SourceFiles\media + + SourceFiles\ui\widgets + + + GeneratedFiles\Deploy + + + GeneratedFiles\Debug + + + GeneratedFiles\Release + + + SourceFiles\media\view + + + GeneratedFiles\styles + + + GeneratedFiles\styles + + + SourceFiles\ui\effects + + + SourceFiles\ui\buttons + + + SourceFiles\media\view + + + GeneratedFiles\Deploy + + + SourceFiles\media\view + + + GeneratedFiles\Debug + + + GeneratedFiles\Release + + + GeneratedFiles\Deploy + + + GeneratedFiles\Debug + + + GeneratedFiles\Release + @@ -1658,6 +1718,18 @@ SourceFiles\media + + GeneratedFiles\styles + + + GeneratedFiles\styles + + + SourceFiles\ui\effects + + + SourceFiles\ui\buttons + @@ -1954,6 +2026,18 @@ SourceFiles\media + + SourceFiles\ui\widgets + + + SourceFiles\media\view + + + SourceFiles\media\view + + + SourceFiles\media\view + @@ -2035,6 +2119,12 @@ SourceFiles\profile + + SourceFiles\ui\widgets + + + SourceFiles\media\view +