 7fa274a68e
			
		
	
	
		7fa274a68e
		
	
	
	
	
		
			
			Also moved FlatLabel and LabelSimple to ui/widgets/labels module. Also moved ScrollArea to ui/widgets/scroll_area module.
		
			
				
	
	
		
			191 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			191 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| 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 "boxes/abstractbox.h"
 | |
| 
 | |
| #include "styles/style_boxes.h"
 | |
| #include "localstorage.h"
 | |
| #include "lang.h"
 | |
| #include "ui/widgets/buttons.h"
 | |
| #include "ui/widgets/scroll_area.h"
 | |
| #include "mainwidget.h"
 | |
| #include "mainwindow.h"
 | |
| 
 | |
| AbstractBox::AbstractBox(int w) : LayerWidget(App::wnd()->bodyWidget()) {
 | |
| 	setAttribute(Qt::WA_OpaquePaintEvent);
 | |
| 	resize((w > 0) ? w : st::boxWideWidth, 0);
 | |
| }
 | |
| 
 | |
| void AbstractBox::prepare() {
 | |
| 	raiseShadow();
 | |
| 	showAll();
 | |
| }
 | |
| 
 | |
| void AbstractBox::keyPressEvent(QKeyEvent *e) {
 | |
| 	if (e->key() == Qt::Key_Escape) {
 | |
| 		onClose();
 | |
| 	} else {
 | |
| 		LayerWidget::keyPressEvent(e);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void AbstractBox::resizeEvent(QResizeEvent *e) {
 | |
| 	if (_blockClose) {
 | |
| 		_blockClose->moveToRight(0, 0);
 | |
| 	}
 | |
| 	if (_blockShadow) {
 | |
| 		_blockShadow->setGeometry(0, st::boxBlockTitleHeight, width(), st::boxBlockTitleShadow.height());
 | |
| 	}
 | |
| 	LayerWidget::resizeEvent(e);
 | |
| }
 | |
| 
 | |
| void AbstractBox::parentResized() {
 | |
| 	auto newHeight = countHeight();
 | |
| 	auto parentSize = parentWidget()->size();
 | |
| 	setGeometry((parentSize.width() - width()) / 2, (parentSize.height() - newHeight) / 2, width(), newHeight);
 | |
| 	update();
 | |
| }
 | |
| 
 | |
| bool AbstractBox::paint(QPainter &p) {
 | |
| 	p.fillRect(rect(), st::boxBg);
 | |
| 	return false;
 | |
| }
 | |
| 
 | |
| int AbstractBox::titleHeight() const {
 | |
| 	return _blockTitle ? st::boxBlockTitleHeight : st::boxTitleHeight;
 | |
| }
 | |
| 
 | |
| void AbstractBox::paintTitle(Painter &p, const QString &title, const QString &additional) {
 | |
| 	if (_blockTitle) {
 | |
| 		p.fillRect(0, 0, width(), titleHeight(), st::boxBlockTitleBg);
 | |
| 
 | |
| 		p.setFont(st::boxBlockTitleFont);
 | |
| 		p.setPen(st::boxBlockTitleFg);
 | |
| 
 | |
| 		auto titleWidth = st::boxBlockTitleFont->width(title);
 | |
| 		p.drawTextLeft(st::boxBlockTitlePosition.x(), st::boxBlockTitlePosition.y(), width(), title, titleWidth);
 | |
| 
 | |
| 		if (!additional.isEmpty()) {
 | |
| 			p.setFont(st::boxBlockTitleAdditionalFont);
 | |
| 			p.setPen(st::boxBlockTitleAdditionalFg);
 | |
| 			p.drawTextLeft(st::boxBlockTitlePosition.x() + titleWidth + st::boxBlockTitleAdditionalSkip, st::boxBlockTitlePosition.y(), width(), additional);
 | |
| 		}
 | |
| 	} else {
 | |
| 		p.setFont(st::boxTitleFont);
 | |
| 		p.setPen(st::boxTitleFg);
 | |
| 		p.drawTextLeft(st::boxTitlePosition.x(), st::boxTitlePosition.y(), width(), title);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 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) {
 | |
| 		QRect g(geometry());
 | |
| 		_maxHeight = maxHeight;
 | |
| 		resize(newWidth, countHeight());
 | |
| 		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);
 | |
| 				}
 | |
| 			}
 | |
| 			parentWidget()->update(geometry().united(g).marginsAdded(QMargins(st::boxShadow.width(), st::boxShadow.height(), st::boxShadow.width(), st::boxShadow.height())));
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int AbstractBox::countHeight() const {
 | |
| 	return qMin(_maxHeight, parentWidget()->height() - 2 * st::boxVerticalMargin);
 | |
| }
 | |
| 
 | |
| void AbstractBox::onClose() {
 | |
| 	if (!_closed) {
 | |
| 		_closed = true;
 | |
| 		closePressed();
 | |
| 	}
 | |
| 	emit closed(this);
 | |
| }
 | |
| 
 | |
| void AbstractBox::setBlockTitle(bool block) {
 | |
| 	_blockTitle = block;
 | |
| 	_blockShadow.create(this, st::boxBlockTitleShadow);
 | |
| 	_blockClose.create(this, st::boxBlockTitleClose);
 | |
| 	_blockClose->setClickedCallback([this] { onClose(); });
 | |
| }
 | |
| 
 | |
| void AbstractBox::raiseShadow() {
 | |
| 	if (_blockShadow) {
 | |
| 		_blockShadow->raise();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| ScrollableBoxShadow::ScrollableBoxShadow(QWidget *parent) : Ui::PlainShadow(parent, st::boxScrollShadowBg) {
 | |
| }
 | |
| 
 | |
| ScrollableBox::ScrollableBox(const style::FlatScroll &scroll, int32 w) : AbstractBox(w)
 | |
| , _scroll(this, scroll)
 | |
| , _topSkip(st::boxBlockTitleHeight)
 | |
| , _bottomSkip(st::boxScrollSkip) {
 | |
| 	setBlockTitle(true);
 | |
| }
 | |
| 
 | |
| void ScrollableBox::resizeEvent(QResizeEvent *e) {
 | |
| 	updateScrollGeometry();
 | |
| 	AbstractBox::resizeEvent(e);
 | |
| }
 | |
| 
 | |
| void ScrollableBox::init(TWidget *inner, int bottomSkip, int topSkip) {
 | |
| 	if (bottomSkip < 0) bottomSkip = st::boxScrollSkip;
 | |
| 	if (topSkip < 0) topSkip = st::boxBlockTitleHeight;
 | |
| 	_bottomSkip = bottomSkip;
 | |
| 	_topSkip = topSkip;
 | |
| 	_scroll->setOwnedWidget(inner);
 | |
| 	updateScrollGeometry();
 | |
| }
 | |
| 
 | |
| void ScrollableBox::setScrollSkips(int bottomSkip, int topSkip) {
 | |
| 	if (bottomSkip < 0) bottomSkip = st::boxScrollSkip;
 | |
| 	if (topSkip < 0) topSkip = st::boxBlockTitleHeight;
 | |
| 	if (_topSkip != topSkip || _bottomSkip != bottomSkip) {
 | |
| 		_topSkip = topSkip;
 | |
| 		_bottomSkip = bottomSkip;
 | |
| 		updateScrollGeometry();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void ScrollableBox::updateScrollGeometry() {
 | |
| 	_scroll->setGeometry(0, _topSkip, width(), height() - _topSkip - _bottomSkip);
 | |
| }
 | |
| 
 | |
| ItemListBox::ItemListBox(const style::FlatScroll &scroll, int32 w) : ScrollableBox(scroll, w) {
 | |
| 	setMaxHeight(st::boxMaxListHeight);
 | |
| }
 |