Profile members block displayed when mouse is over group members count.

This commit is contained in:
John Preston 2016-06-17 21:18:01 +03:00
parent 963000386f
commit f0a8356ff0
20 changed files with 532 additions and 68 deletions

View File

@ -1019,11 +1019,11 @@ void EmojiPanInner::leaveEvent(QEvent *e) {
clearSelection();
}
void EmojiPanInner::leaveToChildEvent(QEvent *e) {
void EmojiPanInner::leaveToChildEvent(QEvent *e, QWidget *child) {
clearSelection();
}
void EmojiPanInner::enterFromChildEvent(QEvent *e) {
void EmojiPanInner::enterFromChildEvent(QEvent *e, QWidget *child) {
_lastMousePos = QCursor::pos();
updateSelected();
}
@ -1544,11 +1544,11 @@ void StickerPanInner::leaveEvent(QEvent *e) {
clearSelection();
}
void StickerPanInner::leaveToChildEvent(QEvent *e) {
void StickerPanInner::leaveToChildEvent(QEvent *e, QWidget *child) {
clearSelection();
}
void StickerPanInner::enterFromChildEvent(QEvent *e) {
void StickerPanInner::enterFromChildEvent(QEvent *e, QWidget *child) {
_lastMousePos = QCursor::pos();
updateSelected();
}
@ -3139,7 +3139,7 @@ void EmojiPan::onRefreshPanels() {
}
}
void EmojiPan::leaveToChildEvent(QEvent *e) {
void EmojiPan::leaveToChildEvent(QEvent *e, QWidget *child) {
if (!_stickersShown) return;
_iconsMousePos = QCursor::pos();
updateSelected();

View File

@ -254,14 +254,14 @@ public:
EmojiPanInner();
void setMaxHeight(int32 h);
void paintEvent(QPaintEvent *e);
void paintEvent(QPaintEvent *e) override;
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void leaveEvent(QEvent *e);
void leaveToChildEvent(QEvent *e);
void enterFromChildEvent(QEvent *e);
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void leaveEvent(QEvent *e) override;
void leaveToChildEvent(QEvent *e, QWidget *child) override;
void enterFromChildEvent(QEvent *e, QWidget *child) override;
void step_selected(uint64 ms, bool timer);
void hideFinish();
@ -346,14 +346,14 @@ public:
StickerPanInner();
void setMaxHeight(int32 h);
void paintEvent(QPaintEvent *e);
void paintEvent(QPaintEvent *e) override;
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void leaveEvent(QEvent *e);
void leaveToChildEvent(QEvent *e);
void enterFromChildEvent(QEvent *e);
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void leaveEvent(QEvent *e) override;
void leaveToChildEvent(QEvent *e, QWidget *child) override;
void enterFromChildEvent(QEvent *e, QWidget *child) override;
void step_selected(uint64 ms, bool timer);
@ -663,7 +663,7 @@ private:
bool _horizontal;
void updateContentHeight();
void leaveToChildEvent(QEvent *e);
void leaveToChildEvent(QEvent *e, QWidget *child);
void hideAnimated();
void prepareShowHideCache();

View File

@ -28,9 +28,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "ui/filedialog.h"
#include "ui/toast/toast.h"
#include "ui/buttons/history_down_button.h"
#include "ui/inner_dropdown.h"
#include "inline_bots/inline_bot_result.h"
#include "data/data_drafts.h"
#include "history/history_service_layout.h"
#include "profile/profile_members_widget.h"
#include "lang.h"
#include "application.h"
#include "mainwidget.h"
@ -5442,7 +5444,7 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
if (startAnim) _a_record.start();
}
void HistoryWidget::leaveToChildEvent(QEvent *e) { // e -- from enterEvent() of child TWidget
void HistoryWidget::leaveToChildEvent(QEvent *e, QWidget *child) { // e -- from enterEvent() of child TWidget
if (hasMouseTracking()) mouseMoveEvent(0);
}
@ -6009,6 +6011,37 @@ void HistoryWidget::paintTopBar(Painter &p, float64 over, int32 decreaseWidth) {
}
}
QRect HistoryWidget::getMembersShowAreaGeometry() const {
int increaseLeft = Adaptive::OneColumn() ? (st::topBarForwardPadding.right() - st::topBarForwardPadding.left()) : 0;
int membersTextLeft = st::topBarForwardPadding.left() + increaseLeft;
int membersTextTop = st::topBarHeight - st::topBarForwardPadding.bottom() - st::dialogsTextFont->height - st::topBarForwardPadding.bottom();
int membersTextWidth = _titlePeerTextWidth;
int membersTextHeight = st::topBarHeight - membersTextTop;
membersTextLeft -= st::topBarForwardPadding.left();
membersTextWidth += 2 * st::topBarForwardPadding.left();
return rtlrect(membersTextLeft, membersTextTop, membersTextWidth, membersTextHeight, width());
}
void HistoryWidget::setMembersShowAreaActive(bool active) {
if (active && _peer && (_peer->isChat() || _peer->isMegagroup())) {
if (!_membersDropdown) {
_membersDropdown = new Ui::InnerDropdown(this, st::dropdownDef, st::solidScroll);
_membersDropdown->setOwnedWidget(new Profile::MembersWidget(_membersDropdown, _peer, Profile::MembersWidget::TitleVisibility::Hidden));
_membersDropdown->setGeometry(0, 0, st::emojiPanWidth, st::emojiPanMaxHeight);
connect(_membersDropdown, SIGNAL(hidden()), this, SLOT(onMembersDropdownHidden()));
}
_membersDropdown->otherEnter();
} else if (_membersDropdown) {
_membersDropdown->otherLeave();
}
}
void HistoryWidget::onMembersDropdownHidden() {
_membersDropdown.destroyDelayed();
}
void HistoryWidget::topBarClick() {
if (Adaptive::OneColumn()) {
Ui::showChatsList();
@ -6074,6 +6107,7 @@ void HistoryWidget::updateOnlineDisplay(int32 x, int32 w) {
_titlePeerTextOnline = titlePeerTextOnline;
_titlePeerTextWidth = st::dialogsTextFont->width(_titlePeerText);
if (App::main()) {
App::main()->topBar()->updateMembersShowArea();
App::main()->topBar()->update();
}
}
@ -7263,6 +7297,9 @@ bool HistoryWidget::pinnedMsgVisibilityUpdated() {
connect(&_pinnedBar->cancel, SIGNAL(clicked()), this, SLOT(onPinnedHide()));
_reportSpamPanel.raise();
_topShadow.raise();
if (_membersDropdown) {
_membersDropdown->raise();
}
updatePinnedBar();
result = true;

View File

@ -36,6 +36,7 @@ class Result;
namespace Ui {
class HistoryDownButton;
class InnerDropdown;
} // namespace Ui
class HistoryWidget;
@ -540,12 +541,14 @@ public:
void dropEvent(QDropEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void leaveToChildEvent(QEvent *e) override;
void leaveToChildEvent(QEvent *e, QWidget *child) override;
void contextMenuEvent(QContextMenuEvent *e) override;
void updateTopBarSelection();
void paintTopBar(Painter &p, float64 over, int32 decreaseWidth);
QRect getMembersShowAreaGeometry() const;
void setMembersShowAreaActive(bool active);
void topBarClick();
void loadMessages();
@ -839,6 +842,7 @@ private slots:
void onHashtagOrBotCommandInsert(QString str, FieldAutocomplete::ChooseMethod method);
void onMentionInsert(UserData *user);
void onInlineBotCancel();
void onMembersDropdownHidden();
void updateField();
@ -1099,6 +1103,8 @@ private:
ScrollArea _kbScroll;
BotKeyboard _keyboard;
ChildWidget<Ui::InnerDropdown> _membersDropdown = { nullptr };
Dropdown _attachType;
EmojiPan _emojiPan;
DragState _attachDrag = DragStateNone;

View File

@ -2696,6 +2696,19 @@ void MainWidget::paintTopBar(Painter &p, float64 over, int32 decreaseWidth) {
}
}
QRect MainWidget::getMembersShowAreaGeometry() const {
if (!_overview && !_wideSection) {
return _history->getMembersShowAreaGeometry();
}
return QRect();
}
void MainWidget::setMembersShowAreaActive(bool active) {
if (!active || (!_overview && !_wideSection)) {
_history->setMembersShowAreaActive(active);
}
}
void MainWidget::onPhotosSelect() {
if (_overview) _overview->switchType(OverviewPhotos);
_mediaType->hideStart();

View File

@ -162,7 +162,10 @@ public:
void updateAdaptiveLayout();
bool needBackButton();
// Temporary methods, while top bar was not done inside HistoryWidget / OverviewWidget.
void paintTopBar(Painter &p, float64 over, int32 decreaseWidth);
QRect getMembersShowAreaGeometry() const;
void setMembersShowAreaActive(bool active);
Window::TopBarWidget *topBar();
PlayerWidget *player();

View File

@ -51,10 +51,10 @@ public:
bool moveToNext(int32 delta);
void preloadData(int32 delta);
void leaveToChildEvent(QEvent *e) override { // e -- from enterEvent() of child TWidget
void leaveToChildEvent(QEvent *e, QWidget *child) override { // e -- from enterEvent() of child TWidget
updateOverState(OverNone);
}
void enterFromChildEvent(QEvent *e) override { // e -- from leaveEvent() of child TWidget
void enterFromChildEvent(QEvent *e, QWidget *child) override { // e -- from leaveEvent() of child TWidget
updateOver(mapFromGlobal(QCursor::pos()));
}

View File

@ -25,29 +25,30 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
namespace Profile {
BlockWidget::BlockWidget(QWidget *parent, PeerData *peer, const QString &title) : TWidget(parent)
BlockWidget::BlockWidget(QWidget *parent, PeerData *peer, const QString &title) : ScrolledWidget(parent)
, _peer(peer)
, _title(title) {
}
void BlockWidget::resizeToWidth(int newWidth) {
resize(newWidth, resizeGetHeight(newWidth));
}
int BlockWidget::contentTop() const {
return st::profileBlockMarginTop + st::profileBlockTitleHeight;
return st::profileBlockMarginTop + (emptyTitle() ? 0 : st::profileBlockTitleHeight);
}
void BlockWidget::paintEvent(QPaintEvent *e) {
Painter p(this);
paintTitle(p);
paintContents(p);
}
void BlockWidget::paintTitle(Painter &p) {
if (emptyTitle()) return;
p.setFont(st::profileBlockTitleFont);
p.setPen(st::profileBlockTitleFg);
int titleLeft = st::profileBlockTitlePosition.x();
int titleTop = st::profileBlockMarginTop + st::profileBlockTitlePosition.y();
p.drawTextLeft(titleLeft, titleTop, width(), _title);
paintContents(p);
}
int defaultOutlineButtonLeft() {

View File

@ -24,22 +24,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
namespace Profile {
class BlockWidget : public TWidget, public Notify::Observer {
class BlockWidget : public ScrolledWidget, public Notify::Observer {
Q_OBJECT
public:
BlockWidget(QWidget *parent, PeerData *peer, const QString &title);
// Count new height for width=newWidth and resize to it.
void resizeToWidth(int newWidth);
// Updates the area that is visible inside the scroll container.
virtual void setVisibleTopBottom(int visibleTop, int visibleBottom) {
}
virtual ~BlockWidget() {
}
signals:
void heightUpdated();
@ -52,7 +42,7 @@ protected:
int contentTop() const;
// Resizes content and counts natural widget height for the desired width.
virtual int resizeGetHeight(int newWidth) = 0;
int resizeGetHeight(int newWidth) override = 0;
void contentSizeUpdated() {
resizeToWidth(width());
@ -63,7 +53,13 @@ protected:
return _peer;
}
bool emptyTitle() const {
return _title.isEmpty();
}
private:
void paintTitle(Painter &p);
PeerData *_peer;
QString _title;

View File

@ -37,7 +37,8 @@ namespace Profile {
using UpdateFlag = Notify::PeerUpdate::Flag;
MembersWidget::MembersWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_participants_section)) {
MembersWidget::MembersWidget(QWidget *parent, PeerData *peer, TitleVisibility titleVisibility)
: BlockWidget(parent, peer, (titleVisibility == TitleVisibility::Visible) ? lang(lng_profile_participants_section) : QString()) {
setMouseTracking(true);
_removeWidth = st::normalFont->width(lang(lng_profile_kick));
@ -309,7 +310,7 @@ void MembersWidget::refreshLimitReached() {
auto chat = peer()->asChat();
if (!chat) return;
bool limitReachedShown = (_list.size() >= Global::ChatSizeMax()) && chat->amCreator();
bool limitReachedShown = (_list.size() >= Global::ChatSizeMax()) && chat->amCreator() && !emptyTitle();
if (limitReachedShown && !_limitReachedInfo) {
_limitReachedInfo = new FlatLabel(this, st::profileLimitReachedLabel, st::profileLimitReachedStyle);
QString title = textRichPrepare(lng_profile_migrate_reached(lt_count, Global::ChatSizeMax()));

View File

@ -38,7 +38,11 @@ class MembersWidget : public BlockWidget {
Q_OBJECT
public:
MembersWidget(QWidget *parent, PeerData *peer);
enum class TitleVisibility {
Visible,
Hidden,
};
MembersWidget(QWidget *parent, PeerData *peer, TitleVisibility titleVisibility = TitleVisibility::Visible);
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
int onlineCount() const {
@ -57,11 +61,11 @@ protected:
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void enterEvent(QEvent *e) override;
void enterFromChildEvent(QEvent *e) override {
void enterFromChildEvent(QEvent *e, QWidget *child) override {
enterEvent(e);
}
void leaveEvent(QEvent *e) override;
void leaveToChildEvent(QEvent *e) override {
void leaveToChildEvent(QEvent *e, QWidget *child) override {
leaveEvent(e);
}

View File

@ -449,13 +449,18 @@ private:
} else {
_data->a.update(dt, _data->transition);
}
if (timer) {
_data->update.call();
}
Callback callbackCache, *toCall = &_data->update;
if (!_data->_a.animating()) {
callbackCache = std_::move(_data->update);
toCall = &callbackCache;
delete _data;
_data = nullptr;
}
if (timer) {
toCall->call();
}
}
};

View File

@ -0,0 +1,185 @@
/*
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 "ui/inner_dropdown.h"
#include "mainwindow.h"
#include "ui/scrollarea.h"
#include "profile/profile_members_widget.h"
namespace Ui {
InnerDropdown::InnerDropdown(QWidget *parent, const style::dropdown &st, const style::flatScroll &scrollSt) : TWidget(parent)
, _st(st)
, _shadow(_st.shadow)
, _scroll(this, scrollSt) {
_hideTimer.setSingleShot(true);
connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(onHideStart()));
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWindowActiveChanged()));
}
hide();
}
void InnerDropdown::setOwnedWidget(ScrolledWidget *widget) {
_scroll->setOwnedWidget(widget);
widget->show();
widget->move(0, 0);
widget->resizeToWidth(_scroll->width() - st::scrollDef.width);
}
void InnerDropdown::onWindowActiveChanged() {
if (!App::wnd()->windowHandle()->isActive() && !isHidden()) {
leaveEvent(nullptr);
}
}
void InnerDropdown::resizeEvent(QResizeEvent *e) {
_scroll->setGeometry(rect().marginsRemoved(_st.padding));
if (auto widget = static_cast<ScrolledWidget*>(_scroll->widget())) {
widget->resizeToWidth(_scroll->width() - st::scrollDef.width);
onScroll();
}
}
void InnerDropdown::onScroll() {
if (auto widget = static_cast<ScrolledWidget*>(_scroll->widget())) {
int visibleTop = _scroll->scrollTop();
int visibleBottom = visibleTop + _scroll->height();
widget->setVisibleTopBottom(visibleTop, visibleBottom);
}
}
void InnerDropdown::paintEvent(QPaintEvent *e) {
QPainter p(this);
if (!_cache.isNull()) {
bool animating = _a_appearance.animating(getms());
if (animating) {
p.setOpacity(_a_appearance.current(_hiding));
} else if (_hiding) {
hidingFinished();
return;
}
p.drawPixmap(0, 0, _cache);
if (!animating) {
showChildren();
_cache = QPixmap();
}
return;
}
// draw shadow
QRect shadowedRect = rect().marginsRemoved(_st.padding);
_shadow.paint(p, shadowedRect, _st.shadowShift);
p.fillRect(shadowedRect, st::windowBg);
}
void InnerDropdown::enterEvent(QEvent *e) {
_hideTimer.stop();
if (_hiding) showingStarted();
return TWidget::enterEvent(e);
}
void InnerDropdown::leaveEvent(QEvent *e) {
if (_a_appearance.animating(getms())) {
onHideStart();
} else {
_hideTimer.start(300);
}
return TWidget::leaveEvent(e);
}
void InnerDropdown::otherEnter() {
_hideTimer.stop();
showingStarted();
}
void InnerDropdown::otherLeave() {
if (_a_appearance.animating(getms())) {
onHideStart();
} else {
_hideTimer.start(0);
}
}
void InnerDropdown::onHideStart() {
if (_hiding) return;
_hiding = true;
startAnimation();
}
void InnerDropdown::startAnimation() {
auto from = _hiding ? 1. : 0.;
auto to = _hiding ? 0. : 1.;
if (_a_appearance.isNull()) {
showChildren();
_cache = myGrab(this);
}
hideChildren();
START_ANIMATION(_a_appearance, func(this, &InnerDropdown::repaintCallback), from, to, _st.duration, anim::linear);
}
void InnerDropdown::hidingFinished() {
hide();
// showChildren();
emit hidden();
}
void InnerDropdown::showingStarted() {
if (isHidden()) {
show();
} else if (!_hiding) {
return;
}
_hiding = false;
startAnimation();
}
void InnerDropdown::repaintCallback() {
update();
if (!_a_appearance.animating(getms()) && _hiding) {
_hiding = false;
hidingFinished();
}
}
bool InnerDropdown::eventFilter(QObject *obj, QEvent *e) {
if (e->type() == QEvent::Enter) {
otherEnter();
} else if (e->type() == QEvent::Leave) {
otherLeave();
} else if (e->type() == QEvent::MouseButtonPress && static_cast<QMouseEvent*>(e)->button() == Qt::LeftButton) {
if (isHidden() || _hiding) {
otherEnter();
} else {
otherLeave();
}
}
return false;
}
} // namespace Ui

View File

@ -0,0 +1,82 @@
/*
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
class ScrollArea;
namespace Ui {
class InnerDropdown : public TWidget {
Q_OBJECT
public:
InnerDropdown(QWidget *parent, const style::dropdown &st = st::dropdownDef, const style::flatScroll &scrollSt = st::scrollDef);
void setOwnedWidget(ScrolledWidget *widget);
bool overlaps(const QRect &globalRect) {
if (isHidden() || !_a_appearance.isNull()) return false;
return rect().marginsRemoved(_st.padding).contains(QRect(mapFromGlobal(globalRect.topLeft()), globalRect.size()));
}
void otherEnter();
void otherLeave();
protected:
void resizeEvent(QResizeEvent *e) override;
void paintEvent(QPaintEvent *e) override;
void enterEvent(QEvent *e) override;
void leaveEvent(QEvent *e) override;
bool eventFilter(QObject *obj, QEvent *e) override;
signals:
void hidden();
private slots:
void onHideStart();
void onWindowActiveChanged();
void onScroll();
private:
void repaintCallback();
void hidingFinished();
void showingStarted();
void startAnimation();
const style::dropdown &_st;
bool _hiding = false;
QPixmap _cache;
FloatAnimation _a_appearance;
QTimer _hideTimer;
BoxShadow _shadow;
ChildWidget<ScrollArea> _scroll;
};
} // namespace Ui

View File

@ -268,3 +268,25 @@ public:
}
void paintEvent(QPaintEvent *e);
};
class ScrolledWidget : public TWidget {
public:
ScrolledWidget(QWidget *parent = nullptr) : TWidget(parent) {
}
// Count new height for width=newWidth and resize to it.
void resizeToWidth(int newWidth) {
resize(newWidth, resizeGetHeight(newWidth));
}
// Updates the area that is visible inside the scroll container.
virtual void setVisibleTopBottom(int visibleTop, int visibleBottom) {
}
protected:
// Resizes content and counts natural widget height for the desired width.
virtual int resizeGetHeight(int newWidth) {
return height();
}
};

View File

@ -127,9 +127,9 @@ return qobject_cast<TWidget*>(parentWidget()); \
const TWidget *tparent() const { \
return qobject_cast<const TWidget*>(parentWidget()); \
} \
virtual void leaveToChildEvent(QEvent *e) { /* e -- from enterEvent() of child TWidget */ \
virtual void leaveToChildEvent(QEvent *e, QWidget *child) { /* e -- from enterEvent() of child TWidget */ \
} \
virtual void enterFromChildEvent(QEvent *e) { /* e -- from leaveEvent() of child TWidget */ \
virtual void enterFromChildEvent(QEvent *e, QWidget *child) { /* e -- from leaveEvent() of child TWidget */ \
} \
void moveToLeft(int x, int y, int outerw = 0) { \
move(rtl() ? ((outerw > 0 ? outerw : parentWidget()->width()) - x - width()) : x, y); \
@ -158,12 +158,12 @@ void rtlupdate(int x, int y, int w, int h) { \
protected: \
void enterEvent(QEvent *e) override { \
TWidget *p(tparent()); \
if (p) p->leaveToChildEvent(e); \
if (p) p->leaveToChildEvent(e, this); \
return enterEventHook(e); \
} \
void leaveEvent(QEvent *e) override { \
TWidget *p(tparent()); \
if (p) p->enterFromChildEvent(e); \
if (p) p->enterFromChildEvent(e, this); \
return leaveEventHook(e); \
}
@ -199,6 +199,9 @@ public:
}
}
virtual ~TWidget() {
}
protected:
void enterEventHook(QEvent *e) {
return QWidget::enterEvent(e);

View File

@ -86,9 +86,11 @@ void TopBarWidget::enterEvent(QEvent *e) {
_a_appearance.start();
}
void TopBarWidget::enterFromChildEvent(QEvent *e) {
a_over.start(1);
_a_appearance.start();
void TopBarWidget::enterFromChildEvent(QEvent *e, QWidget *child) {
if (child != _membersShowArea) {
a_over.start(1);
_a_appearance.start();
}
}
void TopBarWidget::leaveEvent(QEvent *e) {
@ -96,9 +98,11 @@ void TopBarWidget::leaveEvent(QEvent *e) {
_a_appearance.start();
}
void TopBarWidget::leaveToChildEvent(QEvent *e) {
a_over.start(0);
_a_appearance.start();
void TopBarWidget::leaveToChildEvent(QEvent *e, QWidget *child) {
if (child != _membersShowArea) {
a_over.start(0);
_a_appearance.start();
}
}
void TopBarWidget::step_appearance(float64 ms, bool timer) {
@ -112,6 +116,25 @@ void TopBarWidget::step_appearance(float64 ms, bool timer) {
if (timer) update();
}
bool TopBarWidget::eventFilter(QObject *obj, QEvent *e) {
if (obj == _membersShowArea) {
switch (e->type()) {
case QEvent::MouseButtonPress:
mousePressEvent(static_cast<QMouseEvent*>(e));
return true;
case QEvent::Enter:
main()->setMembersShowAreaActive(true);
break;
case QEvent::Leave:
main()->setMembersShowAreaActive(false);
break;
}
}
return TWidget::eventFilter(obj, e);
}
void TopBarWidget::paintEvent(QPaintEvent *e) {
Painter p(this);
@ -136,8 +159,7 @@ void TopBarWidget::paintEvent(QPaintEvent *e) {
}
void TopBarWidget::mousePressEvent(QMouseEvent *e) {
PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0;
if (e->button() == Qt::LeftButton && e->pos().y() < st::topBarHeight && (p || !_selCount)) {
if (e->button() == Qt::LeftButton && e->pos().y() < st::topBarHeight && !_selCount) {
emit clicked();
}
}
@ -209,12 +231,16 @@ void TopBarWidget::startAnim() {
_forward->hide();
_mediaType->hide();
_search->hide();
if (_membersShowArea) {
_membersShowArea->hide();
}
_animating = true;
}
void TopBarWidget::stopAnim() {
_animating = false;
updateMembersShowArea();
showAll();
}
@ -255,21 +281,53 @@ void TopBarWidget::showAll() {
_search->hide();
_info->hide();
}
if (_membersShowArea) {
_membersShowArea->show();
}
resizeEvent(nullptr);
}
void TopBarWidget::updateMembersShowArea() {
auto membersShowAreaNeeded = [this]() {
if (_selCount || App::main()->overviewPeer() || !_selPeer) {
return false;
}
if (_selPeer->isChat()) {
return true;
}
if (_selPeer->isMegagroup()) {
return (_selPeer->asMegagroup()->membersCount() < Global::ChatSizeMax());
}
return false;
};
if (!membersShowAreaNeeded()) {
if (_membersShowArea) {
main()->setMembersShowAreaActive(false);
_membersShowArea.destroy();
}
return;
} else if (!_membersShowArea) {
_membersShowArea = new TWidget(this);
_membersShowArea->show();
_membersShowArea->installEventFilter(this);
}
_membersShowArea->setGeometry(App::main()->getMembersShowAreaGeometry());
}
void TopBarWidget::showSelected(uint32 selCount, bool canDelete) {
PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0;
_selPeer = App::main()->overviewPeer() ? App::main()->overviewPeer() : App::main()->peer();
_selCount = selCount;
_canDelete = canDelete;
_selStr = (_selCount > 0) ? lng_selected_count(lt_count, _selCount) : QString();
_selStrWidth = st::btnDefLink.font->width(_selStr);
setCursor((!p && _selCount) ? style::cur_default : style::cur_pointer);
setCursor(_selCount ? style::cur_default : style::cur_pointer);
updateMembersShowArea();
showAll();
}
void TopBarWidget::updateAdaptiveLayout() {
updateMembersShowArea();
showAll();
}

View File

@ -38,9 +38,9 @@ public:
TopBarWidget(MainWidget *w);
void enterEvent(QEvent *e) override;
void enterFromChildEvent(QEvent *e) override;
void enterFromChildEvent(QEvent *e, QWidget *child) override;
void leaveEvent(QEvent *e) override;
void leaveToChildEvent(QEvent *e) override;
void leaveToChildEvent(QEvent *e, QWidget *child) override;
void paintEvent(QPaintEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
@ -54,8 +54,13 @@ public:
void updateAdaptiveLayout();
void updateMembersShowArea();
Ui::RoundButton *mediaTypeButton();
protected:
bool eventFilter(QObject *obj, QEvent *e) override;
public slots:
void onForwardSelection();
void onDeleteSelection();
@ -87,6 +92,7 @@ private:
ChildWidget<Ui::RoundButton> _mediaType;
ChildWidget<IconedButton> _search;
ChildWidget<TWidget> _membersShowArea = { nullptr };
};

View File

@ -310,6 +310,10 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_inner_dropdown.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_introcode.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@ -631,6 +635,10 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Deploy\moc_inner_dropdown.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Deploy\moc_introcode.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@ -988,6 +996,10 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_inner_dropdown.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_introcode.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@ -1351,6 +1363,7 @@
<ClCompile Include="SourceFiles\ui\flatlabel.cpp" />
<ClCompile Include="SourceFiles\ui\flattextarea.cpp" />
<ClCompile Include="SourceFiles\ui\images.cpp" />
<ClCompile Include="SourceFiles\ui\inner_dropdown.cpp" />
<ClCompile Include="SourceFiles\ui\popupmenu.cpp" />
<ClCompile Include="SourceFiles\ui\scrollarea.cpp" />
<ClCompile Include="SourceFiles\ui\style\style_core.cpp" />
@ -1949,6 +1962,20 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" "-fstdafx.h" "-f../../SourceFiles/ui/twidget.h"</Command>
</CustomBuild>
<CustomBuild Include="SourceFiles\ui\inner_dropdown.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">Moc%27ing inner_dropdown.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/ui/inner_dropdown.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing inner_dropdown.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/ui/inner_dropdown.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl_debug\Debug\include"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing inner_dropdown.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/ui/inner_dropdown.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include"</Command>
</CustomBuild>
<ClInclude Include="SourceFiles\ui\style\style_core.h" />
<ClInclude Include="SourceFiles\ui\style\style_core_color.h" />
<ClInclude Include="SourceFiles\ui\style\style_core_font.h" />

View File

@ -1329,6 +1329,18 @@
<ClCompile Include="GeneratedFiles\Release\moc_main_window_linux.cpp">
<Filter>GeneratedFiles\Release</Filter>
</ClCompile>
<ClCompile Include="SourceFiles\ui\inner_dropdown.cpp">
<Filter>SourceFiles\ui</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Deploy\moc_inner_dropdown.cpp">
<Filter>GeneratedFiles\Deploy</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_inner_dropdown.cpp">
<Filter>GeneratedFiles\Debug</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_inner_dropdown.cpp">
<Filter>GeneratedFiles\Release</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="SourceFiles\stdafx.h">
@ -1864,6 +1876,9 @@
<CustomBuild Include="SourceFiles\platform\linux\main_window_linux.h">
<Filter>SourceFiles\platform\linux</Filter>
</CustomBuild>
<CustomBuild Include="SourceFiles\ui\inner_dropdown.h">
<Filter>SourceFiles\ui</Filter>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<None Include="Resources\langs\lang_it.strings">