Improve title controls in Windows media viewer.
Before Width: | Height: | Size: 513 B After Width: | Height: | Size: 513 B |
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 188 B After Width: | Height: | Size: 188 B |
Before Width: | Height: | Size: 303 B After Width: | Height: | Size: 303 B |
Before Width: | Height: | Size: 441 B After Width: | Height: | Size: 441 B |
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 146 B |
Before Width: | Height: | Size: 207 B After Width: | Height: | Size: 207 B |
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
Before Width: | Height: | Size: 296 B After Width: | Height: | Size: 296 B |
Before Width: | Height: | Size: 497 B After Width: | Height: | Size: 497 B |
Before Width: | Height: | Size: 729 B After Width: | Height: | Size: 729 B |
Before Width: | Height: | Size: 912 B After Width: | Height: | Size: 912 B |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 454 B After Width: | Height: | Size: 454 B |
Before Width: | Height: | Size: 882 B After Width: | Height: | Size: 882 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/Resources/icons/mediaview/shadow_bottom.png
Normal file
After Width: | Height: | Size: 210 B |
BIN
Telegram/Resources/icons/mediaview/shadow_bottom@2x.png
Normal file
After Width: | Height: | Size: 304 B |
BIN
Telegram/Resources/icons/mediaview/shadow_bottom@3x.png
Normal file
After Width: | Height: | Size: 461 B |
BIN
Telegram/Resources/icons/mediaview/shadow_top.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
Telegram/Resources/icons/mediaview/shadow_top@2x.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
Telegram/Resources/icons/mediaview/shadow_top@3x.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
Telegram/Resources/icons/mediaview/title_viewer_button_close.png
Normal file
After Width: | Height: | Size: 280 B |
After Width: | Height: | Size: 451 B |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 300 B |
After Width: | Height: | Size: 388 B |
After Width: | Height: | Size: 606 B |
After Width: | Height: | Size: 236 B |
After Width: | Height: | Size: 296 B |
After Width: | Height: | Size: 414 B |
After Width: | Height: | Size: 423 B |
After Width: | Height: | Size: 639 B |
After Width: | Height: | Size: 921 B |
BIN
Telegram/Resources/icons/mediaview/title_viewer_shadow_close.png
Normal file
After Width: | Height: | Size: 419 B |
After Width: | Height: | Size: 660 B |
After Width: | Height: | Size: 934 B |
After Width: | Height: | Size: 360 B |
After Width: | Height: | Size: 554 B |
After Width: | Height: | Size: 722 B |
After Width: | Height: | Size: 259 B |
After Width: | Height: | Size: 361 B |
After Width: | Height: | Size: 481 B |
After Width: | Height: | Size: 450 B |
After Width: | Height: | Size: 699 B |
After Width: | Height: | Size: 969 B |
Before Width: | Height: | Size: 172 B |
Before Width: | Height: | Size: 351 B |
Before Width: | Height: | Size: 495 B |
|
@ -101,28 +101,27 @@ mediaviewVolumeToggle: IconButton(mediaviewControlsButton) {
|
|||
}
|
||||
mediaviewVolumeSkip: 4px;
|
||||
|
||||
mediaviewLeft: icon {{ "mediaview_next-flip_horizontal", mediaviewControlFg }};
|
||||
mediaviewRight: icon {{ "mediaview_next", mediaviewControlFg }};
|
||||
mediaviewClose: icon {{ "mediaview_close", mediaviewControlFg }};
|
||||
mediaviewSave: icon {{ "mediaview_download", mediaviewControlFg }};
|
||||
mediaviewRotate: icon {{ "mediaview_rotate", mediaviewControlFg }};
|
||||
mediaviewMore: icon {{ "mediaview_more", mediaviewControlFg }};
|
||||
mediaviewLeft: icon {{ "mediaview/next-flip_horizontal", mediaviewControlFg }};
|
||||
mediaviewRight: icon {{ "mediaview/next", mediaviewControlFg }};
|
||||
mediaviewSave: icon {{ "mediaview/download", mediaviewControlFg }};
|
||||
mediaviewRotate: icon {{ "mediaview/rotate", mediaviewControlFg }};
|
||||
mediaviewMore: icon {{ "mediaview/more", mediaviewControlFg }};
|
||||
|
||||
mediaviewFileRed: icon {
|
||||
{ size(25px, 25px), mediaviewFileBg },
|
||||
{ "mediaview_file_corner", mediaviewFileRedCornerFg },
|
||||
{ "mediaview/file_corner", mediaviewFileRedCornerFg },
|
||||
};
|
||||
mediaviewFileYellow: icon {
|
||||
{ size(25px, 25px), mediaviewFileBg },
|
||||
{ "mediaview_file_corner", mediaviewFileYellowCornerFg },
|
||||
{ "mediaview/file_corner", mediaviewFileYellowCornerFg },
|
||||
};
|
||||
mediaviewFileGreen: icon {
|
||||
{ size(25px, 25px), mediaviewFileBg },
|
||||
{ "mediaview_file_corner", mediaviewFileGreenCornerFg },
|
||||
{ "mediaview/file_corner", mediaviewFileGreenCornerFg },
|
||||
};
|
||||
mediaviewFileBlue: icon {
|
||||
{ size(25px, 25px), mediaviewFileBg },
|
||||
{ "mediaview_file_corner", mediaviewFileBlueCornerFg },
|
||||
{ "mediaview/file_corner", mediaviewFileBlueCornerFg },
|
||||
};
|
||||
|
||||
mediaviewFilePadding: 18px;
|
||||
|
@ -211,7 +210,7 @@ mediaviewControlsPopupMenu: PopupMenu(defaultPopupMenu) {
|
|||
animation: mediaviewControlsPanelAnimation;
|
||||
}
|
||||
|
||||
mediaviewSaveMsgCheck: icon {{ "mediaview_save_check", mediaviewSaveMsgFg }};
|
||||
mediaviewSaveMsgCheck: icon {{ "mediaview/save_check", mediaviewSaveMsgFg }};
|
||||
mediaviewSaveMsgPadding: margins(55px, 19px, 29px, 20px);
|
||||
mediaviewSaveMsgCheckPos: point(23px, 21px);
|
||||
mediaviewSaveMsgShowing: 200;
|
||||
|
@ -269,6 +268,56 @@ mediaviewDefaultTop: 120px;
|
|||
mediaviewDefaultWidth: 800px;
|
||||
mediaviewDefaultHeight: 600px;
|
||||
|
||||
mediaviewTitleMinimize: icon{
|
||||
{ "mediaview/title_viewer_shadow_minimize", windowShadowFg },
|
||||
{ "mediaview/title_viewer_button_minimize", mediaviewControlFg },
|
||||
};
|
||||
mediaviewTitleMaximize: icon{
|
||||
{ "mediaview/title_viewer_shadow_maximize", windowShadowFg },
|
||||
{ "mediaview/title_viewer_button_maximize", mediaviewControlFg },
|
||||
};
|
||||
mediaviewTitleRestore: icon{
|
||||
{ "mediaview/title_viewer_shadow_restore", windowShadowFg },
|
||||
{ "mediaview/title_viewer_button_restore", mediaviewControlFg },
|
||||
};
|
||||
mediaviewTitleClose: icon{
|
||||
{ "mediaview/title_viewer_shadow_close", windowShadowFg },
|
||||
{ "mediaview/title_viewer_button_close", mediaviewControlFg },
|
||||
};
|
||||
mediaviewTitleButton: IconButton(windowTitleButton) {
|
||||
width: 44px;
|
||||
height: 32px;
|
||||
}
|
||||
mediaviewTitle: WindowTitle(defaultWindowTitle) {
|
||||
height: 0px;
|
||||
bg: mediaviewBg;
|
||||
bgActive: mediaviewBg;
|
||||
fg: transparent;
|
||||
fgActive: transparent;
|
||||
minimize: IconButton(mediaviewTitleButton) {
|
||||
icon: mediaviewTitleMinimize;
|
||||
iconOver: mediaviewTitleMinimize;
|
||||
}
|
||||
minimizeIconActive: mediaviewTitleMinimize;
|
||||
minimizeIconActiveOver: mediaviewTitleMinimize;
|
||||
maximize: IconButton(mediaviewTitleButton) {
|
||||
icon: mediaviewTitleMaximize;
|
||||
iconOver: mediaviewTitleMaximize;
|
||||
}
|
||||
maximizeIconActive: mediaviewTitleMaximize;
|
||||
maximizeIconActiveOver: mediaviewTitleMaximize;
|
||||
restoreIcon: mediaviewTitleRestore;
|
||||
restoreIconOver: mediaviewTitleRestore;
|
||||
restoreIconActive: mediaviewTitleRestore;
|
||||
restoreIconActiveOver: mediaviewTitleRestore;
|
||||
close: IconButton(mediaviewTitleButton) {
|
||||
icon: mediaviewTitleClose;
|
||||
iconOver: mediaviewTitleClose;
|
||||
}
|
||||
closeIconActive: mediaviewTitleClose;
|
||||
closeIconActiveOver: mediaviewTitleClose;
|
||||
}
|
||||
|
||||
themePreviewSize: size(903px, 584px);
|
||||
themePreviewBg: windowBg;
|
||||
themePreviewOverlayOpacity: 0.8;
|
||||
|
|
|
@ -558,10 +558,9 @@ auto OverlayWidget::RendererGL::ControlMeta(OverState control)
|
|||
switch (control) {
|
||||
case OverLeftNav: return { 0, &st::mediaviewLeft };
|
||||
case OverRightNav: return { 1, &st::mediaviewRight };
|
||||
case OverClose: return { 2, &st::mediaviewClose };
|
||||
case OverSave: return { 3, &st::mediaviewSave };
|
||||
case OverRotate: return { 4, &st::mediaviewRotate };
|
||||
case OverMore: return { 5, &st::mediaviewMore };
|
||||
case OverSave: return { 2, &st::mediaviewSave };
|
||||
case OverRotate: return { 3, &st::mediaviewRotate };
|
||||
case OverMore: return { 4, &st::mediaviewMore };
|
||||
}
|
||||
Unexpected("Control value in OverlayWidget::RendererGL::ControlIndex.");
|
||||
}
|
||||
|
@ -573,7 +572,6 @@ void OverlayWidget::RendererGL::validateControls() {
|
|||
const auto metas = {
|
||||
ControlMeta(OverLeftNav),
|
||||
ControlMeta(OverRightNav),
|
||||
ControlMeta(OverClose),
|
||||
ControlMeta(OverSave),
|
||||
ControlMeta(OverRotate),
|
||||
ControlMeta(OverMore),
|
||||
|
|
|
@ -130,7 +130,7 @@ private:
|
|||
Ui::GL::Image _groupThumbsImage;
|
||||
Ui::GL::Image _controlsImage;
|
||||
|
||||
static constexpr auto kControlsCount = 6;
|
||||
static constexpr auto kControlsCount = 5;
|
||||
[[nodiscard]] static Control ControlMeta(OverState control);
|
||||
std::array<QRect, kControlsCount> _controlsTextures;
|
||||
|
||||
|
|
|
@ -89,7 +89,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "styles/style_media_view.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_menu_icons.h"
|
||||
#include "styles/style_calls.h"
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include "platform/mac/touchbar/mac_touchbar_media_view.h"
|
||||
|
@ -426,7 +425,7 @@ OverlayWidget::OverlayWidget()
|
|||
//
|
||||
// This doesn't make sense. But it works. :shrug:
|
||||
_titleBugWorkaround->setGeometry(
|
||||
{ 0, 0, size.width(), st::callTitleButton.height });
|
||||
{ 0, 0, size.width(), st::mediaviewTitleButton.height });
|
||||
|
||||
_widget->setGeometry({ QPoint(), size });
|
||||
updateControlsGeometry();
|
||||
|
@ -476,7 +475,7 @@ OverlayWidget::OverlayWidget()
|
|||
});
|
||||
|
||||
_window->setTitle(u"Media viewer"_q);
|
||||
_window->setTitleStyle(st::callTitle);
|
||||
_window->setTitleStyle(st::mediaviewTitle);
|
||||
|
||||
if constexpr (Platform::IsMac()) {
|
||||
// Without Qt::Tool starting with Qt 5.15.1 this widget
|
||||
|
@ -523,6 +522,10 @@ OverlayWidget::OverlayWidget()
|
|||
_touchTimer.setCallback([=] { handleTouchTimer(); });
|
||||
|
||||
_controlsHideTimer.setCallback([=] { hideControls(); });
|
||||
_helper->controlsActivations(
|
||||
) | rpl::start_with_next([=] {
|
||||
activateControls();
|
||||
}, lifetime());
|
||||
|
||||
_docDownload->addClickHandler([=] { downloadMedia(); });
|
||||
_docSaveAs->addClickHandler([=] { saveAs(); });
|
||||
|
@ -779,8 +782,6 @@ void OverlayWidget::updateGeometryToScreen(bool inMove) {
|
|||
|
||||
void OverlayWidget::updateControlsGeometry() {
|
||||
const auto navSkip = st::mediaviewHeaderTop;
|
||||
_closeNav = QRect(width() - st::mediaviewControlSize, 0, st::mediaviewControlSize, st::mediaviewControlSize);
|
||||
_closeNavIcon = style::centerrect(_closeNav, st::mediaviewClose);
|
||||
_leftNav = QRect(0, navSkip, st::mediaviewControlSize, height() - 2 * navSkip);
|
||||
_leftNavIcon = style::centerrect(_leftNav, st::mediaviewLeft);
|
||||
_rightNav = QRect(width() - st::mediaviewControlSize, navSkip, st::mediaviewControlSize, height() - 2 * navSkip);
|
||||
|
@ -1365,10 +1366,10 @@ bool OverlayWidget::updateControlsAnimation(crl::time now) {
|
|||
} else {
|
||||
_controlsOpacity.update(dt, anim::linear);
|
||||
}
|
||||
_helper->setControlsOpacity(_controlsOpacity.current());
|
||||
const auto toUpdate = QRegion()
|
||||
+ (_over == OverLeftNav ? _leftNav : _leftNavIcon)
|
||||
+ (_over == OverRightNav ? _rightNav : _rightNavIcon)
|
||||
+ (_over == OverClose ? _closeNav : _closeNavIcon)
|
||||
+ _saveNavIcon
|
||||
+ _rotateNavIcon
|
||||
+ _moreNavIcon
|
||||
|
@ -1759,6 +1760,7 @@ void OverlayWidget::close() {
|
|||
if (const auto window = Core::App().activeWindow()) {
|
||||
window->reActivate();
|
||||
}
|
||||
_helper->clearState();
|
||||
}
|
||||
|
||||
void OverlayWidget::minimize() {
|
||||
|
@ -1769,6 +1771,7 @@ void OverlayWidget::minimize() {
|
|||
}
|
||||
|
||||
void OverlayWidget::toggleFullScreen(bool fullscreen) {
|
||||
_helper->clearState();
|
||||
_fullscreen = fullscreen;
|
||||
_windowed = !fullscreen;
|
||||
initNormalGeometry();
|
||||
|
@ -1786,6 +1789,7 @@ void OverlayWidget::toggleFullScreen(bool fullscreen) {
|
|||
_wasWindowedMode = true;
|
||||
}
|
||||
savePosition();
|
||||
_helper->clearState();
|
||||
}
|
||||
|
||||
void OverlayWidget::activateControls() {
|
||||
|
@ -4164,12 +4168,6 @@ void OverlayWidget::paintControls(
|
|||
_rightNav,
|
||||
_rightNavIcon,
|
||||
st::mediaviewRight },
|
||||
{
|
||||
OverClose,
|
||||
false,
|
||||
_closeNav,
|
||||
_closeNavIcon,
|
||||
st::mediaviewClose },
|
||||
{
|
||||
OverSave,
|
||||
_saveVisible,
|
||||
|
@ -4695,7 +4693,6 @@ void OverlayWidget::handleMousePress(
|
|||
|| _over == OverRotate
|
||||
|| _over == OverIcon
|
||||
|| _over == OverMore
|
||||
|| _over == OverClose
|
||||
|| _over == OverVideo) {
|
||||
_down = _over;
|
||||
} else if (!_saveMsg.contains(position) || !isSaveMsgShown()) {
|
||||
|
@ -4778,7 +4775,6 @@ void OverlayWidget::updateOverRect(OverState state) {
|
|||
case OverRotate: update(_rotateNavIcon); break;
|
||||
case OverIcon: update(_docIconRect); break;
|
||||
case OverHeader: update(_headerNav); break;
|
||||
case OverClose: update(_closeNav); break;
|
||||
case OverMore: update(_moreNavIcon); break;
|
||||
}
|
||||
}
|
||||
|
@ -4875,10 +4871,6 @@ void OverlayWidget::updateOver(QPoint pos) {
|
|||
updateOverState(OverIcon);
|
||||
} else if (_moreNav.contains(pos)) {
|
||||
updateOverState(OverMore);
|
||||
#if 0 // close
|
||||
} else if (_closeNav.contains(pos)) {
|
||||
updateOverState(OverClose);
|
||||
#endif
|
||||
} else if (documentContentShown() && finalContentRect().contains(pos)) {
|
||||
if ((_document->isVideoFile() || _document->isVideoMessage()) && _streamed) {
|
||||
updateOverState(OverVideo);
|
||||
|
@ -4937,9 +4929,6 @@ void OverlayWidget::handleMouseRelease(
|
|||
handleDocumentClick();
|
||||
} else if (_over == OverMore && _down == OverMore) {
|
||||
InvokeQueued(_widget, [=] { showDropdown(); });
|
||||
} else if (_over == OverClose && _down == OverClose) {
|
||||
//close();
|
||||
toggleFullScreen(!_fullscreen);
|
||||
} else if (_over == OverVideo && _down == OverVideo) {
|
||||
if (_streamed) {
|
||||
playbackPauseResume();
|
||||
|
@ -5220,6 +5209,7 @@ void OverlayWidget::clearBeforeHide() {
|
|||
_controlsHideTimer.cancel();
|
||||
_controlsState = ControlsShown;
|
||||
_controlsOpacity = anim::value(1);
|
||||
_helper->setControlsOpacity(1.);
|
||||
_groupThumbs = nullptr;
|
||||
_groupThumbsRect = QRect();
|
||||
_body->hide();
|
||||
|
|
|
@ -129,7 +129,6 @@ private:
|
|||
OverNone,
|
||||
OverLeftNav,
|
||||
OverRightNav,
|
||||
OverClose,
|
||||
OverHeader,
|
||||
OverName,
|
||||
OverDate,
|
||||
|
@ -492,7 +491,6 @@ private:
|
|||
std::unique_ptr<Collage> _collage;
|
||||
std::optional<WebPageCollage> _collageData;
|
||||
|
||||
QRect _closeNav, _closeNavIcon;
|
||||
QRect _leftNav, _leftNavIcon, _rightNav, _rightNavIcon;
|
||||
QRect _headerNav, _nameNav, _dateNav;
|
||||
QRect _rotateNav, _rotateNavIcon, _saveNav, _saveNavIcon, _moreNav, _moreNavIcon;
|
||||
|
|
|
@ -118,9 +118,6 @@ void MacOverlayWidgetHelper::activate(int button) {
|
|||
void MacOverlayWidgetHelper::beforeShow(bool fullscreen) {
|
||||
_data->window->setAttribute(Qt::WA_MacAlwaysShowToolWindow, !fullscreen);
|
||||
_data->window->windowHandle()->setFlag(Qt::FramelessWindowHint, fullscreen);
|
||||
if (!fullscreen) {
|
||||
_data->window->setGeometry({ 100, 100, 800, 600 });
|
||||
}
|
||||
updateStyles(fullscreen);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,170 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "platform/platform_overlay_widget.h"
|
||||
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/platform/ui_platform_window_title.h"
|
||||
#include "ui/widgets/rp_window.h"
|
||||
#include "styles/style_calls.h"
|
||||
#include "ui/abstract_button.h"
|
||||
#include "styles/style_media_view.h"
|
||||
|
||||
namespace Platform {
|
||||
namespace {
|
||||
|
||||
using namespace Media::View;
|
||||
|
||||
} // namespace
|
||||
|
||||
class DefaultOverlayWidgetHelper::Buttons final
|
||||
: public Ui::Platform::AbstractTitleButtons {
|
||||
public:
|
||||
using Control = Ui::Platform::TitleControl;
|
||||
|
||||
object_ptr<Ui::AbstractButton> create(
|
||||
not_null<QWidget*> parent,
|
||||
Control control,
|
||||
const style::WindowTitle &st) override;
|
||||
void updateState(
|
||||
bool active,
|
||||
bool maximized,
|
||||
const style::WindowTitle &st) override;
|
||||
void notifySynteticOver(Control control, bool over) override;
|
||||
|
||||
void setMasterOpacity(float64 opacity);
|
||||
[[nodiscard]] rpl::producer<> activations() const;
|
||||
|
||||
void clearState();
|
||||
|
||||
private:
|
||||
rpl::event_stream<> _activations;
|
||||
rpl::variable<float64> _masterOpacity = 1.;
|
||||
rpl::variable<bool> _maximized = false;
|
||||
rpl::event_stream<> _clearStateRequests;
|
||||
|
||||
};
|
||||
|
||||
object_ptr<Ui::AbstractButton> DefaultOverlayWidgetHelper::Buttons::create(
|
||||
not_null<QWidget*> parent,
|
||||
Control control,
|
||||
const style::WindowTitle &st) {
|
||||
auto result = object_ptr<Ui::AbstractButton>(parent);
|
||||
const auto raw = result.data();
|
||||
|
||||
struct State {
|
||||
Ui::Animations::Simple animation;
|
||||
float64 progress = -1.;
|
||||
QImage frame;
|
||||
bool maximized = false;
|
||||
bool over = false;
|
||||
};
|
||||
const auto state = raw->lifetime().make_state<State>();
|
||||
|
||||
rpl::merge(
|
||||
_masterOpacity.changes() | rpl::to_empty,
|
||||
_maximized.changes() | rpl::to_empty
|
||||
) | rpl::start_with_next([=] {
|
||||
raw->update();
|
||||
}, raw->lifetime());
|
||||
|
||||
_clearStateRequests.events(
|
||||
) | rpl::start_with_next([=] {
|
||||
raw->clearState();
|
||||
raw->update();
|
||||
state->over = raw->isOver();
|
||||
state->animation.stop();
|
||||
}, raw->lifetime());
|
||||
|
||||
const auto icon = [&] {
|
||||
switch (control) {
|
||||
case Control::Minimize: return &st::mediaviewTitleMinimize;
|
||||
case Control::Maximize: return &st::mediaviewTitleMaximize;
|
||||
case Control::Close: return &st::mediaviewTitleClose;
|
||||
}
|
||||
Unexpected("Value in DefaultOverlayWidgetHelper::Buttons::create.");
|
||||
}();
|
||||
|
||||
raw->resize(icon->size());
|
||||
state->frame = QImage(
|
||||
icon->size() * style::DevicePixelRatio(),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
state->frame.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
|
||||
const auto updateOver = [=] {
|
||||
const auto over = raw->isOver();
|
||||
if (state->over == over) {
|
||||
return;
|
||||
}
|
||||
state->over = over;
|
||||
state->animation.start(
|
||||
[=] { raw->update(); },
|
||||
state->over ? 0. : 1.,
|
||||
state->over ? 1. : 0.,
|
||||
st::mediaviewFadeDuration);
|
||||
};
|
||||
|
||||
const auto prepareFrame = [=] {
|
||||
const auto progress = state->animation.value(state->over ? 1. : 0.);
|
||||
const auto maximized = _maximized.current();
|
||||
if (state->progress == progress && state->maximized == maximized) {
|
||||
return;
|
||||
}
|
||||
state->progress = progress;
|
||||
state->maximized = maximized;
|
||||
auto current = icon;
|
||||
if (control == Control::Maximize) {
|
||||
current = maximized ? &st::mediaviewTitleRestore : icon;
|
||||
}
|
||||
const auto alpha = progress * kOverBackgroundOpacity;
|
||||
const auto ialpha = anim::interpolate(0, 255, alpha);
|
||||
state->frame.fill(QColor(255, 255, 255, ialpha));
|
||||
|
||||
auto q = QPainter(&state->frame);
|
||||
const auto normal = maximized
|
||||
? kMaximizedIconOpacity
|
||||
: kNormalIconOpacity;
|
||||
q.setOpacity(progress + (1 - progress) * normal);
|
||||
current->paint(q, 0, 0, raw->width());
|
||||
q.end();
|
||||
};
|
||||
|
||||
raw->paintRequest(
|
||||
) | rpl::start_with_next([=] {
|
||||
updateOver();
|
||||
prepareFrame();
|
||||
|
||||
auto p = QPainter(raw);
|
||||
p.setOpacity(_masterOpacity.current());
|
||||
p.drawImage(0, 0, state->frame);
|
||||
}, raw->lifetime());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void DefaultOverlayWidgetHelper::Buttons::updateState(
|
||||
bool active,
|
||||
bool maximized,
|
||||
const style::WindowTitle &st) {
|
||||
_maximized = maximized;
|
||||
}
|
||||
|
||||
void DefaultOverlayWidgetHelper::Buttons::notifySynteticOver(
|
||||
Ui::Platform::TitleControl control,
|
||||
bool over) {
|
||||
if (over) {
|
||||
_activations.fire({});
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultOverlayWidgetHelper::Buttons::clearState() {
|
||||
_clearStateRequests.fire({});
|
||||
}
|
||||
|
||||
void DefaultOverlayWidgetHelper::Buttons::setMasterOpacity(float64 opacity) {
|
||||
_masterOpacity = opacity;
|
||||
}
|
||||
|
||||
rpl::producer<> DefaultOverlayWidgetHelper::Buttons::activations() const {
|
||||
return _activations.events();
|
||||
}
|
||||
|
||||
void OverlayWidgetHelper::minimize(not_null<Ui::RpWindow*> window) {
|
||||
window->setWindowState(window->windowState() | Qt::WindowMinimized);
|
||||
|
@ -20,10 +179,14 @@ void OverlayWidgetHelper::minimize(not_null<Ui::RpWindow*> window) {
|
|||
DefaultOverlayWidgetHelper::DefaultOverlayWidgetHelper(
|
||||
not_null<Ui::RpWindow*> window,
|
||||
Fn<void(bool)> maximize)
|
||||
: _controls(Ui::Platform::SetupSeparateTitleControls(
|
||||
: _buttons(new DefaultOverlayWidgetHelper::Buttons())
|
||||
, _controls(Ui::Platform::SetupSeparateTitleControls(
|
||||
window,
|
||||
st::callTitle,
|
||||
std::move(maximize))) {
|
||||
std::make_unique<Ui::Platform::SeparateTitleControls>(
|
||||
window->body(),
|
||||
st::mediaviewTitle,
|
||||
std::unique_ptr<DefaultOverlayWidgetHelper::Buttons>(_buttons.get()),
|
||||
std::move(maximize)))) {
|
||||
}
|
||||
|
||||
DefaultOverlayWidgetHelper::~DefaultOverlayWidgetHelper() = default;
|
||||
|
@ -36,4 +199,20 @@ bool DefaultOverlayWidgetHelper::skipTitleHitTest(QPoint position) {
|
|||
return _controls->controls.geometry().contains(position);
|
||||
}
|
||||
|
||||
rpl::producer<> DefaultOverlayWidgetHelper::controlsActivations() {
|
||||
return _buttons->activations();
|
||||
}
|
||||
|
||||
void DefaultOverlayWidgetHelper::beforeShow(bool fullscreen) {
|
||||
_buttons->clearState();
|
||||
}
|
||||
|
||||
void DefaultOverlayWidgetHelper::clearState() {
|
||||
_buttons->clearState();
|
||||
}
|
||||
|
||||
void DefaultOverlayWidgetHelper::setControlsOpacity(float64 opacity) {
|
||||
_buttons->setMasterOpacity(opacity);
|
||||
}
|
||||
|
||||
} // namespace Platform
|
||||
|
|
|
@ -15,6 +15,14 @@ namespace Ui::Platform {
|
|||
struct SeparateTitleControls;
|
||||
} // namespace Ui::Platform
|
||||
|
||||
namespace Media::View {
|
||||
|
||||
inline constexpr auto kMaximizedIconOpacity = 0.6;
|
||||
inline constexpr auto kNormalIconOpacity = 0.9;
|
||||
inline constexpr auto kOverBackgroundOpacity = 0.15;
|
||||
|
||||
} // namespace Media::View
|
||||
|
||||
namespace Platform {
|
||||
|
||||
class OverlayWidgetHelper {
|
||||
|
@ -26,6 +34,9 @@ public:
|
|||
[[nodiscard]] virtual bool skipTitleHitTest(QPoint position) {
|
||||
return false;
|
||||
}
|
||||
[[nodiscard]] virtual rpl::producer<> controlsActivations() {
|
||||
return rpl::never<>();
|
||||
}
|
||||
virtual void beforeShow(bool fullscreen) {
|
||||
}
|
||||
virtual void afterShow(bool fullscreen) {
|
||||
|
@ -33,6 +44,10 @@ public:
|
|||
virtual void notifyFileDialogShown(bool shown) {
|
||||
}
|
||||
virtual void minimize(not_null<Ui::RpWindow*> window);
|
||||
virtual void clearState() {
|
||||
}
|
||||
virtual void setControlsOpacity(float64 opacity) {
|
||||
}
|
||||
};
|
||||
|
||||
[[nodiscard]] std::unique_ptr<OverlayWidgetHelper> CreateOverlayWidgetHelper(
|
||||
|
@ -48,8 +63,15 @@ public:
|
|||
|
||||
void orderWidgets() override;
|
||||
bool skipTitleHitTest(QPoint position) override;
|
||||
rpl::producer<> controlsActivations() override;
|
||||
void beforeShow(bool fullscreen) override;
|
||||
void clearState() override;
|
||||
void setControlsOpacity(float64 opacity) override;
|
||||
|
||||
private:
|
||||
class Buttons;
|
||||
|
||||
const not_null<Buttons*> _buttons;
|
||||
const std::unique_ptr<Ui::Platform::SeparateTitleControls> _controls;
|
||||
|
||||
};
|
||||
|
|
|
@ -320,10 +320,10 @@ historyFileOutPlay: icon {{ "history_file_play", historyFileOutIconFg }};
|
|||
historyFileOutPlaySelected: icon {{ "history_file_play", historyFileOutIconFgSelected }};
|
||||
historyFileInPlay: icon {{ "history_file_play", historyFileInIconFg }};
|
||||
historyFileInPlaySelected: icon {{ "history_file_play", historyFileInIconFgSelected }};
|
||||
historyFileOutWaiting: icon {{ "mediaview_save_check", historyFileOutIconFg }};
|
||||
historyFileOutWaitingSelected: icon {{ "mediaview_save_check", historyFileOutIconFgSelected }};
|
||||
historyFileInWaiting: icon {{ "mediaview_save_check", historyFileInIconFg }};
|
||||
historyFileInWaitingSelected: icon {{ "mediaview_save_check", historyFileInIconFgSelected }};
|
||||
historyFileOutWaiting: icon {{ "mediaview/save_check", historyFileOutIconFg }};
|
||||
historyFileOutWaitingSelected: icon {{ "mediaview/save_check", historyFileOutIconFgSelected }};
|
||||
historyFileInWaiting: icon {{ "mediaview/save_check", historyFileInIconFg }};
|
||||
historyFileInWaitingSelected: icon {{ "mediaview/save_check", historyFileInIconFgSelected }};
|
||||
|
||||
historyFileThumbPause: icon {{ "history_file_pause", historyFileThumbIconFg }};
|
||||
historyFileThumbPauseSelected: icon {{ "history_file_pause", historyFileThumbIconFgSelected }};
|
||||
|
@ -333,8 +333,8 @@ historyFileThumbCancel: icon {{ "history_file_cancel", historyFileThumbIconFg }}
|
|||
historyFileThumbCancelSelected: icon {{ "history_file_cancel", historyFileThumbIconFgSelected }};
|
||||
historyFileThumbPlay: icon {{ "history_file_play", historyFileThumbIconFg }};
|
||||
historyFileThumbPlaySelected: icon {{ "history_file_play", historyFileThumbIconFgSelected }};
|
||||
historyFileThumbWaiting: icon {{ "mediaview_save_check", historyFileThumbIconFg }};
|
||||
historyFileThumbWaitingSelected: icon {{ "mediaview_save_check", historyFileThumbIconFgSelected }};
|
||||
historyFileThumbWaiting: icon {{ "mediaview/save_check", historyFileThumbIconFg }};
|
||||
historyFileThumbWaitingSelected: icon {{ "mediaview/save_check", historyFileThumbIconFgSelected }};
|
||||
|
||||
historySendStateSpace: 24px;
|
||||
historySendStatePosition: point(-17px, -19px);
|
||||
|
|