tdesktop/Telegram/SourceFiles/boxes/abstractbox.cpp

223 lines
6.6 KiB
C++
Raw Normal View History

/*
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.
2015-10-03 13:16:42 +00:00
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
2016-02-08 10:56:18 +00:00
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#include "stdafx.h"
#include "lang.h"
#include "localstorage.h"
#include "abstractbox.h"
#include "mainwidget.h"
#include "mainwindow.h"
2015-10-11 08:37:24 +00:00
void BlueTitleShadow::paintEvent(QPaintEvent *e) {
Painter p(this);
QRect r(e->rect());
p.drawPixmap(QRect(r.left(), 0, r.width(), height()), App::sprite(), st::boxBlueShadow.rect());
2015-10-11 08:37:24 +00:00
}
BlueTitleClose::BlueTitleClose(QWidget *parent) : Button(parent)
, a_iconFg(st::boxBlueCloseBg->c)
2015-12-08 12:33:37 +00:00
, _a_over(animation(this, &BlueTitleClose::step_over)) {
2015-10-11 08:37:24 +00:00
resize(st::boxTitleHeight, st::boxTitleHeight);
setCursor(style::cur_pointer);
connect(this, SIGNAL(stateChanged(int, ButtonStateChangeSource)), this, SLOT(onStateChange(int, ButtonStateChangeSource)));
}
void BlueTitleClose::onStateChange(int oldState, ButtonStateChangeSource source) {
if ((oldState & StateOver) != (_state & StateOver)) {
a_iconFg.start(((_state & StateOver) ? st::white : st::boxBlueCloseBg)->c);
_a_over.start();
}
}
2015-12-08 12:33:37 +00:00
void BlueTitleClose::step_over(float64 ms, bool timer) {
2015-10-11 08:37:24 +00:00
float64 dt = ms / st::boxBlueCloseDuration;
if (dt >= 1) {
2015-12-08 12:33:37 +00:00
_a_over.stop();
2015-10-11 08:37:24 +00:00
a_iconFg.finish();
} else {
a_iconFg.update(dt, anim::linear);
}
2015-12-08 12:33:37 +00:00
if (timer) update((st::boxTitleHeight - st::boxBlueCloseIcon.pxWidth()) / 2, (st::boxTitleHeight - st::boxBlueCloseIcon.pxHeight()) / 2, st::boxBlueCloseIcon.pxWidth(), st::boxBlueCloseIcon.pxHeight());
2015-10-11 08:37:24 +00:00
}
void BlueTitleClose::paintEvent(QPaintEvent *e) {
Painter p(this);
QRect r(e->rect()), s((st::boxTitleHeight - st::boxBlueCloseIcon.pxWidth()) / 2, (st::boxTitleHeight - st::boxBlueCloseIcon.pxHeight()) / 2, st::boxBlueCloseIcon.pxWidth(), st::boxBlueCloseIcon.pxHeight());
if (!s.contains(r)) {
p.fillRect(r, st::boxBlueTitleBg->b);
}
if (s.intersects(r)) {
p.fillRect(s.intersected(r), a_iconFg.current());
p.drawSprite(s.topLeft(), st::boxBlueCloseIcon);
}
}
AbstractBox::AbstractBox(int32 w) : LayerWidget()
2015-10-11 08:37:24 +00:00
, _maxHeight(0)
, _closed(false)
2015-10-11 08:37:24 +00:00
, _blueTitle(false)
, _blueClose(0)
, _blueShadow(0) {
setAttribute(Qt::WA_OpaquePaintEvent);
2015-10-03 10:09:09 +00:00
resize(w, 0);
}
void AbstractBox::prepare() {
showAll();
}
void AbstractBox::keyPressEvent(QKeyEvent *e) {
if (e->key() == Qt::Key_Escape) {
onClose();
} else {
LayerWidget::keyPressEvent(e);
}
}
2015-10-11 08:37:24 +00:00
void AbstractBox::resizeEvent(QResizeEvent *e) {
if (_blueClose) {
_blueClose->moveToRight(0, 0);
}
if (_blueShadow) {
_blueShadow->moveToLeft(0, st::boxTitleHeight);
_blueShadow->resize(width(), st::boxBlueShadow.pxHeight());
}
LayerWidget::resizeEvent(e);
2015-10-11 08:37:24 +00:00
}
void AbstractBox::parentResized() {
int32 newHeight = countHeight();
setGeometry((App::wnd()->width() - width()) / 2, (App::wnd()->height() - newHeight) / 2, width(), newHeight);
update();
}
bool AbstractBox::paint(QPainter &p) {
p.fillRect(rect(), st::boxBg);
return false;
}
2015-10-11 08:37:24 +00:00
void AbstractBox::paintTitle(Painter &p, const QString &title, const QString &additional) {
2015-10-06 19:49:23 +00:00
p.setFont(st::boxTitleFont);
2015-10-11 08:37:24 +00:00
if (_blueTitle) {
p.fillRect(0, 0, width(), st::boxTitleHeight, st::boxBlueTitleBg->b);
p.setPen(st::white);
2015-10-06 19:49:23 +00:00
2015-10-11 08:37:24 +00:00
int32 titleWidth = st::boxTitleFont->width(title);
p.drawTextLeft(st::boxBlueTitlePosition.x(), st::boxBlueTitlePosition.y(), width(), title, titleWidth);
2015-10-06 19:49:23 +00:00
2015-10-11 08:37:24 +00:00
if (!additional.isEmpty()) {
p.setFont(st::boxTextFont);
p.setPen(st::boxBlueTitleAdditionalFg);
p.drawTextLeft(st::boxBlueTitlePosition.x() + titleWidth + st::boxBlueTitleAdditionalSkip, st::boxBlueTitlePosition.y(), width(), additional);
}
} else {
p.setPen(st::boxTitleFg);
p.drawTextLeft(st::boxTitlePosition.x(), st::boxTitlePosition.y(), width(), title);
2015-10-06 19:49:23 +00:00
}
}
void AbstractBox::paintEvent(QPaintEvent *e) {
QPainter p(this);
if (paint(p)) return;
}
void AbstractBox::setMaxHeight(int32 maxHeight) {
resizeMaxHeight(width(), maxHeight);
}
void AbstractBox::resizeMaxHeight(int32 newWidth, int32 maxHeight) {
if (width() != newWidth || _maxHeight != maxHeight) {
2015-04-19 10:29:19 +00:00
QRect g(geometry());
_maxHeight = maxHeight;
resize(newWidth, countHeight());
2015-10-12 21:02:10 +00:00
if (parentWidget()) {
QRect r = geometry();
int32 parenth = parentWidget()->height();
if (r.top() + r.height() + st::boxVerticalMargin > parenth) {
int32 newTop = qMax(parenth - int(st::boxVerticalMargin) - r.height(), (parenth - r.height()) / 2);
if (newTop != r.top()) {
move(r.left(), newTop);
}
}
2015-10-12 21:02:10 +00:00
parentWidget()->update(geometry().united(g).marginsAdded(QMargins(st::boxShadow.pxWidth(), st::boxShadow.pxHeight(), st::boxShadow.pxWidth(), st::boxShadow.pxHeight())));
}
}
}
int32 AbstractBox::countHeight() const {
return qMin(_maxHeight, App::wnd()->height() - int32(2 * st::boxVerticalMargin));
}
void AbstractBox::onClose() {
if (!_closed) {
_closed = true;
closePressed();
}
emit closed(this);
}
2015-10-11 08:37:24 +00:00
void AbstractBox::setBlueTitle(bool blue) {
_blueTitle = blue;
delete _blueShadow;
_blueShadow = new BlueTitleShadow(this);
delete _blueClose;
_blueClose = new BlueTitleClose(this);
_blueClose->setAttribute(Qt::WA_OpaquePaintEvent);
connect(_blueClose, SIGNAL(clicked()), this, SLOT(onClose()));
}
void AbstractBox::raiseShadow() {
if (_blueShadow) {
_blueShadow->raise();
}
}
ScrollableBox::ScrollableBox(const style::flatScroll &scroll, int32 w) : AbstractBox(w),
_scroll(this, scroll), _innerPtr(0), _topSkip(st::boxTitleHeight), _bottomSkip(st::boxScrollSkip) {
setBlueTitle(true);
}
void ScrollableBox::resizeEvent(QResizeEvent *e) {
_scroll.setGeometry(0, _topSkip, width(), height() - _topSkip - _bottomSkip);
2015-10-11 08:37:24 +00:00
AbstractBox::resizeEvent(e);
}
void ScrollableBox::init(QWidget *inner, int32 bottomSkip, int32 topSkip) {
_bottomSkip = bottomSkip;
_topSkip = topSkip;
_innerPtr = inner;
_scroll.setWidget(_innerPtr);
_scroll.setFocusPolicy(Qt::NoFocus);
ScrollableBox::resizeEvent(0);
}
void ScrollableBox::showAll() {
_scroll.show();
2015-10-11 08:37:24 +00:00
AbstractBox::showAll();
}
2015-10-11 08:37:24 +00:00
ItemListBox::ItemListBox(const style::flatScroll &scroll, int32 w) : ScrollableBox(scroll, w) {
setMaxHeight(st::boxMaxListHeight);
}