/* This file is part of Telegram Desktop, an unofficial desktop 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. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014 John Preston, https://tdesktop.com */ #include "stdafx.h" #include "lang.h" #include "style.h" #include "title.h" #include "mainwidget.h" #include "window.h" #include "application.h" #include "boxes/contactsbox.h" #include "boxes/aboutbox.h" TitleHider::TitleHider(QWidget *parent) : QWidget(parent), _level(0) { } void TitleHider::paintEvent(QPaintEvent *e) { QPainter p(this); p.setOpacity(_level * st::layerAlpha); p.fillRect(App::main()->dlgsWidth() - 1, 0, width() - App::main()->dlgsWidth(), height(), st::layerBG->b); } void TitleHider::mousePressEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton) { emit static_cast(parentWidget())->hiderClicked(); } } void TitleHider::setLevel(float64 level) { _level = level; update(); } TitleWidget::TitleWidget(Window *window) : QWidget(window) , wnd(window) , hideLevel(0) , hider(0) , _settings(this, lang(lng_menu_settings), st::titleTextButton) , _contacts(this, lang(lng_menu_contacts), st::titleTextButton) , _about(this, lang(lng_menu_about), st::titleTextButton) , _update(this, window, lang(lng_menu_update)) , _minimize(this, window) , _maximize(this, window) , _restore(this, window) , _close(this, window) , lastMaximized(!(window->windowState() & Qt::WindowMaximized)) { setGeometry(0, 0, wnd->width(), st::titleHeight); stateChanged(); _update.hide(); if (App::app()->updatingState() == Application::UpdatingReady) { showUpdateBtn(); } connect(&_settings, SIGNAL(clicked()), window, SLOT(showSettings())); connect(&_contacts, SIGNAL(clicked()), this, SLOT(onContacts())); connect(&_about, SIGNAL(clicked()), this, SLOT(onAbout())); connect(wnd->windowHandle(), SIGNAL(windowStateChanged(Qt::WindowState)), this, SLOT(stateChanged(Qt::WindowState))); connect(App::app(), SIGNAL(updateReady()), this, SLOT(showUpdateBtn())); if (cPlatform() != dbipWindows) { _minimize.hide(); _maximize.hide(); _restore.hide(); _close.hide(); } } void TitleWidget::paintEvent(QPaintEvent *e) { QPainter p(this); p.fillRect(QRect(0, 0, width(), st::titleHeight), st::titleBG->b); p.drawPixmap(st::titleIconPos, App::sprite(), st::titleIconRect); } bool TitleWidget::animStep(float64 ms) { float64 phase = sin(M_PI_2 * (ms / st::updateBlinkDuration)); if (phase < 0) phase = -phase; _update.setOverLevel(phase); return true; } void TitleWidget::setHideLevel(float64 level) { if (level != hideLevel) { hideLevel = level; if (hideLevel) { if (!hider) { hider = new TitleHider(this); hider->move(0, 0); hider->resize(size()); hider->show(); } hider->setLevel(hideLevel); } else { if (hider) hider->deleteLater(); hider = 0; } } } void TitleWidget::onContacts() { if (App::wnd() && App::wnd()->isHidden()) App::wnd()->showFromTray(); if (!App::self()) return; App::wnd()->showLayer(new ContactsBox()); } void TitleWidget::onAbout() { if (App::wnd() && App::wnd()->isHidden()) App::wnd()->showFromTray(); App::wnd()->showLayer(new AboutBox()); } TitleWidget::~TitleWidget() { delete hider; hider = 0; } void TitleWidget::resizeEvent(QResizeEvent *e) { QPoint p(width() - ((cPlatform() == dbipWindows && lastMaximized) ? 0 : st::sysBtnDelta), 0); if (!_update.isHidden()) { p.setX(p.x() - _update.width()); _update.move(p); p.setX(p.x() + _update.width()); } if (cPlatform() == dbipWindows) { p.setX(p.x() - _close.width()); _close.move(p); p.setX(p.x() - _maximize.width()); _restore.move(p); _maximize.move(p); p.setX(p.x() - _minimize.width()); _minimize.move(p); } _settings.move(st::titleMenuOffset, 0); if (MTP::authedId()) { _contacts.show(); _contacts.move(_settings.x() + _settings.width(), 0); _about.move(_contacts.x() + _contacts.width(), 0); } else { _contacts.hide(); _about.move(_settings.x() + _settings.width(), 0); } if (hider) hider->resize(size()); } void TitleWidget::mousePressEvent(QMouseEvent *e) { if (wnd->psHandleTitle()) return; if (e->buttons() & Qt::LeftButton) { wnd->wStartDrag(e); e->accept(); } } void TitleWidget::mouseDoubleClickEvent(QMouseEvent *e) { if (wnd->psHandleTitle()) return; Qt::WindowStates s(wnd->windowState()); if (s.testFlag(Qt::WindowMaximized)) { wnd->setWindowState(s & ~Qt::WindowMaximized); } else { wnd->setWindowState(s | Qt::WindowMaximized); } } void TitleWidget::stateChanged(Qt::WindowState state) { if (state == Qt::WindowMinimized) return; maximizedChanged(state == Qt::WindowMaximized); } void TitleWidget::showUpdateBtn() { if (App::app()->updatingState() == Application::UpdatingReady || cEvalScale(cConfigScale()) != cEvalScale(cRealScale())) { _update.show(); _minimize.hide(); _restore.hide(); _maximize.hide(); _close.hide(); anim::start(this); } else { _update.hide(); if (cPlatform() == dbipWindows) { _minimize.show(); maximizedChanged(wnd->windowState().testFlag(Qt::WindowMaximized), true); _close.show(); } anim::stop(this); } resizeEvent(0); update(); } void TitleWidget::maximizedChanged(bool maximized, bool force) { if (lastMaximized == maximized && !force) return; lastMaximized = maximized; if (cPlatform() != dbipWindows || !_update.isHidden()) return; if (maximized) { _maximize.clearState(); } else { _restore.clearState(); } _maximize.setVisible(!maximized); _restore.setVisible(maximized); resizeEvent(0); } HitTestType TitleWidget::hitTest(const QPoint &p) { if (App::wnd() && App::wnd()->layerShown()) return HitTestNone; int x(p.x()), y(p.y()), w(width()), h(height() - st::titleShadow); if (hider && x >= App::main()->dlgsWidth()) return HitTestNone; if (x >= st::titleIconPos.x() && y >= st::titleIconPos.y() && x < st::titleIconPos.x() + st::titleIconRect.pxWidth() && y < st::titleIconPos.y() + st::titleIconRect.pxHeight()) { return HitTestIcon; } else if (false || (_update.hitTest(p - _update.geometry().topLeft()) == HitTestSysButton && _update.isVisible()) || (_minimize.hitTest(p - _minimize.geometry().topLeft()) == HitTestSysButton) || (_maximize.hitTest(p - _maximize.geometry().topLeft()) == HitTestSysButton) || (_restore.hitTest(p - _restore.geometry().topLeft()) == HitTestSysButton) || (_close.hitTest(p - _close.geometry().topLeft()) == HitTestSysButton) ) { return HitTestSysButton; } else if (x >= 0 && x < w && y >= 0 && y < h) { if (false || _settings.geometry().contains(x, y) || (!_contacts.isHidden() && _contacts.geometry().contains(x, y)) || _about.geometry().contains(x, y) ) { return HitTestClient; } return HitTestCaption; } return HitTestNone; }