From a74baaea364ae3a64cff82a134a037f6d83e0303 Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Fri, 11 Nov 2016 22:51:59 +0300
Subject: [PATCH] Left main menu.

---
 Telegram/SourceFiles/application.cpp          |   2 +-
 Telegram/SourceFiles/dialogs/dialogs.style    |  14 ++-
 Telegram/SourceFiles/dialogswidget.cpp        |   5 +-
 Telegram/SourceFiles/layerwidget.cpp          |  97 +++++++++++++++-
 Telegram/SourceFiles/layerwidget.h            |   6 +
 Telegram/SourceFiles/mainwindow.cpp           |  12 ++
 Telegram/SourceFiles/mainwindow.h             |   2 +
 Telegram/SourceFiles/window/main_window.h     |   4 +-
 Telegram/SourceFiles/window/window.style      |  34 ++++++
 .../SourceFiles/window/window_main_menu.cpp   | 105 ++++++++++++++++++
 .../SourceFiles/window/window_main_menu.h     |  48 ++++++++
 Telegram/gyp/Telegram.gyp                     |   2 +
 12 files changed, 320 insertions(+), 11 deletions(-)
 create mode 100644 Telegram/SourceFiles/window/window_main_menu.cpp
 create mode 100644 Telegram/SourceFiles/window/window_main_menu.h

diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp
index 42953122c..08b1669d1 100644
--- a/Telegram/SourceFiles/application.cpp
+++ b/Telegram/SourceFiles/application.cpp
@@ -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() {
diff --git a/Telegram/SourceFiles/dialogs/dialogs.style b/Telegram/SourceFiles/dialogs/dialogs.style
index 79226dfb5..4a68d2998 100644
--- a/Telegram/SourceFiles/dialogs/dialogs.style
+++ b/Telegram/SourceFiles/dialogs/dialogs.style
@@ -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 }};
diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp
index 779b7a2a1..32fd61b7c 100644
--- a/Telegram/SourceFiles/dialogswidget.cpp
+++ b/Telegram/SourceFiles/dialogswidget.cpp
@@ -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);
diff --git a/Telegram/SourceFiles/layerwidget.cpp b/Telegram/SourceFiles/layerwidget.cpp
index f6de4cce5..249929550 100644
--- a/Telegram/SourceFiles/layerwidget.cpp
+++ b/Telegram/SourceFiles/layerwidget.cpp
@@ -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) {
diff --git a/Telegram/SourceFiles/layerwidget.h b/Telegram/SourceFiles/layerwidget.h
index b44b4bc32..bd0eb45a1 100644
--- a/Telegram/SourceFiles/layerwidget.h
+++ b/Telegram/SourceFiles/layerwidget.h
@@ -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;
diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp
index bb6f4982b..f6a68ca78 100644
--- a/Telegram/SourceFiles/mainwindow.cpp
+++ b/Telegram/SourceFiles/mainwindow.cpp
@@ -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();
diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h
index 8f53d7d32..452b41611 100644
--- a/Telegram/SourceFiles/mainwindow.h
+++ b/Telegram/SourceFiles/mainwindow.h
@@ -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();
diff --git a/Telegram/SourceFiles/window/main_window.h b/Telegram/SourceFiles/window/main_window.h
index 1e3f11f9b..d287a0370 100644
--- a/Telegram/SourceFiles/window/main_window.h
+++ b/Telegram/SourceFiles/window/main_window.h
@@ -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;
 
diff --git a/Telegram/SourceFiles/window/window.style b/Telegram/SourceFiles/window/window.style
index 06a2cdfe0..a6db6a26c 100644
--- a/Telegram/SourceFiles/window/window.style
+++ b/Telegram/SourceFiles/window/window.style
@@ -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;
diff --git a/Telegram/SourceFiles/window/window_main_menu.cpp b/Telegram/SourceFiles/window/window_main_menu.cpp
new file mode 100644
index 000000000..1e2cc1e90
--- /dev/null
+++ b/Telegram/SourceFiles/window/window_main_menu.cpp
@@ -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
diff --git a/Telegram/SourceFiles/window/window_main_menu.h b/Telegram/SourceFiles/window/window_main_menu.h
new file mode 100644
index 000000000..62f68b4a4
--- /dev/null
+++ b/Telegram/SourceFiles/window/window_main_menu.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 "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
diff --git a/Telegram/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp
index 788c11023..dc7818dfd 100644
--- a/Telegram/gyp/Telegram.gyp
+++ b/Telegram/gyp/Telegram.gyp
@@ -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',