dialogs optimizations, qt 5.5.0 xcode 7 build

This commit is contained in:
John Preston 2015-09-29 16:24:39 +03:00
parent d8b421993d
commit 94fe669c6e
16 changed files with 571 additions and 864 deletions

View File

@ -105,6 +105,10 @@ if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ]; then
fi
if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarget" == "macstore" ]; then
touch ./SourceFiles/telegram.qrc or exit 1
xcodebuild -project Telegram.xcodeproj -alltargets -configuration Release build or exit 1
if [ ! -d "$ReleasePath/$BinaryName.app" ]; then
echo "$BinaryName.app not found!"
exit 1

File diff suppressed because it is too large Load Diff

View File

@ -19,12 +19,12 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
class MainWidget;
class DialogsListWidget : public QWidget {
class DialogsInner : public SplittedWidget {
Q_OBJECT
public:
DialogsListWidget(QWidget *parent, MainWidget *main);
DialogsInner(QWidget *parent, MainWidget *main);
void dialogsReceived(const QVector<MTPDialog> &dialogs);
void addSavedPeersAfter(const QDateTime &date);
@ -42,15 +42,14 @@ public:
int32 peopleOffset() const;
int32 searchedOffset() const;
void paintEvent(QPaintEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mousePressEvent(QMouseEvent *e);
void resizeEvent(QResizeEvent *e);
void enterEvent(QEvent *e);
void leaveEvent(QEvent *e);
void peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool act, bool sel) const;
void searchInPeerPaint(Painter &p, int32 w) const;
void peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const;
void searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) const;
void selectSkip(int32 direction);
void selectSkipPage(int32 pixels, int32 direction);
@ -106,7 +105,7 @@ public:
PeerData *updateFromParentDrag(QPoint globalPos);
~DialogsListWidget();
~DialogsInner();
public slots:
@ -126,9 +125,14 @@ signals:
void completeHashtag(QString tag);
void refreshHashtags();
protected:
void paintRegion(Painter &p, const QRegion &region, bool paintingOther);
private:
void clearSearchResults(bool clearPeople = true);
void updateSelectedRow();
DialogsIndexed dialogs;
DialogsIndexed contactsNoDialogs;
@ -265,8 +269,8 @@ private:
FlatInput _filter;
IconedButton _newGroup, _addContact, _cancelSearch;
ScrollArea scroll;
DialogsListWidget list;
ScrollArea _scroll;
DialogsInner _inner;
QPixmap _animCache, _bgAnimCache;
anim::ivalue a_coord, a_bgCoord;

View File

@ -35,8 +35,7 @@ void ScrollShadow::changeVisibility(bool shown) {
setVisible(shown);
}
ScrollBar::ScrollBar(ScrollArea *parent, bool vert, const style::flatScroll *st) : QWidget(parent),
_area(parent), _st(st), _vertical(vert),
ScrollBar::ScrollBar(ScrollArea *parent, bool vert, const style::flatScroll *st) : QWidget(parent), _st(st), _vertical(vert),
_over(false), _overbar(false), _moving(false), _topSh(false), _bottomSh(false),
_connected(vert ? parent->verticalScrollBar() : parent->horizontalScrollBar()),
_scrollMax(_connected->maximum()), _hideIn(-1),
@ -54,11 +53,11 @@ ScrollBar::ScrollBar(ScrollArea *parent, bool vert, const style::flatScroll *st)
}
void ScrollBar::recountSize() {
setGeometry(_vertical ? QRect(rtl() ? 0 : (_area->width() - _st->width), _st->deltat, _st->width, _area->height() - _st->deltat - _st->deltab) : QRect(_st->deltat, _area->height() - _st->width, _area->width() - _st->deltat - _st->deltab, _st->width));
setGeometry(_vertical ? QRect(rtl() ? 0 : (area()->width() - _st->width), _st->deltat, _st->width, area()->height() - _st->deltat - _st->deltab) : QRect(_st->deltat, area()->height() - _st->width, area()->width() - _st->deltat - _st->deltab, _st->width));
}
void ScrollBar::onValueChanged() {
_area->onScrolled();
area()->onScrolled();
updateBar();
}
@ -67,11 +66,11 @@ void ScrollBar::updateBar(bool force) {
if (_connected->maximum() != _scrollMax) {
int32 oldMax = _scrollMax, newMax = _connected->maximum();
_scrollMax = newMax;
_area->rangeChanged(oldMax, newMax, _vertical);
area()->rangeChanged(oldMax, newMax, _vertical);
}
if (_vertical) {
int sh = _area->scrollHeight(), rh = height(), h = sh ? int32((rh * int64(_area->height())) / sh) : 0;
if (h >= rh || !_area->scrollTopMax() || rh < _st->minHeight) {
int sh = area()->scrollHeight(), rh = height(), h = sh ? int32((rh * int64(area()->height())) / sh) : 0;
if (h >= rh || !area()->scrollTopMax() || rh < _st->minHeight) {
if (!isHidden()) hide();
bool newTopSh = (_st->topsh < 0), newBottomSh = (_st->bottomsh < 0);
if (newTopSh != _topSh || force) emit topShadowVisibility(_topSh = newTopSh);
@ -80,29 +79,29 @@ void ScrollBar::updateBar(bool force) {
}
if (h <= _st->minHeight) h = _st->minHeight;
int stm = _area->scrollTopMax(), y = stm ? int32(((rh - h) * int64(_area->scrollTop())) / stm) : 0;
int stm = area()->scrollTopMax(), y = stm ? int32(((rh - h) * int64(area()->scrollTop())) / stm) : 0;
if (y > rh - h) y = rh - h;
newBar = QRect(_st->deltax, y, width() - 2 * _st->deltax, h);
} else {
int sw = _area->scrollWidth(), rw = width(), w = sw ? int32((rw * int64(_area->width())) / sw) : 0;
if (w >= rw || !_area->scrollLeftMax() || rw < _st->minHeight) {
int sw = area()->scrollWidth(), rw = width(), w = sw ? int32((rw * int64(area()->width())) / sw) : 0;
if (w >= rw || !area()->scrollLeftMax() || rw < _st->minHeight) {
if (!isHidden()) hide();
return;
}
if (w <= _st->minHeight) w = _st->minHeight;
int slm = _area->scrollLeftMax(), x = slm ? int32(((rw - w) * int64(_area->scrollLeft())) / slm) : 0;
int slm = area()->scrollLeftMax(), x = slm ? int32(((rw - w) * int64(area()->scrollLeft())) / slm) : 0;
if (x > rw - w) x = rw - w;
newBar = QRect(x, _st->deltax, w, height() - 2 * _st->deltax);
}
if (newBar != _bar) {
_bar = newBar;
update();// parentWidget()->update(geometry());
update();
}
if (_vertical) {
bool newTopSh = (_st->topsh < 0) || (_area->scrollTop() > _st->topsh), newBottomSh = (_st->bottomsh < 0) || (_area->scrollTop() < _area->scrollTopMax() - _st->bottomsh);
bool newTopSh = (_st->topsh < 0) || (area()->scrollTop() > _st->topsh), newBottomSh = (_st->bottomsh < 0) || (area()->scrollTop() < area()->scrollTopMax() - _st->bottomsh);
if (newTopSh != _topSh || force) emit topShadowVisibility(_topSh = newTopSh);
if (newBottomSh != _bottomSh || force) emit bottomShadowVisibility(_bottomSh = newBottomSh);
}
@ -116,6 +115,10 @@ void ScrollBar::onHideTimer() {
anim::start(this);
}
ScrollArea *ScrollBar::area() {
return static_cast<ScrollArea*>(parentWidget());
}
void ScrollBar::paintEvent(QPaintEvent *e) {
if (!_bar.width() && !_bar.height()) {
hide();
@ -200,10 +203,10 @@ void ScrollBar::mouseMoveEvent(QMouseEvent *e) {
}
}
if (_moving) {
int delta = 0, barDelta = _vertical ? (_area->height() - _bar.height()) : (_area->width() - _bar.width());
int delta = 0, barDelta = _vertical ? (area()->height() - _bar.height()) : (area()->width() - _bar.width());
if (barDelta > 0) {
QPoint d = (e->globalPos() - _dragStart);
delta = int32((_vertical ? (d.y() * int64(_area->scrollTopMax())) : (d.x() * int64(_area->scrollLeftMax()))) / barDelta);
delta = int32((_vertical ? (d.y() * int64(area()->scrollTopMax())) : (d.x() * int64(area()->scrollLeftMax()))) / barDelta);
}
_connected->setValue(_startFrom + delta);
}
@ -220,7 +223,7 @@ void ScrollBar::mousePressEvent(QMouseEvent *e) {
int32 val = _vertical ? e->pos().y() : e->pos().x(), div = _vertical ? height() : width();
val = (val <= _st->deltat) ? 0 : (val - _st->deltat);
div = (div <= _st->deltat + _st->deltab) ? 1 : (div - _st->deltat - _st->deltab);
_startFrom = _vertical ? int32((val * int64(_area->scrollTopMax())) / div) : ((val * int64(_area->scrollLeftMax())) / div);
_startFrom = _vertical ? int32((val * int64(area()->scrollTopMax())) / div) : ((val * int64(area()->scrollLeftMax())) / div);
_connected->setValue(_startFrom);
if (!_overbar) {
_overbar = true;
@ -229,7 +232,7 @@ void ScrollBar::mousePressEvent(QMouseEvent *e) {
anim::start(this);
}
}
emit _area->scrollStarted();
emit area()->scrollStarted();
}
void ScrollBar::mouseReleaseEvent(QMouseEvent *e) {
@ -252,7 +255,7 @@ void ScrollBar::mouseReleaseEvent(QMouseEvent *e) {
}
}
if (a) anim::start(this);
emit _area->scrollFinished();
emit area()->scrollFinished();
}
if (!_over) {
setMouseTracking(false);
@ -263,12 +266,53 @@ void ScrollBar::resizeEvent(QResizeEvent *e) {
updateBar();
}
void SplittedWidget::paintEvent(QPaintEvent *e) {
Painter p(this);
if (rtl()) {
p.translate(-otherWidth(), 0);
paintRegion(p, e->region().translated(otherWidth(), 0), false);
} else {
paintRegion(p, e->region(), false);
}
}
void SplittedWidget::update(const QRect &r) {
if (rtl()) {
TWidget::update(r.translated(-otherWidth(), 0).intersected(rect()));
emit updateOther(r);
} else {
TWidget::update(r.intersected(rect()));
emit updateOther(r.translated(-width(), 0));
}
}
void SplittedWidget::update(const QRegion &r) {
if (rtl()) {
TWidget::update(r.translated(-otherWidth(), 0).intersected(rect()));
emit updateOther(r);
} else {
TWidget::update(r.intersected(rect()));
emit updateOther(r.translated(-width(), 0));
}
}
void SplittedWidgetOther::paintEvent(QPaintEvent *e) {
Painter p(this);
SplittedWidget *s = static_cast<SplittedWidget*>(static_cast<ScrollArea*>(parentWidget())->widget());
if (rtl()) {
s->paintRegion(p, e->region(), true);
} else {
p.translate(-s->width(), 0);
s->paintRegion(p, e->region().translated(s->width(), 0), true);
}
}
ScrollArea::ScrollArea(QWidget *parent, const style::flatScroll &st, bool handleTouch) : QScrollArea(parent),
_disabled(false), _st(st),
hor(this, false, &_st), vert(this, true, &_st), topSh(this, &_st), bottomSh(this, &_st),
_touchEnabled(handleTouch), _touchScroll(false), _touchPress(false), _touchRightButton(false),
_touchScrollState(TouchScrollManual), _touchPrevPosValid(false), _touchWaitingAcceleration(false),
_touchSpeedTime(0), _touchAccelerationTime(0), _touchTime(0), _widgetAcceptsTouch(false) {
_touchSpeedTime(0), _touchAccelerationTime(0), _touchTime(0), _widgetAcceptsTouch(false), _other(0) {
setLayoutDirection(cLangDir());
connect(&vert, SIGNAL(topShadowVisibility(bool)), &topSh, SLOT(changeVisibility(bool)));
@ -581,6 +625,12 @@ void ScrollArea::resizeEvent(QResizeEvent *e) {
vert.recountSize();
topSh.setGeometry(QRect(0, 0, width(), qAbs(_st.topsh)));
bottomSh.setGeometry(QRect(0, height() - qAbs(_st.bottomsh), width(), qAbs(_st.bottomsh)));
if (SplittedWidget *w = qobject_cast<SplittedWidget*>(widget())) {
w->resize(width() - w->otherWidth(), w->height());
if (!rtl()) {
_other->move(w->width(), w->y());
}
}
emit geometryChanged();
}
@ -644,10 +694,22 @@ void ScrollArea::scrollToY(int toTop, int toBottom) {
}
void ScrollArea::setWidget(QWidget *w) {
SplittedWidget *splitted = qobject_cast<SplittedWidget*>(w);
if (widget() && _touchEnabled) {
widget()->removeEventFilter(this);
if (!_widgetAcceptsTouch) widget()->setAttribute(Qt::WA_AcceptTouchEvents, false);
}
if (_other && !splitted) {
delete _other;
_other = 0;
disconnect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onVerticalScroll()));
} else if (!_other && splitted) {
_other = new SplittedWidgetOther(this);
_other->setAttribute(Qt::WA_OpaquePaintEvent);
connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onVerticalScroll()));
hor.raise();
vert.raise();
}
QScrollArea::setWidget(w);
if (w) {
w->setAutoFillBackground(false);
@ -656,9 +718,43 @@ void ScrollArea::setWidget(QWidget *w) {
_widgetAcceptsTouch = w->testAttribute(Qt::WA_AcceptTouchEvents);
w->setAttribute(Qt::WA_AcceptTouchEvents);
}
if (splitted) {
splitted->setOtherWidth(vert.width());
w->resize(width() - splitted->otherWidth(), w->height());
connect(splitted, SIGNAL(resizeOther()), this, SLOT(onResizeOther()));
connect(splitted, SIGNAL(updateOther(const QRect&)), this, SLOT(onUpdateOther(const QRect&)));
connect(splitted, SIGNAL(updateOther(const QRegion&)), this, SLOT(onUpdateOther(const QRegion&)));
onResizeOther();
splitted->update();
}
}
}
QWidget *ScrollArea::takeWidget() {
if (_other) {
delete _other;
_other = 0;
disconnect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onVerticalScroll()));
}
return QScrollArea::takeWidget();
}
void ScrollArea::onResizeOther() {
_other->resize(_other->width(), widget()->height());
}
void ScrollArea::onUpdateOther(const QRect &r) {
_other->update(r.intersected(_other->rect()));
}
void ScrollArea::onUpdateOther(const QRegion &r) {
_other->update(r.intersected(_other->rect()));
}
void ScrollArea::onVerticalScroll() {
_other->move(_other->x(), widget()->y());
}
void ScrollArea::rangeChanged(int oldMax, int newMax, bool vertical) {
}

View File

@ -81,7 +81,7 @@ signals:
private:
ScrollArea *_area;
ScrollArea *area();
const style::flatScroll *_st;
bool _vertical;
@ -100,6 +100,62 @@ private:
QRect _bar;
};
class SplittedWidget : public TWidget {
Q_OBJECT
public:
SplittedWidget(QWidget *parent) : TWidget(parent), _otherWidth(0) {
setAttribute(Qt::WA_OpaquePaintEvent);
}
void paintEvent(QPaintEvent *e); // paintEvent done through paintRegion
void setHeight(int32 newHeight) {
resize(width(), newHeight);
emit resizeOther();
}
void update(int x, int y, int w, int h) {
update(QRect(x, y, w, h));
}
void update(const QRect&);
void update(const QRegion&);
public slots:
void update() {
update(0, 0, fullWidth(), height());
}
signals:
void resizeOther();
void updateOther(const QRect&);
void updateOther(const QRegion&);
protected:
int32 otherWidth() const {
return _otherWidth;
}
int32 fullWidth() const {
return width() + otherWidth();
}
virtual void paintRegion(Painter &p, const QRegion &region, bool paintingOther) = 0;
private:
int32 _otherWidth;
void setOtherWidth(int32 otherWidth) {
_otherWidth = otherWidth;
}
void resize(int32 w, int32 h) {
TWidget::resize(w, h);
}
friend class ScrollArea;
friend class SplittedWidgetOther;
};
class SplittedWidgetOther;
class ScrollArea : public QScrollArea {
Q_OBJECT
@ -127,6 +183,7 @@ public:
int scrollTop() const;
void setWidget(QWidget *widget);
QWidget *takeWidget();
void rangeChanged(int oldMax, int newMax, bool vertical);
@ -145,6 +202,11 @@ public slots:
void onTouchTimer();
void onTouchScrollTimer();
void onResizeOther();
void onUpdateOther(const QRect&);
void onUpdateOther(const QRegion&);
void onVerticalScroll();
signals:
void scrolled();
@ -192,4 +254,14 @@ private:
bool _widgetAcceptsTouch;
friend class SplittedWidgetOther;
SplittedWidgetOther *_other;
};
class SplittedWidgetOther : public TWidget {
public:
SplittedWidgetOther(ScrollArea *parent) : TWidget(parent) {
}
void paintEvent(QPaintEvent *e);
};

