Left main menu.

This commit is contained in:
John Preston 2016-11-11 22:51:59 +03:00
parent 807bebb3cf
commit a74baaea36
12 changed files with 320 additions and 11 deletions

View File

@ -834,7 +834,7 @@ void AppClass::cancelPhotoUpdate(const PeerId &peer) {
void AppClass::mtpPause() {
MTP::pause();
_mtpUnpauseTimer.start(st::slideDuration * 2);
_mtpUnpauseTimer.start(st::layerSlideDuration * 2);
}
void AppClass::mtpUnpause() {

View File

@ -100,18 +100,20 @@ dialogsFilter: flatInput(inpDefGray) {
width: 240px;
height: 32px;
textMrg: margins(12px, 3px, 12px, 3px);
textMrg: margins(12px, 3px, 30px, 3px);
}
dialogsCancelSearch: IconButton(dialogsMenuToggle) {
icon: icon {{ "dialogs_cancel_search", dialogsMenuIconFg, point(0px, 1px) }};
iconOver: icon {{ "dialogs_cancel_search", dialogsMenuIconFgOver, point(0px, 1px) }};
}
dialogsMenu: DropdownMenu(defaultDropdownMenu) {
menu: Menu(defaultMenu) {
itemIconPosition: point(15px, 8px);
itemPadding: margins(56px, 10px, 56px, 12px);
}
dialogsMenu: Menu(defaultMenu) {
itemFont: semiboldFont;
itemIconPosition: point(28px, 11px);
itemPadding: margins(76px, 14px, 28px, 14px);
}
dialogsMenuWrap: DropdownMenu(defaultDropdownMenu) {
menu: dialogsMenu;
}
dialogsMenuPosition: point(-3px, -2px);
dialogsMenuNewGroup: icon {{ "menu_new_group", menuIconFg }};

View File

@ -2012,8 +2012,11 @@ void DialogsWidget::onChooseByDrag() {
}
void DialogsWidget::showMainMenu() {
App::wnd()->showMainMenu();
return;
if (!_mainMenu) {
_mainMenu.create(this, st::dialogsMenu);
_mainMenu.create(this, st::dialogsMenuWrap);
_mainMenu->addAction(lang(lng_create_group_title), [] {
App::wnd()->onShowNewGroup();
}, &st::dialogsMenuNewGroup, &st::dialogsMenuNewGroupOver);

View File

@ -28,6 +28,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "mainwidget.h"
#include "ui/filedialog.h"
#include "styles/style_stickers.h"
#include "window/window_main_menu.h"
namespace {
@ -48,6 +49,19 @@ public:
, _shadow(st::boxShadow) {
}
void setBodyCache(QPixmap &&bodyCache) {
_bodyCache = std_::move(bodyCache);
}
void setMainMenuCache(QPixmap &&mainMenuCache) {
_mainMenuCache = std_::move(mainMenuCache);
if (!_mainMenuCache.isNull()) {
_mainMenuWidth = _mainMenuCache.width() / cIntRetinaFactor();
_mainMenuRight = 0;
}
}
void setMainMenuRight(int right) {
_mainMenuRight = right;
}
void setLayerBox(const QRect &box, const QRect &hiddenSpecialBox) {
_box = box;
_hiddenSpecialBox = hiddenSpecialBox;
@ -61,6 +75,25 @@ protected:
void paintEvent(QPaintEvent *e) override {
Painter p(this);
auto hasMainMenuCache = !_mainMenuCache.isNull();
if (hasMainMenuCache || _mainMenuRight) {
auto boxLeft = _mainMenuRight;
auto cacheWidth = boxLeft * cIntRetinaFactor();
if (left > 0 && hasMainMenuCache) {
p.drawPixmapLeft(0, 0, width(), _mainMenuCache, rtlrect(_mainMenuCache.width() - cacheWidth, 0, cacheWidth, height() * cIntRetinaFactor(), _mainMenuCache.width()));
}
if (!_bodyCache.isNull()) {
p.drawPixmapLeft(boxLeft, 0, width(), _bodyCache, rtlrect(cacheWidth, 0, _bodyCache.width() - cacheWidth, height() * cIntRetinaFactor(), _bodyCache.width() - cacheWidth));
}
_shadow.paint(p, QRect(0, 0, boxLeft, height()), 0, Ui::RectShadow::Side::Right);
p.setOpacity(_opacity);
p.fillRect(myrtlrect(boxLeft, 0, width() - boxLeft, height()), st::layerBg);
return;
}
if (!_bodyCache.isNull()) {
p.drawPixmap(0, 0, _bodyCache);
}
p.setOpacity(_opacity);
if (_box.isNull()) {
p.fillRect(rect(), st::layerBg);
@ -79,6 +112,11 @@ protected:
}
private:
QPixmap _bodyCache;
QPixmap _mainMenuCache;
int _mainMenuWidth = 0;
int _mainMenuRight = 0;
QRect _box, _hiddenSpecialBox;
float64 _opacity = 0.;
@ -224,6 +262,16 @@ void LayerStackWidget::startHide() {
}
void LayerStackWidget::startAnimation(float64 toOpacity) {
if (_mainMenu) {
setAttribute(Qt::WA_OpaquePaintEvent);
hide();
_background->setBodyCache(myGrab(App::wnd()->bodyWidget()));
show();
_mainMenu->hide();
_background->setMainMenuCache(myGrab(_mainMenu));
_background->setMainMenuRight(toOpacity ? 0 : _mainMenu->width());
}
if (App::app()) App::app()->mtpPause();
a_bg.start(toOpacity);
a_layer.start(toOpacity);
@ -283,6 +331,9 @@ void LayerStackWidget::resizeEvent(QResizeEvent *e) {
if (auto l = layer()) {
l->parentResized();
}
if (_mainMenu) {
_mainMenu->resize(_mainMenu->width(), height());
}
updateLayerBox();
}
@ -300,6 +351,28 @@ void LayerStackWidget::showSpecialLayer(LayerWidget *l) {
activateLayer(l);
}
void LayerStackWidget::showMainMenu() {
clearLayers();
if (_specialLayer) {
_specialLayer.destroyDelayed();
}
_mainMenu.create(this);
_mainMenu->setGeometryToLeft(0, 0, _mainMenu->width(), height());
_mainMenu->setParent(this);
fixOrder();
if (isHidden()) {
startShow();
} else {
_mainMenu->show();
if (App::wnd()) App::wnd()->setInnerFocus();
updateLayerBox();
}
fixOrder();
sendFakeMouseEvent();
}
void LayerStackWidget::appendLayer(LayerWidget *l) {
if (auto oldLayer = layer()) {
oldLayer->hide();
@ -338,6 +411,11 @@ void LayerStackWidget::initChildLayer(LayerWidget *l) {
}
void LayerStackWidget::activateLayer(LayerWidget *l) {
if (_mainMenu) {
_mainMenu.destroyDelayed();
_background->setMainMenuRight(0);
_background->setMainMenuCache(QPixmap());
}
initChildLayer(l);
if (isHidden()) {
startShow();
@ -358,6 +436,9 @@ void LayerStackWidget::fixOrder() {
} else if (_specialLayer) {
_specialLayer->raise();
}
if (_mainMenu) {
_mainMenu->raise();
}
}
void LayerStackWidget::sendFakeMouseEvent() {
@ -371,8 +452,15 @@ void LayerStackWidget::step_background(float64 ms, bool timer) {
a_layer.finish();
_a_background.stop();
_layerCache = _hiddenSpecialLayerCache = QPixmap();
setAttribute(Qt::WA_OpaquePaintEvent, false);
_background->setBodyCache(QPixmap());
if (_hiding) {
App::wnd()->layerFinishedHide(this);
if (_mainMenu) {
_background->setMainMenuRight(0);
_background->setMainMenuCache(QPixmap());
_mainMenu.destroyDelayed();
}
} else {
if (_specialLayer) {
_specialLayer->show();
@ -382,7 +470,11 @@ void LayerStackWidget::step_background(float64 ms, bool timer) {
l->show();
l->showDone();
}
fixOrder();
if (_mainMenu) {
_background->setMainMenuRight(_mainMenu->width());
_background->setMainMenuCache(QPixmap());
_mainMenu->show();
}
if (App::wnd()) App::wnd()->setInnerFocus();
}
updateLayerBox();
@ -390,6 +482,9 @@ void LayerStackWidget::step_background(float64 ms, bool timer) {
} else {
a_bg.update(dt, anim::easeOutCirc);
a_layer.update(dt, anim::linear);
if (_mainMenu) {
_background->setMainMenuRight(a_bg.current() * _mainMenu->width());
}
}
_background->setOpacity(a_bg.current());
if (timer) {

View File

@ -20,6 +20,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#pragma once
namespace Window {
class MainMenu;
} // namespace Window
#include "ui/effects/rect_shadow.h"
class LayerWidget : public TWidget {
@ -65,6 +69,7 @@ public:
void showLayer(LayerWidget *l);
void showSpecialLayer(LayerWidget *l);
void showMainMenu();
void appendLayer(LayerWidget *l);
void prependLayer(LayerWidget *l);
@ -115,6 +120,7 @@ private:
Layers _layers;
ChildWidget<LayerWidget> _specialLayer = { nullptr };
ChildWidget<Window::MainMenu> _mainMenu = { nullptr };
class BackgroundWidget;
ChildWidget<BackgroundWidget> _background;

View File

@ -48,6 +48,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "window/notifications_manager.h"
#include "window/window_theme.h"
#include "window/window_theme_warning.h"
#include "window/window_main_menu.h"
ConnectingWidget::ConnectingWidget(QWidget *parent, const QString &text, const QString &reconnect) : TWidget(parent)
, _shadow(st::boxShadow)
@ -406,6 +407,17 @@ void MainWindow::showSettings() {
_layerBg->showSpecialLayer(_settings);
}
void MainWindow::showMainMenu() {
if (_passcode) return;
if (isHidden()) showFromTray();
if (!_layerBg) {
_layerBg.create(bodyWidget());
}
_layerBg->showMainMenu();
}
void MainWindow::ui_hideSettingsAndLayer(ShowLayerOptions options) {
if (_layerBg) {
_layerBg->onClose();

View File

@ -157,6 +157,8 @@ public:
return contentOverlapped(QRect(w->mapToGlobal(r.boundingRect().topLeft()), r.boundingRect().size()));
}
void showMainMenu();
void ui_showLayer(LayerWidget *box, ShowLayerOptions options);
void ui_hideSettingsAndLayer(ShowLayerOptions options);
bool ui_isLayerShown();

View File

@ -50,7 +50,7 @@ public:
virtual ~MainWindow();
QWidget *bodyWidget() {
TWidget *bodyWidget() {
return _body;
}
@ -90,7 +90,7 @@ private:
bool _positionInited = false;
ChildWidget<TitleWidget> _title = { nullptr };
ChildWidget<QWidget> _body;
ChildWidget<TWidget> _body;
QString _titleText;

View File

@ -84,6 +84,40 @@ notifySendReply: IconButton {
titleUnreadCounterTop: 5px;
titleUnreadCounterRight: 35px;
mainMenuBg: #ffffff;
mainMenuWidth: 274px;
mainMenuCoverBg: #419fd9;
mainMenuCoverFg: windowActiveFg;
mainMenuCoverHeight: 140px;
mainMenuUserpicLeft: 24px;
mainMenuUserpicTop: 22px;
mainMenuUserpicSize: 48px;
mainMenuCoverTextLeft: 30px;
mainMenuCoverNameTop: 88px;
mainMenuCoverStatusTop: 106px;
mainMenuSkip: 13px;
mainMenuFooterLeft: 30px;
mainMenuTelegramLabel: flatLabel(labelDefFlat) {
font: semiboldFont;
align: align(left);
textFg: windowSubTextFg;
}
mainMenuTelegramStyle: textStyle(defaultTextStyle) {
linkFlags: semiboldFont;
linkFlagsOver: font(fsize semibold underline);
linkFg: windowSubTextFg;
linkFgDown: windowSubTextFg;
}
mainMenuTelegramBottom: 43px;
mainMenuVersionLabel: flatLabel(mainMenuTelegramLabel) {
font: normalFont;
}
mainMenuVersionStyle: textStyle(mainMenuTelegramStyle) {
linkFlags: normalFont;
linkFlagsOver: font(fsize underline);
}
mainMenuVersionBottom: 21px;
// Windows specific title
titleHeight: 21px;

View File

@ -0,0 +1,105 @@
/*
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 "window/window_main_menu.h"
#include "styles/style_window.h"
#include "ui/flatlabel.h"
#include "ui/widgets/menu.h"
#include "mainwindow.h"
#include "boxes/contactsbox.h"
#include "boxes/aboutbox.h"
#include "lang.h"
#include "core/click_handler_types.h"
#include "styles/style_dialogs.h"
namespace Window {
namespace {
class AboutClickHandler : public ClickHandler {
public:
void onClick(Qt::MouseButton) const override {
Ui::showLayer(new AboutBox());
}
};
} // namespace
MainMenu::MainMenu(QWidget *parent) : TWidget(parent)
, _menu(this, st::dialogsMenu)
, _telegram(this, st::mainMenuTelegramLabel, st::mainMenuTelegramStyle)
, _version(this, st::mainMenuVersionLabel, st::mainMenuVersionStyle) {
setAttribute(Qt::WA_OpaquePaintEvent);
resize(st::mainMenuWidth, parentWidget()->height());
_menu->setTriggeredCallback([](QAction *action, int actionTop, Ui::Menu::TriggeredSource source) {
emit action->triggered();
});
_menu->addAction(lang(lng_create_group_title), [] {
App::wnd()->onShowNewGroup();
}, &st::dialogsMenuNewGroup, &st::dialogsMenuNewGroupOver);
_menu->addAction(lang(lng_create_channel_title), [] {
App::wnd()->onShowNewChannel();
}, &st::dialogsMenuNewChannel, &st::dialogsMenuNewChannelOver);
_menu->addAction(lang(lng_menu_contacts), [] {
Ui::showLayer(new ContactsBox());
}, &st::dialogsMenuContacts, &st::dialogsMenuContactsOver);
_menu->addAction(lang(lng_menu_settings), [] {
App::wnd()->showSettings();
}, &st::dialogsMenuSettings, &st::dialogsMenuSettingsOver);
_menu->addAction(lang(lng_settings_faq), [] {
QDesktopServices::openUrl(telegramFaqLink());
}, &st::dialogsMenuHelp, &st::dialogsMenuHelpOver);
_telegram->setRichText(textcmdLink(1, qsl("Telegram Desktop")));
_telegram->setLink(1, ClickHandlerPtr(new UrlClickHandler(qsl("https://desktop.telegram.org"))));
_version->setRichText(textcmdLink(1, qsl("Version 1.2.3")) + QChar(' ') + QChar(8211) + QChar(' ') + textcmdLink(2, qsl("About")));
_version->setLink(1, ClickHandlerPtr(new UrlClickHandler(qsl("https://desktop.telegram.org/?_hash=changelog"))));
_version->setLink(2, ClickHandlerPtr(new AboutClickHandler()));
}
void MainMenu::resizeEvent(QResizeEvent *e) {
_menu->setGeometry(0, st::mainMenuCoverHeight + st::mainMenuSkip, width(), _menu->height());
_telegram->moveToLeft(st::mainMenuFooterLeft, height() - st::mainMenuTelegramBottom - _telegram->height());
_version->moveToLeft(st::mainMenuFooterLeft, height() - st::mainMenuVersionBottom - _version->height());
}
void MainMenu::paintEvent(QPaintEvent *e) {
Painter p(this);
auto cover = QRect(0, 0, width(), st::mainMenuCoverHeight).intersected(e->rect());
if (!cover.isEmpty()) {
p.fillRect(cover, st::mainMenuCoverBg);
p.setPen(st::mainMenuCoverFg);
p.setFont(st::semiboldFont);
if (auto self = App::self()) {
self->paintUserpicLeft(p, st::mainMenuUserpicSize, st::mainMenuUserpicLeft, st::mainMenuUserpicTop, width());
self->nameText.drawLeftElided(p, st::mainMenuCoverTextLeft, st::mainMenuCoverNameTop, width() - 2 * st::mainMenuCoverTextLeft, width());
p.setFont(st::normalFont);
p.drawTextLeft(st::mainMenuCoverTextLeft, st::mainMenuCoverStatusTop, width(), qsl("online"));
}
}
auto other = QRect(0, st::mainMenuCoverHeight, width(), height() - st::mainMenuCoverHeight);
if (!other.isEmpty()) {
p.fillRect(other, st::mainMenuBg);
}
}
} // namespace Window

View File

@ -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 "ui/effects/rect_shadow.h"
class FlatLabel;
namespace Ui {
class Menu;
} // namespace Ui
namespace Window {
class MainMenu : public TWidget {
public:
MainMenu(QWidget *parent);
protected:
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
private:
ChildWidget<Ui::Menu> _menu;
ChildWidget<FlatLabel> _telegram;
ChildWidget<FlatLabel> _version;
};
} // namespace Window

View File

@ -555,6 +555,8 @@
'<(src_loc)/window/slide_animation.h',
'<(src_loc)/window/top_bar_widget.cpp',
'<(src_loc)/window/top_bar_widget.h',
'<(src_loc)/window/window_main_menu.cpp',
'<(src_loc)/window/window_main_menu.h',
'<(src_loc)/window/window_theme.cpp',
'<(src_loc)/window/window_theme.h',
'<(src_loc)/window/window_theme_warning.cpp',