View File

@ -149,10 +149,11 @@ void stopGif() {
animated.stop();
}
void DialogRow::paint(Painter &p, int32 w, bool act, bool sel) const {
void DialogRow::paint(Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const {
QRect fullRect(0, 0, w, st::dlgHeight);
p.fillRect(fullRect, (act ? st::dlgActiveBG : (sel ? st::dlgHoverBG : st::dlgBG))->b);
if (onlyBackground) return;
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->photo->pix(st::dlgPhotoSize));
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding;
@ -240,10 +241,11 @@ void DialogRow::paint(Painter &p, int32 w, bool act, bool sel) const {
history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
}
void FakeDialogRow::paint(Painter &p, int32 w, bool act, bool sel) const {
void FakeDialogRow::paint(Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const {
QRect fullRect(0, 0, w, st::dlgHeight);
p.fillRect(fullRect, (act ? st::dlgActiveBG : (sel ? st::dlgHoverBG : st::dlgBG))->b);
if (onlyBackground) return;
History *history = _item->history();
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->photo->pix(st::dlgPhotoSize));

View File

@ -77,7 +77,7 @@ struct DialogRow {
DialogRow(History *history = 0, DialogRow *prev = 0, DialogRow *next = 0, int32 pos = 0) : prev(prev), next(next), history(history), pos(pos), attached(0) {
}
void paint(Painter &p, int32 w, bool act, bool sel) const;
void paint(Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const;
DialogRow *prev, *next;
History *history;
@ -89,7 +89,7 @@ struct FakeDialogRow {
FakeDialogRow(HistoryItem *item) : _item(item), _cacheFor(0), _cache(st::dlgRichMinWidth) {
}
void paint(Painter &p, int32 w, bool act, bool sel) const;
void paint(Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const;
HistoryItem *_item;
mutable const HistoryItem *_cacheFor;
@ -447,13 +447,13 @@ struct DialogsList {
}
}
void paint(Painter &p, int32 w, int32 hFrom, int32 hTo, PeerData *act, PeerData *sel) const {
void paint(Painter &p, int32 w, int32 hFrom, int32 hTo, PeerData *act, PeerData *sel, bool onlyBackground) const {
adjustCurrent(hFrom, st::dlgHeight);
DialogRow *drawFrom = current;
p.translate(0, drawFrom->pos * st::dlgHeight);
while (drawFrom != end && drawFrom->pos * st::dlgHeight < hTo) {
drawFrom->paint(p, w, (drawFrom->history->peer == act), (drawFrom->history->peer == sel));
drawFrom->paint(p, w, (drawFrom->history->peer == act), (drawFrom->history->peer == sel), onlyBackground);
drawFrom = drawFrom->next;
p.translate(0, st::dlgHeight);
}

View File

@ -34,7 +34,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
// flick scroll taken from http://qt-project.org/doc/qt-4.8/demos-embedded-anomaly-src-flickcharm-cpp.html
HistoryList::HistoryList(HistoryWidget *historyWidget, ScrollArea *scroll, History *history) : QWidget(0)
HistoryInner::HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, History *history) : QWidget(0)
, hist(history)
, ySkip(0)
, botInfo(history->peer->isUser() ? history->peer->asUser()->botInfo : 0)
@ -82,20 +82,20 @@ HistoryList::HistoryList(HistoryWidget *historyWidget, ScrollArea *scroll, Histo
setMouseTracking(true);
}
void HistoryList::messagesReceived(const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed) {
void HistoryInner::messagesReceived(const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed) {
hist->addOlderSlice(messages, collapsed);
}
void HistoryList::messagesReceivedDown(const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed) {
void HistoryInner::messagesReceivedDown(const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed) {
hist->addNewerSlice(messages, collapsed);
}
void HistoryList::updateMsg(const HistoryItem *msg) {
void HistoryInner::updateMsg(const HistoryItem *msg) {
if (!msg || msg->detached() || !hist || hist != msg->history()) return;
update(0, ySkip + msg->block()->y + msg->y, width(), msg->height());
}
void HistoryList::paintEvent(QPaintEvent *e) {
void HistoryInner::paintEvent(QPaintEvent *e) {
if (!App::main()) return;
QRect r(e->rect());
@ -174,7 +174,7 @@ void HistoryList::paintEvent(QPaintEvent *e) {
}
}
bool HistoryList::event(QEvent *e) {
bool HistoryInner::event(QEvent *e) {
if (e->type() == QEvent::TouchBegin || e->type() == QEvent::TouchUpdate || e->type() == QEvent::TouchEnd || e->type() == QEvent::TouchCancel) {
QTouchEvent *ev = static_cast<QTouchEvent*>(e);
if (ev->device()->type() == QTouchDevice::TouchScreen) {
@ -185,7 +185,7 @@ bool HistoryList::event(QEvent *e) {
return QWidget::event(e);
}
void HistoryList::onTouchScrollTimer() {
void HistoryInner::onTouchScrollTimer() {
uint64 nowTime = getms();
if (_touchScrollState == TouchScrollAcceleration && _touchWaitingAcceleration && (nowTime - _touchAccelerationTime) > 40) {
_touchScrollState = TouchScrollManual;
@ -206,7 +206,7 @@ void HistoryList::onTouchScrollTimer() {
}
}
void HistoryList::touchUpdateSpeed() {
void HistoryInner::touchUpdateSpeed() {
const uint64 nowTime = getms();
if (_touchPrevPosValid) {
const int elapsed = nowTime - _touchSpeedTime;
@ -245,19 +245,19 @@ void HistoryList::touchUpdateSpeed() {
_touchPrevPos = _touchPos;
}
void HistoryList::touchResetSpeed() {
void HistoryInner::touchResetSpeed() {
_touchSpeed = QPoint();
_touchPrevPosValid = false;
}
void HistoryList::touchDeaccelerate(int32 elapsed) {
void HistoryInner::touchDeaccelerate(int32 elapsed) {
int32 x = _touchSpeed.x();
int32 y = _touchSpeed.y();
_touchSpeed.setX((x == 0) ? x : (x > 0) ? qMax(0, x - elapsed) : qMin(0, x + elapsed));
_touchSpeed.setY((y == 0) ? y : (y > 0) ? qMax(0, y - elapsed) : qMin(0, y + elapsed));
}
void HistoryList::touchEvent(QTouchEvent *e) {
void HistoryInner::touchEvent(QTouchEvent *e) {
const Qt::TouchPointStates &states(e->touchPointStates());
if (e->type() == QEvent::TouchCancel) { // cancel
if (!_touchInProgress) return;
@ -353,31 +353,31 @@ void HistoryList::touchEvent(QTouchEvent *e) {
}
}
void HistoryList::mouseMoveEvent(QMouseEvent *e) {
void HistoryInner::mouseMoveEvent(QMouseEvent *e) {
if (!(e->buttons() & (Qt::LeftButton | Qt::MiddleButton)) && (textlnkDown() || _dragAction != NoDrag)) {
mouseReleaseEvent(e);
}
dragActionUpdate(e->globalPos());
}
void HistoryList::dragActionUpdate(const QPoint &screenPos) {
void HistoryInner::dragActionUpdate(const QPoint &screenPos) {
_dragPos = screenPos;
onUpdateSelected();
}
void HistoryList::touchScrollUpdated(const QPoint &screenPos) {
void HistoryInner::touchScrollUpdated(const QPoint &screenPos) {
_touchPos = screenPos;
historyWidget->touchScroll(_touchPos - _touchPrevPos);
touchUpdateSpeed();
}
QPoint HistoryList::mapMouseToItem(QPoint p, HistoryItem *item) {
QPoint HistoryInner::mapMouseToItem(QPoint p, HistoryItem *item) {
if (!item || item->detached()) return QPoint(0, 0);
p.setY(p.y() - (height() - hist->height - st::historyPadding) - item->block()->y - item->y);
return p;
}
void HistoryList::mousePressEvent(QMouseEvent *e) {
void HistoryInner::mousePressEvent(QMouseEvent *e) {
if (_menu) {
e->accept();
return; // ignore mouse press, that was hiding context menu
@ -385,7 +385,7 @@ void HistoryList::mousePressEvent(QMouseEvent *e) {
dragActionStart(e->globalPos(), e->button());
}
void HistoryList::dragActionStart(const QPoint &screenPos, Qt::MouseButton button) {
void HistoryInner::dragActionStart(const QPoint &screenPos, Qt::MouseButton button) {
dragActionUpdate(screenPos);
if (button != Qt::LeftButton) return;
@ -492,7 +492,7 @@ void HistoryList::dragActionStart(const QPoint &screenPos, Qt::MouseButton butto
}
}
void HistoryList::dragActionCancel() {
void HistoryInner::dragActionCancel() {
_dragItem = 0;
_dragAction = NoDrag;
_dragStartPos = QPoint(0, 0);
@ -501,7 +501,7 @@ void HistoryList::dragActionCancel() {
historyWidget->noSelectingScroll();
}
void HistoryList::onDragExec() {
void HistoryInner::onDragExec() {
if (_dragAction != Dragging) return;
bool uponSelected = false;
@ -589,7 +589,7 @@ void HistoryList::onDragExec() {
}
}
void HistoryList::itemRemoved(HistoryItem *item) {
void HistoryInner::itemRemoved(HistoryItem *item) {
SelectedItems::iterator i = _selected.find(item);
if (i != _selected.cend()) {
_selected.erase(i);
@ -609,7 +609,7 @@ void HistoryList::itemRemoved(HistoryItem *item) {
updateDragSelection(_dragSelFrom, _dragSelTo, _dragSelecting, true);
}
void HistoryList::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
void HistoryInner::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
if (_dragItem == oldItem) _dragItem = newItem;
SelectedItems::iterator i = _selected.find(oldItem);
@ -623,7 +623,7 @@ void HistoryList::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
if (_dragSelTo == oldItem) _dragSelTo = newItem;
}
void HistoryList::dragActionFinish(const QPoint &screenPos, Qt::MouseButton button) {
void HistoryInner::dragActionFinish(const QPoint &screenPos, Qt::MouseButton button) {
TextLinkPtr needClick;
dragActionUpdate(screenPos);
@ -712,14 +712,14 @@ void HistoryList::dragActionFinish(const QPoint &screenPos, Qt::MouseButton butt
historyWidget->updateTopBarSelection();
}
void HistoryList::mouseReleaseEvent(QMouseEvent *e) {
void HistoryInner::mouseReleaseEvent(QMouseEvent *e) {
dragActionFinish(e->globalPos(), e->button());
if (!rect().contains(e->pos())) {
leaveEvent(e);
}
}
void HistoryList::mouseDoubleClickEvent(QMouseEvent *e) {
void HistoryInner::mouseDoubleClickEvent(QMouseEvent *e) {
if (!hist) return;
if (((_dragAction == Selecting && !_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) || (_dragAction == NoDrag && (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel))) && _dragSelType == TextSelectLetters && _dragItem) {
@ -748,7 +748,7 @@ void HistoryList::mouseDoubleClickEvent(QMouseEvent *e) {
}
}
void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
if (_menu) {
_menu->deleteLater();
_menu = 0;
@ -929,34 +929,34 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
}
}
void HistoryList::onMenuDestroy(QObject *obj) {
void HistoryInner::onMenuDestroy(QObject *obj) {
if (_menu == obj) {
_menu = 0;
}
}
void HistoryList::copySelectedText() {
void HistoryInner::copySelectedText() {
QString sel = getSelectedText();
if (!sel.isEmpty()) {
QApplication::clipboard()->setText(sel);
}
}
void HistoryList::openContextUrl() {
void HistoryInner::openContextUrl() {
HistoryItem *was = App::hoveredLinkItem();
App::hoveredLinkItem(App::contextItem());
_contextMenuLnk->onClick(Qt::LeftButton);
App::hoveredLinkItem(was);
}
void HistoryList::copyContextUrl() {
void HistoryInner::copyContextUrl() {
QString enc = _contextMenuLnk->encoded();
if (!enc.isEmpty()) {
QApplication::clipboard()->setText(enc);
}
}
void HistoryList::saveContextImage() {
void HistoryInner::saveContextImage() {
PhotoLink *lnk = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
if (!lnk) return;
@ -971,7 +971,7 @@ void HistoryList::saveContextImage() {
}
}
void HistoryList::copyContextImage() {
void HistoryInner::copyContextImage() {
PhotoLink *lnk = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
if (!lnk) return;
@ -981,7 +981,7 @@ void HistoryList::copyContextImage() {
QApplication::clipboard()->setPixmap(photo->full->pix());
}
void HistoryList::cancelContextDownload() {
void HistoryInner::cancelContextDownload() {
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
@ -989,7 +989,7 @@ void HistoryList::cancelContextDownload() {
if (loader) loader->cancel();
}
void HistoryList::showContextInFolder() {
void HistoryInner::showContextInFolder() {
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
@ -997,7 +997,7 @@ void HistoryList::showContextInFolder() {
if (!already.isEmpty()) psShowInFolder(already);
}
void HistoryList::openContextFile() {
void HistoryInner::openContextFile() {
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
@ -1006,7 +1006,7 @@ void HistoryList::openContextFile() {
if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton);
}
void HistoryList::saveContextFile() {
void HistoryInner::saveContextFile() {
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
@ -1015,7 +1015,7 @@ void HistoryList::saveContextFile() {
if (lnkDocument) DocumentSaveLink::doSave(lnkDocument->document(), true);
}
void HistoryList::copyContextText() {
void HistoryInner::copyContextText() {
HistoryItem *item = App::contextItem();
if (item && item->type() != HistoryItemMsg) {
item = 0;
@ -1029,11 +1029,11 @@ void HistoryList::copyContextText() {
}
}
void HistoryList::resizeEvent(QResizeEvent *e) {
void HistoryInner::resizeEvent(QResizeEvent *e) {
onUpdateSelected();
}
QString HistoryList::getSelectedText() const {
QString HistoryInner::getSelectedText() const {
SelectedItems sel = _selected;
if (_dragAction == Selecting && _dragSelFrom && _dragSelTo) {
@ -1070,7 +1070,7 @@ QString HistoryList::getSelectedText() const {
return result;
}
void HistoryList::keyPressEvent(QKeyEvent *e) {
void HistoryInner::keyPressEvent(QKeyEvent *e) {
if (e->key() == Qt::Key_Escape) {
historyWidget->onListEscapePressed();
} else if (e == QKeySequence::Copy && !_selected.isEmpty()) {
@ -1086,7 +1086,7 @@ void HistoryList::keyPressEvent(QKeyEvent *e) {
}
}
int32 HistoryList::recountHeight(HistoryItem *resizedItem) {
int32 HistoryInner::recountHeight(HistoryItem *resizedItem) {
int32 st = hist->lastScrollTop;
int32 ph = scrollArea->height(), minadd = 0;
@ -1127,7 +1127,7 @@ int32 HistoryList::recountHeight(HistoryItem *resizedItem) {
return st + (newYSkip - wasYSkip);
}
void HistoryList::updateBotInfo(bool recount) {
void HistoryInner::updateBotInfo(bool recount) {
int32 newh = 0;
if (botInfo && !botInfo->description.isEmpty()) {
if (botInfo->text.isEmpty()) {
@ -1164,16 +1164,16 @@ void HistoryList::updateBotInfo(bool recount) {
}
}
bool HistoryList::wasSelectedText() const {
bool HistoryInner::wasSelectedText() const {
return _wasSelectedText;
}
void HistoryList::setFirstLoading(bool loading) {
void HistoryInner::setFirstLoading(bool loading) {
_firstLoading = loading;
update();
}
HistoryItem *HistoryList::atTopImportantMsg(int32 top, int32 height, int32 &bottomUnderScrollTop) const {
HistoryItem *HistoryInner::atTopImportantMsg(int32 top, int32 height, int32 &bottomUnderScrollTop) const {
if (hist->isEmpty()) return 0;
adjustCurrent(top);
@ -1205,7 +1205,7 @@ HistoryItem *HistoryList::atTopImportantMsg(int32 top, int32 height, int32 &bott
return 0;
}
void HistoryList::updateSize() {
void HistoryInner::updateSize() {
int32 ph = scrollArea->height(), minadd = 0;
int32 newYSkip = ph - (hist->height + st::historyPadding);
if (botInfo && !botInfo->text.isEmpty()) {
@ -1234,11 +1234,11 @@ void HistoryList::updateSize() {
}
}
void HistoryList::enterEvent(QEvent *e) {
void HistoryInner::enterEvent(QEvent *e) {
return QWidget::enterEvent(e);
}
void HistoryList::leaveEvent(QEvent *e) {
void HistoryInner::leaveEvent(QEvent *e) {
if (textlnkOver()) {
updateMsg(App::hoveredItem());
updateMsg(App::hoveredLinkItem());
@ -1253,12 +1253,12 @@ void HistoryList::leaveEvent(QEvent *e) {
return QWidget::leaveEvent(e);
}
HistoryList::~HistoryList() {
HistoryInner::~HistoryInner() {
delete _menu;
_dragAction = NoDrag;
}
void HistoryList::adjustCurrent(int32 y) const {
void HistoryInner::adjustCurrent(int32 y) const {
if (hist->isEmpty()) return;
if (currentBlock >= hist->blocks.size()) {
currentBlock = hist->blocks.size() - 1;
@ -1286,7 +1286,7 @@ void HistoryList::adjustCurrent(int32 y) const {
}
}
HistoryItem *HistoryList::prevItem(HistoryItem *item) {
HistoryItem *HistoryInner::prevItem(HistoryItem *item) {
if (!item) return 0;
HistoryBlock *block = item->block();
int32 blockIndex = hist->blocks.indexOf(block), itemIndex = block->items.indexOf(item);
@ -1300,7 +1300,7 @@ HistoryItem *HistoryList::prevItem(HistoryItem *item) {
return 0;
}
HistoryItem *HistoryList::nextItem(HistoryItem *item) {
HistoryItem *HistoryInner::nextItem(HistoryItem *item) {
if (!item) return 0;
HistoryBlock *block = item->block();
int32 blockIndex = hist->blocks.indexOf(block), itemIndex = block->items.indexOf(item);
@ -1314,18 +1314,18 @@ HistoryItem *HistoryList::nextItem(HistoryItem *item) {
return 0;
}
bool HistoryList::canCopySelected() const {
bool HistoryInner::canCopySelected() const {
return !_selected.isEmpty();
}
bool HistoryList::canDeleteSelected() const {
bool HistoryInner::canDeleteSelected() const {
if (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel) return false;
int32 selectedForForward, selectedForDelete;
getSelectionState(selectedForForward, selectedForDelete);
return (selectedForForward == selectedForDelete);
}
void HistoryList::getSelectionState(int32 &selectedForForward, int32 &selectedForDelete) const {
void HistoryInner::getSelectionState(int32 &selectedForForward, int32 &selectedForDelete) const {
selectedForForward = selectedForDelete = 0;
for (SelectedItems::const_iterator i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) {
if (i.key()->type() == HistoryItemMsg && i.value() == FullItemSel) {
@ -1340,7 +1340,7 @@ void HistoryList::getSelectionState(int32 &selectedForForward, int32 &selectedFo
}
}
void HistoryList::clearSelectedItems(bool onlyTextSelection) {
void HistoryInner::clearSelectedItems(bool onlyTextSelection) {
if (!_selected.isEmpty() && (!onlyTextSelection || _selected.cbegin().value() != FullItemSel)) {
_selected.clear();
historyWidget->updateTopBarSelection();
@ -1348,7 +1348,7 @@ void HistoryList::clearSelectedItems(bool onlyTextSelection) {
}
}
void HistoryList::fillSelectedItems(SelectedItemSet &sel, bool forDelete) {
void HistoryInner::fillSelectedItems(SelectedItemSet &sel, bool forDelete) {
if (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel) return;
for (SelectedItems::const_iterator i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) {
@ -1359,7 +1359,7 @@ void HistoryList::fillSelectedItems(SelectedItemSet &sel, bool forDelete) {
}
}
void HistoryList::selectItem(HistoryItem *item) {
void HistoryInner::selectItem(HistoryItem *item) {
if (!_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) {
_selected.clear();
} else if (_selected.size() == MaxSelectedItems && _selected.constFind(item) == _selected.cend()) {
@ -1370,12 +1370,12 @@ void HistoryList::selectItem(HistoryItem *item) {
historyWidget->update();
}
void HistoryList::onTouchSelect() {
void HistoryInner::onTouchSelect() {
_touchSelect = true;
dragActionStart(_touchPos);
}
void HistoryList::onUpdateSelected() {
void HistoryInner::onUpdateSelected() {
if (!hist) return;
QPoint mousePos(mapFromGlobal(_dragPos));
@ -1539,7 +1539,7 @@ void HistoryList::onUpdateSelected() {
}
}
void HistoryList::updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force) {
void HistoryInner::updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force) {
if (_dragSelFrom != dragSelFrom || _dragSelTo != dragSelTo || _dragSelecting != dragSelecting) {
_dragSelFrom = dragSelFrom;
_dragSelTo = dragSelTo;
@ -1558,11 +1558,11 @@ void HistoryList::updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dra
update();
}
void HistoryList::applyDragSelection() {
void HistoryInner::applyDragSelection() {
applyDragSelection(&_selected);
}
void HistoryList::applyDragSelection(SelectedItems *toItems) const {
void HistoryInner::applyDragSelection(SelectedItems *toItems) const {
if (!toItems->isEmpty() && toItems->cbegin().value() != FullItemSel) {
toItems->clear();
}
@ -1606,7 +1606,7 @@ void HistoryList::applyDragSelection(SelectedItems *toItems) const {
}
}
void HistoryList::showLinkTip() {
void HistoryInner::showLinkTip() {
TextLinkPtr lnk = textlnkOver();
int32 dd = QApplication::startDragDistance();
QPoint dp(mapFromGlobal(_dragPos));
@ -1620,7 +1620,7 @@ void HistoryList::showLinkTip() {
}
}
void HistoryList::onParentGeometryChanged() {
void HistoryInner::onParentGeometryChanged() {
bool needToUpdate = (_dragAction != NoDrag || _touchScroll || rect().contains(mapFromGlobal(QCursor::pos())));
if (needToUpdate) {
dragActionUpdate(QCursor::pos());
@ -2913,6 +2913,8 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) {
if (_history->unreadBar) {
_history->unreadBar->destroy();
}
App::main()->dlgUpdated(_history);
_history = 0;
}
@ -2933,9 +2935,6 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) {
_showAtMsgId = showAtMsgId;
_histInited = false;
if (_history) {
App::main()->dlgUpdated(_history);
}
_peer = peerId ? App::peer(peerId) : 0;
_channel = _peer ? peerToChannel(_peer->id) : NoChannel;
@ -2979,7 +2978,7 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) {
_history->lastWidth = 0;
}
_list = new HistoryList(this, &_scroll, _history);
_list = new HistoryInner(this, &_scroll, _history);
_list->hide();
_scroll.hide();
_scroll.setWidget(_list);

View File

@ -30,12 +30,12 @@ enum DragState {
};
class HistoryWidget;
class HistoryList : public QWidget {
class HistoryInner : public QWidget {
Q_OBJECT
public:
HistoryList(HistoryWidget *historyWidget, ScrollArea *scroll, History *history);
HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, History *history);
void messagesReceived(const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed);
void messagesReceivedDown(const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed);
@ -86,7 +86,7 @@ public:
HistoryItem *atTopImportantMsg(int32 top, int32 height, int32 &bottomUnderScrollTop) const;
~HistoryList();
~HistoryInner();
public slots:
@ -715,7 +715,7 @@ private:
MsgId _activeAnimMsgId;
ScrollArea _scroll;
HistoryList *_list;
HistoryInner *_list;
History *_history;
bool _histInited; // initial updateListSize() called

View File

@ -2661,7 +2661,7 @@ void MainWidget::onActiveChannelUpdateFull() {
void MainWidget::msgUpdated(PeerId peer, const HistoryItem *msg) {
if (!msg) return;
history.msgUpdated(peer, msg);
if (!msg->history()->dialogs.isEmpty()) dialogs.dlgUpdated(msg->history()->dialogs[0]);
if (!msg->history()->dialogs.isEmpty() && msg->history()->lastMsg == msg) dialogs.dlgUpdated(msg->history()->dialogs[0]);
if (overview) overview->msgUpdated(peer, msg);
}

View File

@ -357,7 +357,7 @@ void PsMainWindow::psFirstShow() {
namespace {
void _sendKeySequence(Qt::Key key, Qt::KeyboardModifiers modifiers = Qt::NoModifier) {
QWidget *focused = QApplication::focusWidget();
if (qobject_cast<QLineEdit*>(focused) || qobject_cast<FlatTextarea*>(focused) || qobject_cast<HistoryList*>(focused)) {
if (qobject_cast<QLineEdit*>(focused) || qobject_cast<FlatTextarea*>(focused) || qobject_cast<HistoryInner*>(focused)) {
QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyPress, key, modifiers));
QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyRelease, key, modifiers));
}
@ -429,7 +429,7 @@ void PsMainWindow::psMacUpdateMenu() {
canUndo = edit->isUndoAvailable();
canRedo = edit->isRedoAvailable();
canPaste = !App::app()->clipboard()->text().isEmpty();
} else if (HistoryList *list = qobject_cast<HistoryList*>(focused)) {
} else if (HistoryInner *list = qobject_cast<HistoryInner*>(focused)) {
canCopy = list->canCopySelected();
canDelete = list->canDeleteSelected();
}
@ -509,7 +509,7 @@ void PsMainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) {
bool PsMainWindow::eventFilter(QObject *obj, QEvent *evt) {
QEvent::Type t = evt->type();
if (t == QEvent::FocusIn || t == QEvent::FocusOut) {
if (qobject_cast<QLineEdit*>(obj) || qobject_cast<FlatTextarea*>(obj) || qobject_cast<HistoryList*>(obj)) {
if (qobject_cast<QLineEdit*>(obj) || qobject_cast<FlatTextarea*>(obj) || qobject_cast<HistoryInner*>(obj)) {
psMacUpdateMenu();
}
}

View File

@ -94,7 +94,7 @@ TitleWidget::TitleWidget(Window *window)
void TitleWidget::paintEvent(QPaintEvent *e) {
QPainter p(this);
LOG(("TITLE"));
p.fillRect(QRect(0, 0, width(), st::titleHeight), st::titleBG->b);
if (!_cancel.isHidden()) {
p.setPen(st::titleTextButton.color->p);

View File

@ -368,7 +368,7 @@ _connecting(0), _clearManager(0), dragging(false), _inactivePress(false), _shoul
setObjectName(qsl("MainWindow"));
}
resize(st::wndDefWidth, st::wndDefHeight);
setWindowOpacity(1);
setLocale(QLocale(QLocale::English, QLocale::UnitedStates));
centralwidget = new QWidget(this);
centralwidget->setObjectName(qsl("centralwidget"));
@ -388,6 +388,9 @@ _connecting(0), _clearManager(0), dragging(false), _inactivePress(false), _shoul
connect(this, SIGNAL(imageLoaded()), this, SLOT(update()));
connect(this, SIGNAL(imageLoaded()), this, SLOT(notifyUpdateAllPhotos()));
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_OpaquePaintEvent);
}
void Window::inactivePress(bool inactive) {

View File

@ -1,509 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QOBJECTDEFS_H
#define QOBJECTDEFS_H
#if defined(__OBJC__) && !defined(__cplusplus)
# warning "File built in Objective-C mode (.m), but using Qt requires Objective-C++ (.mm)"
#endif
#include <QtCore/qnamespace.h>
#include <QtCore/qobjectdefs_impl.h>
QT_BEGIN_NAMESPACE
class QByteArray;
struct QArrayData;
typedef QArrayData QByteArrayData;
class QString;
#ifndef Q_MOC_OUTPUT_REVISION
#define Q_MOC_OUTPUT_REVISION 67
#endif
// The following macros are our "extensions" to C++
// They are used, strictly speaking, only by the moc.
#ifndef Q_MOC_RUN
#ifndef QT_NO_META_MACROS
# if defined(QT_NO_KEYWORDS)
# define QT_NO_EMIT
# else
# ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS
# define slots
# define signals public
# endif
# endif
# define Q_SLOTS
# define Q_SIGNALS public
# define Q_PRIVATE_SLOT(d, signature)
# define Q_EMIT
#ifndef QT_NO_EMIT
# define emit
#endif
#define Q_CLASSINFO(name, value)
#define Q_PLUGIN_METADATA(x)
#define Q_INTERFACES(x)
#define Q_PROPERTY(text)
#define Q_PRIVATE_PROPERTY(d, text)
#define Q_REVISION(v)
#define Q_OVERRIDE(text)
#define Q_ENUMS(x)
#define Q_FLAGS(x)
#define Q_ENUM(ENUM) \
friend Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) Q_DECL_NOEXCEPT { return &staticMetaObject; } \
friend Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) Q_DECL_NOEXCEPT { return #ENUM; }
#define Q_FLAG(ENUM) Q_ENUM(ENUM)
#define Q_SCRIPTABLE
#define Q_INVOKABLE
#define Q_SIGNAL
#define Q_SLOT
#endif // QT_NO_META_MACROS
#ifndef QT_NO_TRANSLATION
// full set of tr functions
# define QT_TR_FUNCTIONS \
static inline QString tr(const char *s, const char *c = Q_NULLPTR, int n = -1) \
{ return staticMetaObject.tr(s, c, n); } \
QT_DEPRECATED static inline QString trUtf8(const char *s, const char *c = Q_NULLPTR, int n = -1) \
{ return staticMetaObject.tr(s, c, n); }
#else
// inherit the ones from QObject
# define QT_TR_FUNCTIONS
#endif
#if defined(QT_NO_QOBJECT_CHECK)
/* qmake ignore Q_OBJECT */
#define Q_OBJECT_CHECK
#else
/* This is a compile time check that ensures that any class cast with qobject_cast
actually contains a Q_OBJECT macro. Note: qobject_cast will fail if a QObject
subclass doesn't contain Q_OBJECT.
In qt_check_for_QOBJECT_macro, we call a dummy templated function with two
parameters, the first being "this" and the other the target of the qobject
cast. If the types are not identical, we know that a Q_OBJECT macro is missing.
If you get a compiler error here, make sure that the class you are casting
to contains a Q_OBJECT macro.
*/
/* qmake ignore Q_OBJECT */
#define Q_OBJECT_CHECK \
template <typename ThisObject> inline void qt_check_for_QOBJECT_macro(const ThisObject &_q_argument) const \
{ int i = qYouForgotTheQ_OBJECT_Macro(this, &_q_argument); i = i + 1; }
template <typename T>
inline int qYouForgotTheQ_OBJECT_Macro(T, T) { return 0; }
template <typename T1, typename T2>
inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {}
#endif // QT_NO_QOBJECT_CHECK
#if defined(Q_CC_INTEL)
// Cannot redefine the visibility of a method in an exported class
# define Q_DECL_HIDDEN_STATIC_METACALL
#else
# define Q_DECL_HIDDEN_STATIC_METACALL Q_DECL_HIDDEN
#endif
#if defined(Q_CC_CLANG) && (Q_CC_CLANG >= 306) && 0
# define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override")
#else
# define Q_OBJECT_NO_OVERRIDE_WARNING
#endif
/* qmake ignore Q_OBJECT */
#define Q_OBJECT \
public: \
Q_OBJECT_CHECK \
QT_WARNING_PUSH \
Q_OBJECT_NO_OVERRIDE_WARNING \
static const QMetaObject staticMetaObject; \
virtual const QMetaObject *metaObject() const; \
virtual void *qt_metacast(const char *); \
virtual int qt_metacall(QMetaObject::Call, int, void **); \
QT_WARNING_POP \
QT_TR_FUNCTIONS \
private: \
Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
struct QPrivateSignal {};
/* qmake ignore Q_OBJECT */
#define Q_OBJECT_FAKE Q_OBJECT
#ifndef QT_NO_META_MACROS
/* qmake ignore Q_GADGET */
#define Q_GADGET \
public: \
static const QMetaObject staticMetaObject; \
void qt_check_for_QGADGET_macro(); \
typedef void QtGadgetHelper; \
private: \
Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);
#endif // QT_NO_META_MACROS
#else // Q_MOC_RUN
#define slots slots
#define signals signals
#define Q_SLOTS Q_SLOTS
#define Q_SIGNALS Q_SIGNALS
#define Q_CLASSINFO(name, value) Q_CLASSINFO(name, value)
#define Q_INTERFACES(x) Q_INTERFACES(x)
#define Q_PROPERTY(text) Q_PROPERTY(text)
#define Q_PRIVATE_PROPERTY(d, text) Q_PRIVATE_PROPERTY(d, text)
#define Q_REVISION(v) Q_REVISION(v)
#define Q_OVERRIDE(text) Q_OVERRIDE(text)
#define Q_ENUMS(x) Q_ENUMS(x)
#define Q_FLAGS(x) Q_FLAGS(x)
#define Q_ENUM(x) Q_ENUM(x)
#define Q_FLAGS(x) Q_FLAGS(x)
/* qmake ignore Q_OBJECT */
#define Q_OBJECT Q_OBJECT
/* qmake ignore Q_OBJECT */
#define Q_OBJECT_FAKE Q_OBJECT_FAKE
/* qmake ignore Q_GADGET */
#define Q_GADGET Q_GADGET
#define Q_SCRIPTABLE Q_SCRIPTABLE
#define Q_INVOKABLE Q_INVOKABLE
#define Q_SIGNAL Q_SIGNAL
#define Q_SLOT Q_SLOT
#endif //Q_MOC_RUN
#ifndef QT_NO_META_MACROS
// macro for onaming members
#ifdef METHOD
#undef METHOD
#endif
#ifdef SLOT
#undef SLOT
#endif
#ifdef SIGNAL
#undef SIGNAL
#endif
#endif // QT_NO_META_MACROS
Q_CORE_EXPORT const char *qFlagLocation(const char *method);
#ifndef QT_NO_META_MACROS
#ifndef QT_NO_DEBUG
# define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__)
# ifndef QT_NO_KEYWORDS
# define METHOD(a) qFlagLocation("0"#a QLOCATION)
# endif
# define SLOT(a) qFlagLocation("1"#a QLOCATION)
# define SIGNAL(a) qFlagLocation("2"#a QLOCATION)
#else
# ifndef QT_NO_KEYWORDS
# define METHOD(a) "0"#a
# endif
# define SLOT(a) "1"#a
# define SIGNAL(a) "2"#a
#endif
#define QMETHOD_CODE 0 // member type codes
#define QSLOT_CODE 1
#define QSIGNAL_CODE 2
#endif // QT_NO_META_MACROS
#define Q_ARG(type, data) QArgument<type >(#type, data)
#define Q_RETURN_ARG(type, data) QReturnArgument<type >(#type, data)
class QObject;
class QMetaMethod;
class QMetaEnum;
class QMetaProperty;
class QMetaClassInfo;
class Q_CORE_EXPORT QGenericArgument
{
public:
inline QGenericArgument(const char *aName = 0, const void *aData = 0)
: _data(aData), _name(aName) {}
inline void *data() const { return const_cast<void *>(_data); }
inline const char *name() const { return _name; }
private:
const void *_data;
const char *_name;
};
class Q_CORE_EXPORT QGenericReturnArgument: public QGenericArgument
{
public:
inline QGenericReturnArgument(const char *aName = 0, void *aData = 0)
: QGenericArgument(aName, aData)
{}
};
template <class T>
class QArgument: public QGenericArgument
{
public:
inline QArgument(const char *aName, const T &aData)
: QGenericArgument(aName, static_cast<const void *>(&aData))
{}
};
template <class T>
class QArgument<T &>: public QGenericArgument
{
public:
inline QArgument(const char *aName, T &aData)
: QGenericArgument(aName, static_cast<const void *>(&aData))
{}
};
template <typename T>
class QReturnArgument: public QGenericReturnArgument
{
public:
inline QReturnArgument(const char *aName, T &aData)
: QGenericReturnArgument(aName, static_cast<void *>(&aData))
{}
};
struct Q_CORE_EXPORT QMetaObject
{
class Connection;
const char *className() const;
const QMetaObject *superClass() const;
QObject *cast(QObject *obj) const;
const QObject *cast(const QObject *obj) const;
#ifndef QT_NO_TRANSLATION
QString tr(const char *s, const char *c, int n = -1) const;
#endif // QT_NO_TRANSLATION
int methodOffset() const;
int enumeratorOffset() const;
int propertyOffset() const;
int classInfoOffset() const;
int constructorCount() const;
int methodCount() const;
int enumeratorCount() const;
int propertyCount() const;
int classInfoCount() const;
int indexOfConstructor(const char *constructor) const;
int indexOfMethod(const char *method) const;
int indexOfSignal(const char *signal) const;
int indexOfSlot(const char *slot) const;
int indexOfEnumerator(const char *name) const;
int indexOfProperty(const char *name) const;
int indexOfClassInfo(const char *name) const;
QMetaMethod constructor(int index) const;
QMetaMethod method(int index) const;
QMetaEnum enumerator(int index) const;
QMetaProperty property(int index) const;
QMetaClassInfo classInfo(int index) const;
QMetaProperty userProperty() const;
static bool checkConnectArgs(const char *signal, const char *method);
static bool checkConnectArgs(const QMetaMethod &signal,
const QMetaMethod &method);
static QByteArray normalizedSignature(const char *method);
static QByteArray normalizedType(const char *type);
// internal index-based connect
static Connection connect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index,
int type = 0, int *types = 0);
// internal index-based disconnect
static bool disconnect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index);
static bool disconnectOne(const QObject *sender, int signal_index,
const QObject *receiver, int method_index);
// internal slot-name based connect
static void connectSlotsByName(QObject *o);
// internal index-based signal activation
static void activate(QObject *sender, int signal_index, void **argv);
static void activate(QObject *sender, const QMetaObject *, int local_signal_index, void **argv);
static void activate(QObject *sender, int signal_offset, int local_signal_index, void **argv);
static bool invokeMethod(QObject *obj, const char *member,
Qt::ConnectionType,
QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(0),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument());
static inline bool invokeMethod(QObject *obj, const char *member,
QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(0),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument())
{
return invokeMethod(obj, member, Qt::AutoConnection, ret, val0, val1, val2, val3,
val4, val5, val6, val7, val8, val9);
}
static inline bool invokeMethod(QObject *obj, const char *member,
Qt::ConnectionType type,
QGenericArgument val0 = QGenericArgument(0),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument())
{
return invokeMethod(obj, member, type, QGenericReturnArgument(), val0, val1, val2,
val3, val4, val5, val6, val7, val8, val9);
}
static inline bool invokeMethod(QObject *obj, const char *member,
QGenericArgument val0 = QGenericArgument(0),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument())
{
return invokeMethod(obj, member, Qt::AutoConnection, QGenericReturnArgument(), val0,
val1, val2, val3, val4, val5, val6, val7, val8, val9);
}
QObject *newInstance(QGenericArgument val0 = QGenericArgument(0),
QGenericArgument val1 = QGenericArgument(),
QGenericArgument val2 = QGenericArgument(),
QGenericArgument val3 = QGenericArgument(),
QGenericArgument val4 = QGenericArgument(),
QGenericArgument val5 = QGenericArgument(),
QGenericArgument val6 = QGenericArgument(),
QGenericArgument val7 = QGenericArgument(),
QGenericArgument val8 = QGenericArgument(),
QGenericArgument val9 = QGenericArgument()) const;
enum Call {
InvokeMetaMethod,
ReadProperty,
WriteProperty,
ResetProperty,
QueryPropertyDesignable,
QueryPropertyScriptable,
QueryPropertyStored,
QueryPropertyEditable,
QueryPropertyUser,
CreateInstance,
IndexOfMethod,
RegisterPropertyMetaType,
RegisterMethodArgumentMetaType
};
int static_metacall(Call, int, void **) const;
static int metacall(QObject *, Call, int, void **);
struct { // private data
const QMetaObject *superdata;
const QByteArrayData *stringdata;
const uint *data;
typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
StaticMetacallFunction static_metacall;
const QMetaObject * const *relatedMetaObjects;
void *extradata; //reserved for future use
} d;
};
class Q_CORE_EXPORT QMetaObject::Connection {
void *d_ptr; //QObjectPrivate::Connection*
explicit Connection(void *data) : d_ptr(data) { }
friend class QObject;
friend class QObjectPrivate;
friend struct QMetaObject;
public:
~Connection();
Connection();
Connection(const Connection &other);
Connection &operator=(const Connection &other);
#ifdef Q_QDOC
operator bool() const;
#else
typedef void *Connection::*RestrictedBool;
operator RestrictedBool() const { return d_ptr ? &Connection::d_ptr : 0; }
#endif
#ifdef Q_COMPILER_RVALUE_REFS
inline Connection(Connection &&o) : d_ptr(o.d_ptr) { o.d_ptr = 0; }
inline Connection &operator=(Connection &&other)
{ qSwap(d_ptr, other.d_ptr); return *this; }
#endif
};
inline const QMetaObject *QMetaObject::superClass() const
{ return d.superdata; }
namespace QtPrivate {
/* Trait that tells is a the Object has a Q_OBJECT macro */
template <typename Object> struct HasQ_OBJECT_Macro {
template <typename T>
static char test(int (T::*)(QMetaObject::Call, int, void **));
static int test(int (Object::*)(QMetaObject::Call, int, void **));
enum { Value = sizeof(test(&Object::qt_metacall)) == sizeof(int) };
};
}
QT_END_NAMESPACE
#endif // QOBJECTDEFS_H

View File

@ -62,7 +62,7 @@ public:
private:
QImage m_qImage;
QSize m_requestedSize;
bool m_imageWasEqual;
bool m_qImageNeedsClear, m_imageWasEqual;
};
QT_END_NAMESPACE

View File

@ -38,7 +38,7 @@
QT_BEGIN_NAMESPACE
QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
: QPlatformBackingStore(window), m_imageWasEqual(false)
: QPlatformBackingStore(window), m_qImageNeedsClear(false), m_imageWasEqual(false)
{
}
@ -57,9 +57,10 @@ QPaintDevice *QCocoaBackingStore::paintDevice()
if (m_qImage.size() != effectiveBufferSize) {
QImage::Format format = (window()->format().hasAlpha() || cocoaWindow->m_drawContentBorderGradient)
? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
m_qImageNeedsClear = window()->requestedFormat().hasAlpha() || cocoaWindow->m_drawContentBorderGradient;
m_qImage = QImage(effectiveBufferSize, format);
m_qImage.setDevicePixelRatio(windowDevicePixelRatio);
if (format == QImage::Format_ARGB32_Premultiplied)
if (m_qImageNeedsClear)
m_qImage.fill(Qt::transparent);
}
return &m_qImage;
@ -98,7 +99,7 @@ bool QCocoaBackingStore::scroll(const QRegion &area, int dx, int dy)
void QCocoaBackingStore::beginPaint(const QRegion &region)
{
if (m_qImage.hasAlphaChannel()) {
if (m_qImageNeedsClear && m_qImage.hasAlphaChannel()) {
QPainter p(&m_qImage);
p.setCompositionMode(QPainter::CompositionMode_Source);
const QVector<QRect> rects = region.rects();