New main menu in DialogsWidget.
Also "flip_horizontal" and "flip_vertical" modifiers support added. Also moving parts of MainWindow to Window::MainWindow.
|
@ -402,25 +402,12 @@ noContactsHeight: 100px;
|
||||||
noContactsFont: font(fsize);
|
noContactsFont: font(fsize);
|
||||||
noContactsColor: #777777;
|
noContactsColor: #777777;
|
||||||
|
|
||||||
fieldSearchIcon: icon {{ "box_search", #aaaaaa, point(10px, 9px) }};
|
|
||||||
dlgFilter: flatInput(inpDefGray) {
|
|
||||||
font: font(fsize);
|
|
||||||
bgColor: #f2f2f2;
|
|
||||||
phColor: #949494;
|
|
||||||
phFocusColor: #a4a4a4;
|
|
||||||
icon: fieldSearchIcon;
|
|
||||||
|
|
||||||
width: 240px;
|
|
||||||
height: 34px;
|
|
||||||
textMrg: margins(34px, 2px, 34px, 4px);
|
|
||||||
}
|
|
||||||
|
|
||||||
topBarHeight: 54px;
|
topBarHeight: 54px;
|
||||||
topBarDuration: 200;
|
topBarDuration: 200;
|
||||||
topBarForward: icon {{ "title_next", #a3a3a3 }};
|
topBarForward: icon {{ "title_back-flip_horizontal", #a3a3a3 }};
|
||||||
topBarBackward: icon {{ "title_previous", #a3a3a3 }};
|
topBarBackward: icon {{ "title_back", #a3a3a3 }};
|
||||||
topBarForwardAlpha: 0.6;
|
topBarForwardAlpha: 0.6;
|
||||||
topBarBack: icon {{ "title_previous", #259fd8 }};
|
topBarBack: icon {{ "title_back", #259fd8 }};
|
||||||
topBarBackAlpha: 0.8;
|
topBarBackAlpha: 0.8;
|
||||||
topBarBackColor: #005faf;
|
topBarBackColor: #005faf;
|
||||||
topBarBackFont: font(16px);
|
topBarBackFont: font(16px);
|
||||||
|
@ -1104,15 +1091,15 @@ infoButton: PeerAvatarButton {
|
||||||
photoSize: 42px;
|
photoSize: 42px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// forward declaration for single "title_previous" usage.
|
// forward declaration for single "title_back" usage.
|
||||||
profileTopBarBackIconFg: #0290d7;
|
profileTopBarBackIconFg: #0290d7;
|
||||||
profileTopBarBackIcon: icon {{ "title_previous", profileTopBarBackIconFg }};
|
profileTopBarBackIcon: icon {{ "title_back", profileTopBarBackIconFg }};
|
||||||
|
|
||||||
historyReplyCancelIcon: icon {{ "box_button_close-invert", historyReplyBg }};
|
historyReplyCancelIcon: icon {{ "box_button_close-invert", historyReplyBg }};
|
||||||
boxSearchCancelIcon: icon {{ "box_button_close-invert", boxSearchBg }};
|
boxSearchCancelIcon: icon {{ "box_button_close-invert", boxSearchBg }};
|
||||||
settingsFixedBarCloseIcon: icon {{ "box_button_close-invert", settingsFixedBarBg }};
|
settingsFixedBarCloseIcon: icon {{ "box_button_close-invert", settingsFixedBarBg }};
|
||||||
|
|
||||||
notifyFadeRight: icon {{ "fade_horizontal_right", notificationBg }};
|
notifyFadeRight: icon {{ "fade_horizontal", notificationBg }};
|
||||||
|
|
||||||
stickerIconLeft: icon {{ "fade_horizontal_left", emojiPanCategories }};
|
stickerIconLeft: icon {{ "fade_horizontal-flip_horizontal", emojiPanCategories }};
|
||||||
stickerIconRight: icon {{ "fade_horizontal_right", emojiPanCategories }};
|
stickerIconRight: icon {{ "fade_horizontal", emojiPanCategories }};
|
||||||
|
|
|
@ -24,7 +24,7 @@ windowBg: #ffffff; // white: fallback for background
|
||||||
windowTextFg: #000000; // black: fallback for text color
|
windowTextFg: #000000; // black: fallback for text color
|
||||||
windowSubTextFg: #8a8a8a; // gray: fallback for subtext color
|
windowSubTextFg: #8a8a8a; // gray: fallback for subtext color
|
||||||
windowActiveFill: #40ace3; // bright blue: fallback for blue filled active areas
|
windowActiveFill: #40ace3; // bright blue: fallback for blue filled active areas
|
||||||
windowOverBg: #edf2f5; // light blue: fallback for over background
|
windowOverBg: #f3f3f3; // light blue: fallback for over background
|
||||||
windowSubTextFgOver: #7c99b2; // gray over light blue: fallback for subtext over color
|
windowSubTextFgOver: #7c99b2; // gray over light blue: fallback for subtext over color
|
||||||
windowActiveTextFg: #1485c2; // online blue: fallback for active color
|
windowActiveTextFg: #1485c2; // online blue: fallback for active color
|
||||||
windowShadowFg: #000000; // black: fallback for shadow color
|
windowShadowFg: #000000; // black: fallback for shadow color
|
||||||
|
@ -32,22 +32,7 @@ windowShadowFg: #000000; // black: fallback for shadow color
|
||||||
imageBg: #000000;
|
imageBg: #000000;
|
||||||
imageBgTransparent: #ffffff;
|
imageBgTransparent: #ffffff;
|
||||||
|
|
||||||
// custom title bar for Windows
|
// widgets
|
||||||
titleBg: #f3f3f3;
|
|
||||||
titleShadow: #00000003;
|
|
||||||
titleButtonFg: #ababab;
|
|
||||||
titleButtonBgOver: #e5e5e5;
|
|
||||||
titleButtonFgOver: #9a9a9a;
|
|
||||||
titleButtonCloseBgOver: #e81123;
|
|
||||||
titleButtonCloseFgOver: #ffffff;
|
|
||||||
|
|
||||||
// tray icon
|
|
||||||
trayCounterBg: #f23c34;
|
|
||||||
trayCounterBgMute: #888888;
|
|
||||||
trayCounterFg: #ffffff;
|
|
||||||
trayCounterBgMacInvert: #ffffff;
|
|
||||||
trayCounterFgMacInvert: #ffffff01;
|
|
||||||
|
|
||||||
cancelIconFg: #a2a2a2;
|
cancelIconFg: #a2a2a2;
|
||||||
cancelIconFgOver: #808080;
|
cancelIconFgOver: #808080;
|
||||||
|
|
||||||
|
@ -63,6 +48,24 @@ lightButtonBgOver: #f2f7fa | lightButtonBg;
|
||||||
lightButtonFg: #2b99d5;
|
lightButtonFg: #2b99d5;
|
||||||
lightButtonFgOver: lightButtonFg;
|
lightButtonFgOver: lightButtonFg;
|
||||||
|
|
||||||
|
menuIconFg: #808080 | windowSubTextFg;
|
||||||
|
|
||||||
|
// custom title bar for Windows
|
||||||
|
titleBg: windowOverBg;
|
||||||
|
titleShadow: #00000003;
|
||||||
|
titleButtonFg: #ababab;
|
||||||
|
titleButtonBgOver: #e5e5e5;
|
||||||
|
titleButtonFgOver: #9a9a9a;
|
||||||
|
titleButtonCloseBgOver: #e81123;
|
||||||
|
titleButtonCloseFgOver: #ffffff;
|
||||||
|
|
||||||
|
// tray icon
|
||||||
|
trayCounterBg: #f23c34;
|
||||||
|
trayCounterBgMute: #888888;
|
||||||
|
trayCounterFg: #ffffff;
|
||||||
|
trayCounterBgMacInvert: #ffffff;
|
||||||
|
trayCounterFgMacInvert: #ffffff01;
|
||||||
|
|
||||||
// layers
|
// layers
|
||||||
layerBg: #0000007f;
|
layerBg: #0000007f;
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 124 B |
Before Width: | Height: | Size: 163 B |
BIN
Telegram/Resources/icons/dialogs_menu.png
Normal file
After Width: | Height: | Size: 110 B |
BIN
Telegram/Resources/icons/dialogs_menu@2x.png
Normal file
After Width: | Height: | Size: 148 B |
Before Width: | Height: | Size: 145 B After Width: | Height: | Size: 145 B |
Before Width: | Height: | Size: 213 B After Width: | Height: | Size: 213 B |
Before Width: | Height: | Size: 145 B |
Before Width: | Height: | Size: 236 B |
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 142 B |
Before Width: | Height: | Size: 190 B After Width: | Height: | Size: 190 B |
Before Width: | Height: | Size: 139 B |
Before Width: | Height: | Size: 192 B |
Before Width: | Height: | Size: 304 B |
Before Width: | Height: | Size: 496 B |
BIN
Telegram/Resources/icons/menu_contacts.png
Normal file
After Width: | Height: | Size: 355 B |
BIN
Telegram/Resources/icons/menu_contacts@2x.png
Normal file
After Width: | Height: | Size: 661 B |
BIN
Telegram/Resources/icons/menu_help.png
Normal file
After Width: | Height: | Size: 393 B |
BIN
Telegram/Resources/icons/menu_help@2x.png
Normal file
After Width: | Height: | Size: 805 B |
BIN
Telegram/Resources/icons/menu_new_channel.png
Normal file
After Width: | Height: | Size: 210 B |
BIN
Telegram/Resources/icons/menu_new_channel@2x.png
Normal file
After Width: | Height: | Size: 392 B |
BIN
Telegram/Resources/icons/menu_new_group.png
Normal file
After Width: | Height: | Size: 336 B |
BIN
Telegram/Resources/icons/menu_new_group@2x.png
Normal file
After Width: | Height: | Size: 667 B |
BIN
Telegram/Resources/icons/menu_settings.png
Normal file
After Width: | Height: | Size: 559 B |
BIN
Telegram/Resources/icons/menu_settings@2x.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 182 B |
Before Width: | Height: | Size: 292 B |
Before Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 325 B |
Before Width: | Height: | Size: 152 B After Width: | Height: | Size: 152 B |
Before Width: | Height: | Size: 416 B After Width: | Height: | Size: 416 B |
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 148 B |
Before Width: | Height: | Size: 264 B After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 316 B |
Before Width: | Height: | Size: 573 B |
Before Width: | Height: | Size: 314 B |
Before Width: | Height: | Size: 557 B |
Before Width: | Height: | Size: 154 B |
Before Width: | Height: | Size: 261 B |
|
@ -519,9 +519,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_create_group_next" = "Next";
|
"lng_create_group_next" = "Next";
|
||||||
"lng_create_group_create" = "Create";
|
"lng_create_group_create" = "Create";
|
||||||
"lng_create_group_title" = "New Group";
|
"lng_create_group_title" = "New Group";
|
||||||
"lng_create_group_about" = "Groups are ideal for limited communities,\nthey can have up to {count:_not_used|# member|# members}";
|
|
||||||
"lng_create_channel_title" = "New Channel";
|
"lng_create_channel_title" = "New Channel";
|
||||||
"lng_create_channel_about" = "Channels are a tool for broadcasting your messages to unlimited audiences";
|
|
||||||
"lng_create_public_channel_title" = "Public Channel";
|
"lng_create_public_channel_title" = "Public Channel";
|
||||||
"lng_create_public_channel_about" = "Anyone can find the channel in search and join";
|
"lng_create_public_channel_about" = "Anyone can find the channel in search and join";
|
||||||
"lng_create_private_channel_title" = "Private Channel";
|
"lng_create_private_channel_title" = "Private Channel";
|
||||||
|
|
|
@ -25,24 +25,12 @@ windowBg: #ffffff;
|
||||||
windowTextFg: #000000;
|
windowTextFg: #000000;
|
||||||
windowSubTextFg: #8a8a8a;
|
windowSubTextFg: #8a8a8a;
|
||||||
windowActiveFill: #40ace3;
|
windowActiveFill: #40ace3;
|
||||||
windowOverBg: #edf2f5;
|
windowOverBg: #f3f3f3;
|
||||||
windowSubTextFgOver: #7c99b2;
|
windowSubTextFgOver: #7c99b2;
|
||||||
windowActiveTextFg: #1485c2;
|
windowActiveTextFg: #1485c2;
|
||||||
windowShadowFg: #000000;
|
windowShadowFg: #000000;
|
||||||
imageBg: #000000;
|
imageBg: #000000;
|
||||||
imageBgTransparent: #ffffff;
|
imageBgTransparent: #ffffff;
|
||||||
titleBg: #f3f3f3;
|
|
||||||
titleShadow: #00000003;
|
|
||||||
titleButtonFg: #ababab;
|
|
||||||
titleButtonBgOver: #e5e5e5;
|
|
||||||
titleButtonFgOver: #9a9a9a;
|
|
||||||
titleButtonCloseBgOver: #e81123;
|
|
||||||
titleButtonCloseFgOver: #ffffff;
|
|
||||||
trayCounterBg: #f23c34;
|
|
||||||
trayCounterBgMute: #888888;
|
|
||||||
trayCounterFg: #ffffff;
|
|
||||||
trayCounterBgMacInvert: #ffffff;
|
|
||||||
trayCounterFgMacInvert: #ffffff01;
|
|
||||||
cancelIconFg: #a2a2a2;
|
cancelIconFg: #a2a2a2;
|
||||||
cancelIconFgOver: #808080;
|
cancelIconFgOver: #808080;
|
||||||
activeButtonBg: windowActiveFill;
|
activeButtonBg: windowActiveFill;
|
||||||
|
@ -55,6 +43,19 @@ lightButtonBg: windowBg;
|
||||||
lightButtonBgOver: #f2f7fa; // lightButtonBg;
|
lightButtonBgOver: #f2f7fa; // lightButtonBg;
|
||||||
lightButtonFg: #2b99d5;
|
lightButtonFg: #2b99d5;
|
||||||
lightButtonFgOver: lightButtonFg;
|
lightButtonFgOver: lightButtonFg;
|
||||||
|
menuIconFg: #808080; // windowSubTextFg;
|
||||||
|
titleBg: windowOverBg;
|
||||||
|
titleShadow: #00000003;
|
||||||
|
titleButtonFg: #ababab;
|
||||||
|
titleButtonBgOver: #e5e5e5;
|
||||||
|
titleButtonFgOver: #9a9a9a;
|
||||||
|
titleButtonCloseBgOver: #e81123;
|
||||||
|
titleButtonCloseFgOver: #ffffff;
|
||||||
|
trayCounterBg: #f23c34;
|
||||||
|
trayCounterBgMute: #888888;
|
||||||
|
trayCounterFg: #ffffff;
|
||||||
|
trayCounterBgMacInvert: #ffffff;
|
||||||
|
trayCounterFgMacInvert: #ffffff01;
|
||||||
layerBg: #0000007f;
|
layerBg: #0000007f;
|
||||||
boxBg: windowBg;
|
boxBg: windowBg;
|
||||||
boxTextFg: windowTextFg;
|
boxTextFg: windowTextFg;
|
||||||
|
|
|
@ -260,64 +260,6 @@ void AddContactBox::onRetry() {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
NewGroupBox::NewGroupBox() : AbstractBox(),
|
|
||||||
_group(this, qsl("group_type"), 0, lang(lng_create_group_title), true),
|
|
||||||
_channel(this, qsl("group_type"), 1, lang(lng_create_channel_title)),
|
|
||||||
_aboutGroupWidth(width() - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultRadiobutton.textPosition.x()),
|
|
||||||
_aboutGroup(st::normalFont, lng_create_group_about(lt_count, Global::MegagroupSizeMax()), _defaultOptions, _aboutGroupWidth),
|
|
||||||
_aboutChannel(st::normalFont, lang(lng_create_channel_about), _defaultOptions, _aboutGroupWidth),
|
|
||||||
_next(this, lang(lng_create_group_next), st::defaultBoxButton),
|
|
||||||
_cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
|
||||||
_aboutGroupHeight = _aboutGroup.countHeight(_aboutGroupWidth);
|
|
||||||
setMaxHeight(st::boxPadding.top() + st::newGroupPadding.top() + _group->height() + _aboutGroupHeight + st::newGroupSkip + _channel->height() + _aboutChannel.countHeight(_aboutGroupWidth) + st::newGroupPadding.bottom() + st::boxPadding.bottom() + st::boxButtonPadding.top() + _next->height() + st::boxButtonPadding.bottom());
|
|
||||||
|
|
||||||
connect(_next, SIGNAL(clicked()), this, SLOT(onNext()));
|
|
||||||
connect(_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
|
||||||
|
|
||||||
prepare();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGroupBox::showAll() {
|
|
||||||
_group->show();
|
|
||||||
_channel->show();
|
|
||||||
_cancel->show();
|
|
||||||
_next->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGroupBox::keyPressEvent(QKeyEvent *e) {
|
|
||||||
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
|
|
||||||
onNext();
|
|
||||||
} else {
|
|
||||||
AbstractBox::keyPressEvent(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGroupBox::paintEvent(QPaintEvent *e) {
|
|
||||||
Painter p(this);
|
|
||||||
if (paint(p)) return;
|
|
||||||
|
|
||||||
p.setPen(st::newGroupAboutFg->p);
|
|
||||||
|
|
||||||
QRect aboutGroup(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultRadiobutton.textPosition.x(), _group->y() + _group->height() + st::lineWidth, _aboutGroupWidth, _aboutGroupHeight);
|
|
||||||
_aboutGroup.drawLeft(p, aboutGroup.x(), aboutGroup.y(), aboutGroup.width(), width());
|
|
||||||
|
|
||||||
QRect aboutChannel(st::boxPadding.left() + st::newGroupPadding.left() + st::defaultRadiobutton.textPosition.x(), _channel->y() + _channel->height() + st::lineWidth, _aboutGroupWidth, _aboutGroupHeight);
|
|
||||||
_aboutChannel.drawLeft(p, aboutChannel.x(), aboutChannel.y(), aboutChannel.width(), width());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGroupBox::resizeEvent(QResizeEvent *e) {
|
|
||||||
_group->moveToLeft(st::boxPadding.left() + st::newGroupPadding.left(), st::boxPadding.top() + st::newGroupPadding.top());
|
|
||||||
_channel->moveToLeft(st::boxPadding.left() + st::newGroupPadding.left(), _group->y() + _group->height() + _aboutGroupHeight + st::newGroupSkip);
|
|
||||||
|
|
||||||
_next->moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _next->height());
|
|
||||||
_cancel->moveToRight(st::boxButtonPadding.right() + _next->width() + st::boxButtonPadding.left(), _next->y());
|
|
||||||
AbstractBox::resizeEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewGroupBox::onNext() {
|
|
||||||
Ui::showLayer(new GroupInfoBox(_group->checked() ? CreatingGroupGroup : CreatingGroupChannel, true), KeepOtherLayers);
|
|
||||||
}
|
|
||||||
|
|
||||||
GroupInfoBox::GroupInfoBox(CreatingGroupType creating, bool fromTypeChoose) : AbstractBox(),
|
GroupInfoBox::GroupInfoBox(CreatingGroupType creating, bool fromTypeChoose) : AbstractBox(),
|
||||||
_creating(creating),
|
_creating(creating),
|
||||||
a_photoOver(0, 0),
|
a_photoOver(0, 0),
|
||||||
|
|
|
@ -78,34 +78,6 @@ private:
|
||||||
QString _sentName;
|
QString _sentName;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NewGroupBox : public AbstractBox {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
NewGroupBox();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void onNext();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void keyPressEvent(QKeyEvent *e) override;
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
|
||||||
|
|
||||||
void showAll() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
ChildWidget<Ui::Radiobutton> _group;
|
|
||||||
ChildWidget<Ui::Radiobutton> _channel;
|
|
||||||
|
|
||||||
int32 _aboutGroupWidth, _aboutGroupHeight;
|
|
||||||
Text _aboutGroup, _aboutChannel;
|
|
||||||
|
|
||||||
ChildWidget<BoxButton> _next;
|
|
||||||
ChildWidget<BoxButton> _cancel;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class GroupInfoBox : public AbstractBox, public RPCSender {
|
class GroupInfoBox : public AbstractBox, public RPCSender {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
using "basic.style";
|
using "basic.style";
|
||||||
|
|
||||||
using "ui/widgets/widgets.style";
|
using "ui/widgets/widgets.style";
|
||||||
using "intro/intro.style";
|
using "intro/intro.style";
|
||||||
|
|
||||||
|
@ -143,7 +144,7 @@ contactsMultiSelect: MultiSelect {
|
||||||
font: normalFont;
|
font: normalFont;
|
||||||
}
|
}
|
||||||
fieldMinWidth: 42px;
|
fieldMinWidth: 42px;
|
||||||
fieldIcon: fieldSearchIcon;
|
fieldIcon: boxFieldSearchIcon;
|
||||||
fieldIconSkip: 36px;
|
fieldIconSkip: 36px;
|
||||||
|
|
||||||
fieldCancel: MaskButton(defaultMaskButton) {
|
fieldCancel: MaskButton(defaultMaskButton) {
|
||||||
|
|
|
@ -38,8 +38,8 @@ namespace codegen {
|
||||||
namespace style {
|
namespace style {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr int kErrorBadIconSize = 861;
|
constexpr int kErrorBadIconSize = 861;
|
||||||
constexpr int kErrorBadIconFormat = 862;
|
constexpr int kErrorBadIconFormat = 862;
|
||||||
|
|
||||||
// crc32 hash, taken somewhere from the internet
|
// crc32 hash, taken somewhere from the internet
|
||||||
|
|
||||||
|
@ -1017,10 +1017,10 @@ QByteArray iconMaskValueSize(int width, int height) {
|
||||||
QByteArray iconMaskValuePng(QString filepath) {
|
QByteArray iconMaskValuePng(QString filepath) {
|
||||||
QByteArray result;
|
QByteArray result;
|
||||||
|
|
||||||
auto inverted = filepath.endsWith("-invert");
|
auto pathAndModifiers = filepath.split('-');
|
||||||
if (inverted) {
|
filepath = pathAndModifiers[0];
|
||||||
filepath.chop(QLatin1String("-invert").size());
|
auto modifiers = pathAndModifiers.mid(1);
|
||||||
}
|
|
||||||
QImage png100x(filepath + ".png");
|
QImage png100x(filepath + ".png");
|
||||||
QImage png200x(filepath + "@2x.png");
|
QImage png200x(filepath + "@2x.png");
|
||||||
png100x.setDevicePixelRatio(1.);
|
png100x.setDevicePixelRatio(1.);
|
||||||
|
@ -1041,9 +1041,13 @@ QByteArray iconMaskValuePng(QString filepath) {
|
||||||
common::logError(kErrorBadIconSize, filepath + ".png") << "bad icons size, 1x: " << png100x.width() << "x" << png100x.height() << ", 2x: " << png200x.width() << "x" << png200x.height();
|
common::logError(kErrorBadIconSize, filepath + ".png") << "bad icons size, 1x: " << png100x.width() << "x" << png100x.height() << ", 2x: " << png200x.width() << "x" << png200x.height();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (inverted) {
|
for (auto modifierName : modifiers) {
|
||||||
png100x.invertPixels();
|
if (auto modifier = GetModifier(modifierName)) {
|
||||||
png200x.invertPixels();
|
modifier(png100x, png200x);
|
||||||
|
} else {
|
||||||
|
common::logError(common::kErrorInternal, filepath) << "modifier should be valid here, name: " << modifierName.toStdString();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
QImage png125x = png200x.scaled(structure::data::pxAdjust(png100x.width(), 5), structure::data::pxAdjust(png100x.height(), 5), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
QImage png125x = png200x.scaled(structure::data::pxAdjust(png100x.width(), 5), structure::data::pxAdjust(png100x.height(), 5), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
QImage png150x = png200x.scaled(structure::data::pxAdjust(png100x.width(), 6), structure::data::pxAdjust(png100x.height(), 6), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
QImage png150x = png200x.scaled(structure::data::pxAdjust(png100x.width(), 6), structure::data::pxAdjust(png100x.height(), 6), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
|
|
@ -44,6 +44,7 @@ constexpr int kErrorIdentifierNotFound = 804;
|
||||||
constexpr int kErrorAlreadyDefined = 805;
|
constexpr int kErrorAlreadyDefined = 805;
|
||||||
constexpr int kErrorBadString = 806;
|
constexpr int kErrorBadString = 806;
|
||||||
constexpr int kErrorIconDuplicate = 807;
|
constexpr int kErrorIconDuplicate = 807;
|
||||||
|
constexpr int kErrorBadIconModifier = 808;
|
||||||
|
|
||||||
QString findInputFile(const Options &options) {
|
QString findInputFile(const Options &options) {
|
||||||
for (const auto &dir : options.includePaths) {
|
for (const auto &dir : options.includePaths) {
|
||||||
|
@ -151,6 +152,25 @@ bool validateAlignString(const QString &value) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
Modifier GetModifier(const QString &name) {
|
||||||
|
static QMap<QString, Modifier> modifiers;
|
||||||
|
if (modifiers.empty()) {
|
||||||
|
modifiers.insert("invert", [](QImage &png100x, QImage &png200x) {
|
||||||
|
png100x.invertPixels();
|
||||||
|
png200x.invertPixels();
|
||||||
|
});
|
||||||
|
modifiers.insert("flip_horizontal", [](QImage &png100x, QImage &png200x) {
|
||||||
|
png100x = png100x.mirrored(true, false);
|
||||||
|
png200x = png200x.mirrored(true, false);
|
||||||
|
});
|
||||||
|
modifiers.insert("flip_vertical", [](QImage &png100x, QImage &png200x) {
|
||||||
|
png100x = png100x.mirrored(false, true);
|
||||||
|
png200x = png200x.mirrored(false, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return modifiers.value(name);
|
||||||
|
}
|
||||||
|
|
||||||
ParsedFile::ParsedFile(const Options &options)
|
ParsedFile::ParsedFile(const Options &options)
|
||||||
: filePath_(findInputFile(options))
|
: filePath_(findInputFile(options))
|
||||||
, file_(filePath_)
|
, file_(filePath_)
|
||||||
|
@ -821,21 +841,26 @@ structure::data::monoicon ParsedFile::readMonoIconFields() {
|
||||||
QString ParsedFile::readMonoIconFilename() {
|
QString ParsedFile::readMonoIconFilename() {
|
||||||
if (auto filename = readValue()) {
|
if (auto filename = readValue()) {
|
||||||
if (filename.type().tag == structure::TypeTag::String) {
|
if (filename.type().tag == structure::TypeTag::String) {
|
||||||
auto filepath = QString::fromStdString(filename.String());
|
auto fullpath = QString::fromStdString(filename.String());
|
||||||
auto inverted = filepath.endsWith("-invert");
|
auto pathAndModifiers = fullpath.split('-');
|
||||||
if (inverted) {
|
auto filepath = pathAndModifiers[0];
|
||||||
filepath.chop(QLatin1String("-invert").size());
|
auto modifiers = pathAndModifiers.mid(1);
|
||||||
}
|
for (auto modifierName : modifiers) {
|
||||||
for (const auto &path : options_.includePaths) {
|
if (!GetModifier(modifierName)) {
|
||||||
QFileInfo fileinfo(path + '/' + filepath + ".png");
|
logError(kErrorBadIconModifier) << "unknown modifier: " << modifierName.toStdString();
|
||||||
if (fileinfo.exists()) {
|
return QString();
|
||||||
return path + '/' + filepath + (inverted ? "-invert" : "");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto &path : options_.includePaths) {
|
for (auto &path : options_.includePaths) {
|
||||||
|
QFileInfo fileinfo(path + '/' + filepath + ".png");
|
||||||
|
if (fileinfo.exists()) {
|
||||||
|
return path + '/' + fullpath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto &path : options_.includePaths) {
|
||||||
QFileInfo fileinfo(path + "/icons/" + filepath + ".png");
|
QFileInfo fileinfo(path + "/icons/" + filepath + ".png");
|
||||||
if (fileinfo.exists()) {
|
if (fileinfo.exists()) {
|
||||||
return path + "/icons/" + filepath + (inverted ? "-invert" : "");
|
return path + "/icons/" + fullpath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logError(common::kErrorFileNotFound) << "could not open icon file '" << filename.String() << "'";
|
logError(common::kErrorFileNotFound) << "could not open icon file '" << filename.String() << "'";
|
||||||
|
|
|
@ -22,6 +22,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
#include <QImage>
|
||||||
#include "codegen/common/basic_tokenized_file.h"
|
#include "codegen/common/basic_tokenized_file.h"
|
||||||
#include "codegen/style/options.h"
|
#include "codegen/style/options.h"
|
||||||
#include "codegen/style/module.h"
|
#include "codegen/style/module.h"
|
||||||
|
@ -29,6 +31,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
namespace style {
|
namespace style {
|
||||||
|
|
||||||
|
using Modifier = std::function<void(QImage &png100x, QImage &png200x)>;
|
||||||
|
Modifier GetModifier(const QString &name);
|
||||||
|
|
||||||
// Parses an input file to the internal struct.
|
// Parses an input file to the internal struct.
|
||||||
class ParsedFile {
|
class ParsedFile {
|
||||||
public:
|
public:
|
||||||
|
@ -44,7 +49,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool failed() const {
|
bool failed() const {
|
||||||
return failed_ || file_.failed();
|
return failed_ || file_.failed();
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,8 @@ template <typename T>
|
||||||
struct remove_reference<T&&> {
|
struct remove_reference<T&&> {
|
||||||
using type = T;
|
using type = T;
|
||||||
};
|
};
|
||||||
|
template <typename T>
|
||||||
|
using remove_reference_t = typename remove_reference<T>::type;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_lvalue_reference : false_type {
|
struct is_lvalue_reference : false_type {
|
||||||
|
|
|
@ -25,7 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
inline constexpr size_t array_size(T(&)[N]) {
|
inline constexpr size_t array_size(const T(&)[N]) {
|
||||||
return N;
|
return N;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,27 @@ inline T take(T &source, T &&new_value = T()) {
|
||||||
return std_::move(new_value);
|
return std_::move(new_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <typename D, typename T>
|
||||||
|
inline constexpr D up_cast_helper(std_::true_type, T object) {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename D, typename T>
|
||||||
|
inline constexpr D up_cast_helper(std_::false_type, T object) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <typename D, typename T>
|
||||||
|
inline constexpr D up_cast(T object) {
|
||||||
|
using DV = std_::decay_simple_t<decltype(*D())>;
|
||||||
|
using TV = std_::decay_simple_t<decltype(*T())>;
|
||||||
|
return internal::up_cast_helper<D>(std_::integral_constant<bool, std_::is_base_of<DV, TV>::value || std_::is_same<DV, TV>::value>(), object);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
|
||||||
template <typename Enum>
|
template <typename Enum>
|
||||||
|
|
|
@ -48,7 +48,7 @@ dialogsNameFg: #000000;
|
||||||
dialogsNameTop: 2px;
|
dialogsNameTop: 2px;
|
||||||
|
|
||||||
dialogsRowHeight: 62px;
|
dialogsRowHeight: 62px;
|
||||||
dialogsFilterPadding: 10px;
|
dialogsFilterPadding: point(11px, 11px);
|
||||||
dialogsPhotoSize: 46px;
|
dialogsPhotoSize: 46px;
|
||||||
dialogsPhotoPadding: 12px;
|
dialogsPhotoPadding: 12px;
|
||||||
dialogsPadding: point(10px, 8px);
|
dialogsPadding: point(10px, 8px);
|
||||||
|
@ -83,24 +83,44 @@ dialogsTextStyleDraftActive: textStyle(dialogsTextStyle) {
|
||||||
linkFgDown: #c6e1f7;
|
linkFgDown: #c6e1f7;
|
||||||
}
|
}
|
||||||
|
|
||||||
dialogsNewChatIcon: icon {{ "dialogs_new_chat", #b7b7b7 }};
|
dialogsMenuToggle: IconButton {
|
||||||
dialogsNewChatButton: IconButton {
|
width: 32px;
|
||||||
width: 36px;
|
height: 32px;
|
||||||
height: 36px;
|
|
||||||
|
|
||||||
icon: dialogsNewChatIcon;
|
icon: icon {{ "dialogs_menu", #999999 }};
|
||||||
iconPosition: point(9px, 10px);
|
iconPosition: point(6px, 6px);
|
||||||
iconPositionDown: point(9px, 11px);
|
iconPositionDown: point(6px, 6px);
|
||||||
}
|
}
|
||||||
dialogsAddContact: IconButton(dialogsNewChatButton) {
|
dialogsFilter: flatInput(inpDefGray) {
|
||||||
icon: icon {{ "dialogs_add_contact", #a6a6a6 }};
|
font: font(fsize);
|
||||||
iconPosition: point(8px, 8px);
|
bgColor: #f2f2f2;
|
||||||
iconPositionDown: point(8px, 9px);
|
phColor: #949494;
|
||||||
|
phFocusColor: #a4a4a4;
|
||||||
|
icon: fieldSearchIcon;
|
||||||
|
|
||||||
|
width: 240px;
|
||||||
|
height: 32px;
|
||||||
|
textMrg: margins(32px, 3px, 32px, 3px);
|
||||||
}
|
}
|
||||||
dialogsCancelSearch: IconButton(dialogsAddContact) {
|
dialogsCancelSearch: IconButton(dialogsMenuToggle) {
|
||||||
icon: icon {{ "dialogs_cancel_search", #a6a6a6 }};
|
icon: icon {{ "dialogs_cancel_search", #a6a6a6, point(0px, 1px) }};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialogsMenu: DropdownMenu(defaultDropdownMenu) {
|
||||||
|
menu: Menu(defaultMenu) {
|
||||||
|
skip: 8px;
|
||||||
|
|
||||||
|
itemIconPosition: point(15px, 8px);
|
||||||
|
itemPadding: margins(56px, 10px, 56px, 12px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dialogsMenuPosition: point(-3px, -2px);
|
||||||
|
dialogsMenuNewGroup: icon {{ "menu_new_group", menuIconFg }};
|
||||||
|
dialogsMenuNewChannel: icon {{ "menu_new_channel", menuIconFg }};
|
||||||
|
dialogsMenuContacts: icon {{ "menu_contacts", menuIconFg }};
|
||||||
|
dialogsMenuSettings: icon {{ "menu_settings", menuIconFg }};
|
||||||
|
dialogsMenuHelp: icon {{ "menu_help", menuIconFg }};
|
||||||
|
|
||||||
dialogsChatTypeSkip: 22px;
|
dialogsChatTypeSkip: 22px;
|
||||||
dialogsChatIcon: icon {{ "dialogs_chat", #373737, point(1px, 4px) }};
|
dialogsChatIcon: icon {{ "dialogs_chat", #373737, point(1px, 4px) }};
|
||||||
dialogsChatActiveIcon: icon {{ "dialogs_chat", #ffffff, point(1px, 4px) }};
|
dialogsChatActiveIcon: icon {{ "dialogs_chat", #ffffff, point(1px, 4px) }};
|
||||||
|
|
|
@ -36,10 +36,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "boxes/addcontactbox.h"
|
#include "boxes/addcontactbox.h"
|
||||||
#include "boxes/contactsbox.h"
|
#include "boxes/contactsbox.h"
|
||||||
#include "boxes/confirmbox.h"
|
#include "boxes/confirmbox.h"
|
||||||
|
#include "boxes/aboutbox.h"
|
||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
#include "ui/widgets/dropdown_menu.h"
|
||||||
|
|
||||||
DialogsInner::DialogsInner(QWidget *parent, MainWidget *main) : SplittedWidget(parent)
|
DialogsInner::DialogsInner(QWidget *parent, QWidget *main) : SplittedWidget(parent)
|
||||||
, dialogs(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date))
|
, dialogs(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date))
|
||||||
, contactsNoDialogs(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
, contactsNoDialogs(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
||||||
, contacts(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
, contacts(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
||||||
|
@ -1770,28 +1772,13 @@ MsgId DialogsInner::lastSearchMigratedId() const {
|
||||||
return _lastSearchMigratedId;
|
return _lastSearchMigratedId;
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogsWidget::DialogsWidget(MainWidget *parent) : TWidget(parent)
|
DialogsWidget::DialogsWidget(QWidget *parent) : TWidget(parent)
|
||||||
, _dragInScroll(false)
|
, _mainMenuToggle(this, st::dialogsMenuToggle)
|
||||||
, _dragForward(false)
|
, _filter(this, st::dialogsFilter, lang(lng_dlg_filter))
|
||||||
, _dialogsFull(false)
|
|
||||||
, _dialogsOffsetDate(0)
|
|
||||||
, _dialogsOffsetId(0)
|
|
||||||
, _dialogsOffsetPeer(0)
|
|
||||||
, _dialogsRequest(0)
|
|
||||||
, _contactsRequest(0)
|
|
||||||
, _filter(this, st::dlgFilter, lang(lng_dlg_filter))
|
|
||||||
, _newGroup(this, st::dialogsNewChatButton)
|
|
||||||
, _addContact(this, st::dialogsAddContact)
|
|
||||||
, _cancelSearch(this, st::dialogsCancelSearch)
|
, _cancelSearch(this, st::dialogsCancelSearch)
|
||||||
, _scroll(this, st::dialogsScroll)
|
, _scroll(this, st::dialogsScroll)
|
||||||
, _inner(&_scroll, parent)
|
, _inner(&_scroll, parent)
|
||||||
, _a_show(animation(this, &DialogsWidget::step_show))
|
, _a_show(animation(this, &DialogsWidget::step_show)) {
|
||||||
, _searchInPeer(0)
|
|
||||||
, _searchInMigrated(0)
|
|
||||||
, _searchFull(false)
|
|
||||||
, _searchFullMigrated(false)
|
|
||||||
, _peopleFull(false)
|
|
||||||
{
|
|
||||||
_scroll.setWidget(&_inner);
|
_scroll.setWidget(&_inner);
|
||||||
_scroll.setFocusPolicy(Qt::NoFocus);
|
_scroll.setFocusPolicy(Qt::NoFocus);
|
||||||
connect(&_inner, SIGNAL(mustScrollTo(int,int)), &_scroll, SLOT(scrollToY(int,int)));
|
connect(&_inner, SIGNAL(mustScrollTo(int,int)), &_scroll, SLOT(scrollToY(int,int)));
|
||||||
|
@ -1803,14 +1790,13 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : TWidget(parent)
|
||||||
connect(&_inner, SIGNAL(cancelSearchInPeer()), this, SLOT(onCancelSearchInPeer()));
|
connect(&_inner, SIGNAL(cancelSearchInPeer()), this, SLOT(onCancelSearchInPeer()));
|
||||||
connect(&_scroll, SIGNAL(geometryChanged()), &_inner, SLOT(onParentGeometryChanged()));
|
connect(&_scroll, SIGNAL(geometryChanged()), &_inner, SLOT(onParentGeometryChanged()));
|
||||||
connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll()));
|
connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll()));
|
||||||
connect(&_filter, SIGNAL(cancelled()), this, SLOT(onCancel()));
|
connect(_filter, SIGNAL(cancelled()), this, SLOT(onCancel()));
|
||||||
connect(&_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate()));
|
connect(_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate()));
|
||||||
connect(&_filter, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(onFilterCursorMoved(int,int)));
|
connect(_filter, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(onFilterCursorMoved(int,int)));
|
||||||
connect(parent, SIGNAL(dialogsUpdated()), this, SLOT(onListScroll()));
|
|
||||||
connect(_addContact, SIGNAL(clicked()), this, SLOT(onAddContact()));
|
|
||||||
connect(_newGroup, SIGNAL(clicked()), this, SLOT(onNewGroup()));
|
|
||||||
connect(_cancelSearch, SIGNAL(clicked()), this, SLOT(onCancelSearch()));
|
connect(_cancelSearch, SIGNAL(clicked()), this, SLOT(onCancelSearch()));
|
||||||
|
|
||||||
|
_mainMenuToggle->setClickedCallback([this] { showMainMenu(); });
|
||||||
|
|
||||||
_chooseByDragTimer.setSingleShot(true);
|
_chooseByDragTimer.setSingleShot(true);
|
||||||
connect(&_chooseByDragTimer, SIGNAL(timeout()), this, SLOT(onChooseByDrag()));
|
connect(&_chooseByDragTimer, SIGNAL(timeout()), this, SLOT(onChooseByDrag()));
|
||||||
|
|
||||||
|
@ -1819,21 +1805,13 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : TWidget(parent)
|
||||||
_searchTimer.setSingleShot(true);
|
_searchTimer.setSingleShot(true);
|
||||||
connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchMessages()));
|
connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchMessages()));
|
||||||
|
|
||||||
_scroll.show();
|
_filter->setFocusPolicy(Qt::StrongFocus);
|
||||||
_filter.show();
|
_filter->customUpDown(true);
|
||||||
_filter.move(st::dialogsPadding.x(), st::dialogsFilterPadding);
|
|
||||||
_filter.setFocusPolicy(Qt::StrongFocus);
|
|
||||||
_filter.customUpDown(true);
|
|
||||||
_addContact->hide();
|
|
||||||
_newGroup->show();
|
|
||||||
_cancelSearch->hide();
|
_cancelSearch->hide();
|
||||||
_newGroup->move(width() - _newGroup->width() - st::dialogsPadding.x(), 0);
|
|
||||||
_addContact->move(width() - _addContact->width() - st::dialogsPadding.x(), 0);
|
|
||||||
_cancelSearch->move(width() - _cancelSearch->width() - st::dialogsPadding.x(), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsWidget::activate() {
|
void DialogsWidget::activate() {
|
||||||
_filter.setFocus();
|
_filter->setFocus();
|
||||||
_inner.activate();
|
_inner.activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1858,7 +1836,7 @@ void DialogsWidget::dlgUpdated(History *row, MsgId msgId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsWidget::dialogsToUp() {
|
void DialogsWidget::dialogsToUp() {
|
||||||
if (_filter.getLastText().trimmed().isEmpty()) {
|
if (_filter->getLastText().trimmed().isEmpty()) {
|
||||||
_scroll.scrollToY(0);
|
_scroll.scrollToY(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1873,9 +1851,8 @@ void DialogsWidget::showAnimated(Window::SlideDirection direction, const Window:
|
||||||
_a_show.stop();
|
_a_show.stop();
|
||||||
|
|
||||||
_scroll.hide();
|
_scroll.hide();
|
||||||
_filter.hide();
|
_filter->hide();
|
||||||
_cancelSearch->hide();
|
_cancelSearch->hide();
|
||||||
_newGroup->hide();
|
|
||||||
|
|
||||||
int delta = st::slideShift;
|
int delta = st::slideShift;
|
||||||
if (direction == Window::SlideDirection::FromLeft) {
|
if (direction == Window::SlideDirection::FromLeft) {
|
||||||
|
@ -1903,7 +1880,7 @@ void DialogsWidget::step_show(float64 ms, bool timer) {
|
||||||
_cacheUnder = _cacheOver = QPixmap();
|
_cacheUnder = _cacheOver = QPixmap();
|
||||||
|
|
||||||
_scroll.show();
|
_scroll.show();
|
||||||
_filter.show();
|
_filter->show();
|
||||||
_a_show.stop();
|
_a_show.stop();
|
||||||
|
|
||||||
onFilterUpdate();
|
onFilterUpdate();
|
||||||
|
@ -1930,8 +1907,8 @@ void DialogsWidget::updateNotifySettings(PeerData *peer) {
|
||||||
|
|
||||||
void DialogsWidget::notify_userIsContactChanged(UserData *user, bool fromThisApp) {
|
void DialogsWidget::notify_userIsContactChanged(UserData *user, bool fromThisApp) {
|
||||||
if (fromThisApp) {
|
if (fromThisApp) {
|
||||||
_filter.setText(QString());
|
_filter->setText(QString());
|
||||||
_filter.updatePlaceholder();
|
_filter->updatePlaceholder();
|
||||||
onFilterUpdate();
|
onFilterUpdate();
|
||||||
}
|
}
|
||||||
_inner.notify_userIsContactChanged(user, fromThisApp);
|
_inner.notify_userIsContactChanged(user, fromThisApp);
|
||||||
|
@ -2031,7 +2008,7 @@ bool DialogsWidget::dialogsFailed(const RPCError &error, mtpRequestId req) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DialogsWidget::onSearchMessages(bool searchCache) {
|
bool DialogsWidget::onSearchMessages(bool searchCache) {
|
||||||
QString q = _filter.getLastText().trimmed();
|
QString q = _filter->getLastText().trimmed();
|
||||||
if (q.isEmpty()) {
|
if (q.isEmpty()) {
|
||||||
if (_searchRequest) {
|
if (_searchRequest) {
|
||||||
MTP::cancel(_searchRequest);
|
MTP::cancel(_searchRequest);
|
||||||
|
@ -2098,16 +2075,39 @@ void DialogsWidget::onChooseByDrag() {
|
||||||
_inner.choosePeer();
|
_inner.choosePeer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogsWidget::showMainMenu() {
|
||||||
|
if (!_mainMenu) {
|
||||||
|
_mainMenu.create(this, st::dialogsMenu);
|
||||||
|
_mainMenu->addAction(lang(lng_create_group_title), [] {
|
||||||
|
App::wnd()->onShowNewGroup();
|
||||||
|
}, &st::dialogsMenuNewGroup);
|
||||||
|
_mainMenu->addAction(lang(lng_create_channel_title), [] {
|
||||||
|
App::wnd()->onShowNewChannel();
|
||||||
|
}, &st::dialogsMenuNewChannel);
|
||||||
|
_mainMenu->addAction(lang(lng_menu_contacts), [] {
|
||||||
|
Ui::showLayer(new ContactsBox());
|
||||||
|
}, &st::dialogsMenuContacts);
|
||||||
|
_mainMenu->addAction(lang(lng_menu_settings), [] {
|
||||||
|
App::wnd()->showSettings();
|
||||||
|
}, &st::dialogsMenuSettings);
|
||||||
|
_mainMenu->addAction(lang(lng_settings_faq), [] {
|
||||||
|
QDesktopServices::openUrl(telegramFaqLink());
|
||||||
|
}, &st::dialogsMenuHelp);
|
||||||
|
}
|
||||||
|
updateMainMenuGeometry();
|
||||||
|
_mainMenu->showAnimated();
|
||||||
|
}
|
||||||
|
|
||||||
void DialogsWidget::searchMessages(const QString &query, PeerData *inPeer) {
|
void DialogsWidget::searchMessages(const QString &query, PeerData *inPeer) {
|
||||||
if ((_filter.getLastText() != query) || (inPeer && inPeer != _searchInPeer && inPeer->migrateTo() != _searchInPeer)) {
|
if ((_filter->getLastText() != query) || (inPeer && inPeer != _searchInPeer && inPeer->migrateTo() != _searchInPeer)) {
|
||||||
if (inPeer) {
|
if (inPeer) {
|
||||||
onCancelSearch();
|
onCancelSearch();
|
||||||
_searchInPeer = inPeer->migrateTo() ? inPeer->migrateTo() : inPeer;
|
_searchInPeer = inPeer->migrateTo() ? inPeer->migrateTo() : inPeer;
|
||||||
_searchInMigrated = _searchInPeer ? _searchInPeer->migrateFrom() : 0;
|
_searchInMigrated = _searchInPeer ? _searchInPeer->migrateFrom() : 0;
|
||||||
_inner.searchInPeer(_searchInPeer);
|
_inner.searchInPeer(_searchInPeer);
|
||||||
}
|
}
|
||||||
_filter.setText(query);
|
_filter->setText(query);
|
||||||
_filter.updatePlaceholder();
|
_filter->updatePlaceholder();
|
||||||
onFilterUpdate(true);
|
onFilterUpdate(true);
|
||||||
_searchTimer.stop();
|
_searchTimer.stop();
|
||||||
onSearchMessages();
|
onSearchMessages();
|
||||||
|
@ -2371,17 +2371,15 @@ void DialogsWidget::onListScroll() {
|
||||||
void DialogsWidget::onFilterUpdate(bool force) {
|
void DialogsWidget::onFilterUpdate(bool force) {
|
||||||
if (_a_show.animating() && !force) return;
|
if (_a_show.animating() && !force) return;
|
||||||
|
|
||||||
QString filterText = _filter.getLastText();
|
QString filterText = _filter->getLastText();
|
||||||
_inner.onFilterUpdate(filterText, force);
|
_inner.onFilterUpdate(filterText, force);
|
||||||
if (filterText.isEmpty()) {
|
if (filterText.isEmpty()) {
|
||||||
_searchCache.clear();
|
_searchCache.clear();
|
||||||
_searchQueries.clear();
|
_searchQueries.clear();
|
||||||
_searchQuery = QString();
|
_searchQuery = QString();
|
||||||
_cancelSearch->hide();
|
_cancelSearch->hide();
|
||||||
_newGroup->show();
|
|
||||||
} else if (_cancelSearch->isHidden()) {
|
} else if (_cancelSearch->isHidden()) {
|
||||||
_cancelSearch->show();
|
_cancelSearch->show();
|
||||||
_newGroup->hide();
|
|
||||||
}
|
}
|
||||||
if (filterText.size() < MinUsernameLength) {
|
if (filterText.size() < MinUsernameLength) {
|
||||||
_peopleCache.clear();
|
_peopleCache.clear();
|
||||||
|
@ -2399,8 +2397,8 @@ void DialogsWidget::searchInPeer(PeerData *peer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsWidget::onFilterCursorMoved(int from, int to) {
|
void DialogsWidget::onFilterCursorMoved(int from, int to) {
|
||||||
if (to < 0) to = _filter.cursorPosition();
|
if (to < 0) to = _filter->cursorPosition();
|
||||||
QString t = _filter.getLastText();
|
QString t = _filter->getLastText();
|
||||||
QStringRef r;
|
QStringRef r;
|
||||||
for (int start = to; start > 0;) {
|
for (int start = to; start > 0;) {
|
||||||
--start;
|
--start;
|
||||||
|
@ -2415,8 +2413,8 @@ void DialogsWidget::onFilterCursorMoved(int from, int to) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsWidget::onCompleteHashtag(QString tag) {
|
void DialogsWidget::onCompleteHashtag(QString tag) {
|
||||||
QString t = _filter.getLastText(), r;
|
QString t = _filter->getLastText(), r;
|
||||||
int cur = _filter.cursorPosition();
|
int cur = _filter->cursorPosition();
|
||||||
for (int start = cur; start > 0;) {
|
for (int start = cur; start > 0;) {
|
||||||
--start;
|
--start;
|
||||||
if (t.size() <= start) break;
|
if (t.size() <= start) break;
|
||||||
|
@ -2427,8 +2425,8 @@ void DialogsWidget::onCompleteHashtag(QString tag) {
|
||||||
}
|
}
|
||||||
if (cur - start - 1 == tag.size() && cur < t.size() && t.at(cur) == ' ') ++cur;
|
if (cur - start - 1 == tag.size() && cur < t.size() && t.at(cur) == ' ') ++cur;
|
||||||
r = t.mid(0, start + 1) + tag + ' ' + t.mid(cur);
|
r = t.mid(0, start + 1) + tag + ' ' + t.mid(cur);
|
||||||
_filter.setText(r);
|
_filter->setText(r);
|
||||||
_filter.setCursorPosition(start + 1 + tag.size() + 1);
|
_filter->setCursorPosition(start + 1 + tag.size() + 1);
|
||||||
onFilterUpdate(true);
|
onFilterUpdate(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2436,22 +2434,23 @@ void DialogsWidget::onCompleteHashtag(QString tag) {
|
||||||
}
|
}
|
||||||
if (!t.at(start).isLetterOrNumber() && t.at(start) != '_') break;
|
if (!t.at(start).isLetterOrNumber() && t.at(start) != '_') break;
|
||||||
}
|
}
|
||||||
_filter.setText(t.mid(0, cur) + '#' + tag + ' ' + t.mid(cur));
|
_filter->setText(t.mid(0, cur) + '#' + tag + ' ' + t.mid(cur));
|
||||||
_filter.setCursorPosition(cur + 1 + tag.size() + 1);
|
_filter->setCursorPosition(cur + 1 + tag.size() + 1);
|
||||||
onFilterUpdate(true);
|
onFilterUpdate(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsWidget::resizeEvent(QResizeEvent *e) {
|
void DialogsWidget::resizeEvent(QResizeEvent *e) {
|
||||||
int32 w = width();
|
int32 w = width();
|
||||||
_filter.setGeometry(st::dialogsPadding.x(), st::dialogsFilterPadding, w - 2 * st::dialogsPadding.x(), _filter.height());
|
_filter->setGeometryToLeft(st::dialogsFilterPadding.x() * 2 + _mainMenuToggle->width(), st::dialogsFilterPadding.y(), w - 3 * st::dialogsFilterPadding.x() - _mainMenuToggle->width(), _filter->height());
|
||||||
_newGroup->move(w - _newGroup->width() - st::dialogsPadding.x(), _filter.y());
|
_mainMenuToggle->moveToLeft(st::dialogsFilterPadding.x(), _filter->y());
|
||||||
_addContact->move(w - _addContact->width() - st::dialogsPadding.x(), _filter.y());
|
_cancelSearch->moveToRight(st::dialogsFilterPadding.x(), _filter->y());
|
||||||
_cancelSearch->move(w - _cancelSearch->width() - st::dialogsPadding.x(), _filter.y());
|
_scroll.move(0, _filter->height() + 2 * st::dialogsFilterPadding.y());
|
||||||
_scroll.move(0, _filter.height() + 2 * st::dialogsFilterPadding);
|
|
||||||
|
updateMainMenuGeometry();
|
||||||
|
|
||||||
int32 addToY = App::main() ? App::main()->contentScrollAddToY() : 0;
|
int32 addToY = App::main() ? App::main()->contentScrollAddToY() : 0;
|
||||||
int32 newScrollY = _scroll.scrollTop() + addToY;
|
int32 newScrollY = _scroll.scrollTop() + addToY;
|
||||||
_scroll.resize(w, height() - _filter.y() - _filter.height() - st::dialogsFilterPadding - st::dialogsPadding.y());
|
_scroll.resize(w, height() - _filter->y() - _filter->height() - st::dialogsFilterPadding.y() - st::dialogsPadding.y());
|
||||||
if (addToY) {
|
if (addToY) {
|
||||||
_scroll.scrollToY(newScrollY);
|
_scroll.scrollToY(newScrollY);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2459,6 +2458,12 @@ void DialogsWidget::resizeEvent(QResizeEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogsWidget::updateMainMenuGeometry() {
|
||||||
|
if (!_mainMenu) return;
|
||||||
|
|
||||||
|
_mainMenu->moveToLeft(st::dialogsMenuPosition.x(), st::dialogsMenuPosition.y());
|
||||||
|
}
|
||||||
|
|
||||||
void DialogsWidget::keyPressEvent(QKeyEvent *e) {
|
void DialogsWidget::keyPressEvent(QKeyEvent *e) {
|
||||||
if (e->key() == Qt::Key_Escape) {
|
if (e->key() == Qt::Key_Escape) {
|
||||||
e->ignore();
|
e->ignore();
|
||||||
|
@ -2548,16 +2553,8 @@ Dialogs::IndexedList *DialogsWidget::dialogsList() {
|
||||||
return _inner.dialogsList();
|
return _inner.dialogsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsWidget::onAddContact() {
|
|
||||||
Ui::showLayer(new AddContactBox(), KeepOtherLayers);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogsWidget::onNewGroup() {
|
|
||||||
Ui::showLayer(new NewGroupBox());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DialogsWidget::onCancelSearch() {
|
bool DialogsWidget::onCancelSearch() {
|
||||||
bool clearing = !_filter.getLastText().isEmpty();
|
bool clearing = !_filter->getLastText().isEmpty();
|
||||||
if (_searchRequest) {
|
if (_searchRequest) {
|
||||||
MTP::cancel(_searchRequest);
|
MTP::cancel(_searchRequest);
|
||||||
_searchRequest = 0;
|
_searchRequest = 0;
|
||||||
|
@ -2571,8 +2568,8 @@ bool DialogsWidget::onCancelSearch() {
|
||||||
clearing = true;
|
clearing = true;
|
||||||
}
|
}
|
||||||
_inner.clearFilter();
|
_inner.clearFilter();
|
||||||
_filter.clear();
|
_filter->clear();
|
||||||
_filter.updatePlaceholder();
|
_filter->updatePlaceholder();
|
||||||
onFilterUpdate();
|
onFilterUpdate();
|
||||||
return clearing;
|
return clearing;
|
||||||
}
|
}
|
||||||
|
@ -2590,8 +2587,8 @@ void DialogsWidget::onCancelSearchInPeer() {
|
||||||
_inner.searchInPeer(0);
|
_inner.searchInPeer(0);
|
||||||
}
|
}
|
||||||
_inner.clearFilter();
|
_inner.clearFilter();
|
||||||
_filter.clear();
|
_filter->clear();
|
||||||
_filter.updatePlaceholder();
|
_filter->updatePlaceholder();
|
||||||
onFilterUpdate();
|
onFilterUpdate();
|
||||||
if (!Adaptive::OneColumn() && !App::main()->selectingPeer()) {
|
if (!Adaptive::OneColumn() && !App::main()->selectingPeer()) {
|
||||||
emit cancelled();
|
emit cancelled();
|
||||||
|
|
|
@ -31,10 +31,9 @@ class IndexedList;
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class IconButton;
|
class IconButton;
|
||||||
class PopupMenu;
|
class PopupMenu;
|
||||||
|
class DropdownMenu;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
class MainWidget;
|
|
||||||
|
|
||||||
enum DialogsSearchRequestType {
|
enum DialogsSearchRequestType {
|
||||||
DialogsSearchFromStart,
|
DialogsSearchFromStart,
|
||||||
DialogsSearchFromOffset,
|
DialogsSearchFromOffset,
|
||||||
|
@ -48,7 +47,7 @@ class DialogsInner : public SplittedWidget, public RPCSender, private base::Subs
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DialogsInner(QWidget *parent, MainWidget *main);
|
DialogsInner(QWidget *parent, QWidget *main);
|
||||||
|
|
||||||
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
||||||
void addSavedPeersAfter(const QDateTime &date);
|
void addSavedPeersAfter(const QDateTime &date);
|
||||||
|
@ -238,7 +237,7 @@ class DialogsWidget : public TWidget, public RPCSender {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DialogsWidget(MainWidget *parent);
|
DialogsWidget(QWidget *parent);
|
||||||
|
|
||||||
void dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpRequestId req);
|
void dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpRequestId req);
|
||||||
void contactsReceived(const MTPcontacts_Contacts &contacts);
|
void contactsReceived(const MTPcontacts_Contacts &contacts);
|
||||||
|
@ -295,17 +294,13 @@ public:
|
||||||
void notify_historyMuteUpdated(History *history);
|
void notify_historyMuteUpdated(History *history);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void cancelled();
|
void cancelled();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onCancel();
|
void onCancel();
|
||||||
void onListScroll();
|
void onListScroll();
|
||||||
void activate();
|
void activate();
|
||||||
void onFilterUpdate(bool force = false);
|
void onFilterUpdate(bool force = false);
|
||||||
void onAddContact();
|
|
||||||
void onNewGroup();
|
|
||||||
bool onCancelSearch();
|
bool onCancelSearch();
|
||||||
void onCancelSearchInPeer();
|
void onCancelSearchInPeer();
|
||||||
|
|
||||||
|
@ -319,8 +314,11 @@ public slots:
|
||||||
void onChooseByDrag();
|
void onChooseByDrag();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void showMainMenu();
|
||||||
|
void updateMainMenuGeometry();
|
||||||
|
|
||||||
bool _dragInScroll, _dragForward;
|
bool _dragInScroll = false;
|
||||||
|
bool _dragForward = false;
|
||||||
QTimer _chooseByDragTimer;
|
QTimer _chooseByDragTimer;
|
||||||
|
|
||||||
void unreadCountsReceived(const QVector<MTPDialog> &dialogs);
|
void unreadCountsReceived(const QVector<MTPDialog> &dialogs);
|
||||||
|
@ -329,15 +327,16 @@ private:
|
||||||
bool searchFailed(DialogsSearchRequestType type, const RPCError &error, mtpRequestId req);
|
bool searchFailed(DialogsSearchRequestType type, const RPCError &error, mtpRequestId req);
|
||||||
bool peopleFailed(const RPCError &error, mtpRequestId req);
|
bool peopleFailed(const RPCError &error, mtpRequestId req);
|
||||||
|
|
||||||
bool _dialogsFull;
|
bool _dialogsFull = false;
|
||||||
int32 _dialogsOffsetDate;
|
int32 _dialogsOffsetDate = 0;
|
||||||
MsgId _dialogsOffsetId;
|
MsgId _dialogsOffsetId = 0;
|
||||||
PeerData *_dialogsOffsetPeer;
|
PeerData *_dialogsOffsetPeer = nullptr;
|
||||||
mtpRequestId _dialogsRequest, _contactsRequest;
|
mtpRequestId _dialogsRequest = 0;
|
||||||
|
mtpRequestId _contactsRequest = 0;
|
||||||
|
|
||||||
FlatInput _filter;
|
ChildWidget<Ui::IconButton> _mainMenuToggle;
|
||||||
ChildWidget<Ui::IconButton> _newGroup;
|
ChildWidget<Ui::DropdownMenu> _mainMenu = { nullptr };
|
||||||
ChildWidget<Ui::IconButton> _addContact;
|
ChildWidget<FlatInput> _filter;
|
||||||
ChildWidget<Ui::IconButton> _cancelSearch;
|
ChildWidget<Ui::IconButton> _cancelSearch;
|
||||||
ScrollArea _scroll;
|
ScrollArea _scroll;
|
||||||
DialogsInner _inner;
|
DialogsInner _inner;
|
||||||
|
@ -347,11 +346,14 @@ private:
|
||||||
anim::ivalue a_coordUnder, a_coordOver;
|
anim::ivalue a_coordUnder, a_coordOver;
|
||||||
anim::fvalue a_progress;
|
anim::fvalue a_progress;
|
||||||
|
|
||||||
PeerData *_searchInPeer, *_searchInMigrated;
|
PeerData *_searchInPeer = nullptr;
|
||||||
|
PeerData *_searchInMigrated = nullptr;
|
||||||
|
|
||||||
QTimer _searchTimer;
|
QTimer _searchTimer;
|
||||||
QString _searchQuery, _peopleQuery;
|
QString _searchQuery, _peopleQuery;
|
||||||
bool _searchFull, _searchFullMigrated, _peopleFull;
|
bool _searchFull = false;
|
||||||
|
bool _searchFullMigrated = false;
|
||||||
|
bool _peopleFull = false;
|
||||||
mtpRequestId _searchRequest, _peopleRequest;
|
mtpRequestId _searchRequest, _peopleRequest;
|
||||||
|
|
||||||
typedef QMap<QString, MTPmessages_Messages> SearchCache;
|
typedef QMap<QString, MTPmessages_Messages> SearchCache;
|
||||||
|
|
|
@ -151,11 +151,11 @@ introBackButton: IconButton {
|
||||||
|
|
||||||
icon: icon {
|
icon: icon {
|
||||||
{ size(40px, 40px), #f2f2f2 },
|
{ size(40px, 40px), #f2f2f2 },
|
||||||
{ "title_previous", #adadad, point(12px, 12px) },
|
{ "title_back", #adadad, point(12px, 12px) },
|
||||||
};
|
};
|
||||||
iconOver: icon {
|
iconOver: icon {
|
||||||
{ size(40px, 40px), #eeeeee },
|
{ size(40px, 40px), #eeeeee },
|
||||||
{ "title_previous", #969696, point(12px, 12px) },
|
{ "title_back", #969696, point(12px, 12px) },
|
||||||
};
|
};
|
||||||
|
|
||||||
iconPosition: point(0px, 0px);
|
iconPosition: point(0px, 0px);
|
||||||
|
|
|
@ -83,6 +83,7 @@ MainWidget::MainWidget(QWidget *parent) : TWidget(parent)
|
||||||
updateScrollColors();
|
updateScrollColors();
|
||||||
|
|
||||||
connect(_dialogs, SIGNAL(cancelled()), this, SLOT(dialogsCancelled()));
|
connect(_dialogs, SIGNAL(cancelled()), this, SLOT(dialogsCancelled()));
|
||||||
|
connect(this, SIGNAL(dialogsUpdated()), this, SLOT(onListScroll()));
|
||||||
connect(_history, SIGNAL(cancelled()), _dialogs, SLOT(activate()));
|
connect(_history, SIGNAL(cancelled()), _dialogs, SLOT(activate()));
|
||||||
connect(this, SIGNAL(peerPhotoChanged(PeerData*)), this, SIGNAL(dialogsUpdated()));
|
connect(this, SIGNAL(peerPhotoChanged(PeerData*)), this, SIGNAL(dialogsUpdated()));
|
||||||
connect(&noUpdatesTimer, SIGNAL(timeout()), this, SLOT(mtpPing()));
|
connect(&noUpdatesTimer, SIGNAL(timeout()), this, SLOT(mtpPing()));
|
||||||
|
@ -1448,14 +1449,6 @@ void MainWidget::checkLastUpdate(bool afterSleep) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::showAddContact() {
|
|
||||||
_dialogs->onAddContact();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::showNewGroup() {
|
|
||||||
_dialogs->onNewGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::overviewLoaded(History *history, const MTPmessages_Messages &result, mtpRequestId req) {
|
void MainWidget::overviewLoaded(History *history, const MTPmessages_Messages &result, mtpRequestId req) {
|
||||||
OverviewsPreload::iterator it;
|
OverviewsPreload::iterator it;
|
||||||
MediaOverviewType type = OverviewCount;
|
MediaOverviewType type = OverviewCount;
|
||||||
|
|
|
@ -312,8 +312,6 @@ public:
|
||||||
void loadMediaBack(PeerData *peer, MediaOverviewType type, bool many = false);
|
void loadMediaBack(PeerData *peer, MediaOverviewType type, bool many = false);
|
||||||
|
|
||||||
void checkLastUpdate(bool afterSleep);
|
void checkLastUpdate(bool afterSleep);
|
||||||
void showAddContact();
|
|
||||||
void showNewGroup();
|
|
||||||
|
|
||||||
void serviceNotification(const QString &msg, const MTPMessageMedia &media);
|
void serviceNotification(const QString &msg, const MTPMessageMedia &media);
|
||||||
void serviceHistoryDone(const MTPmessages_Messages &msgs);
|
void serviceHistoryDone(const MTPmessages_Messages &msgs);
|
||||||
|
|
|
@ -44,7 +44,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "settings/settings_widget.h"
|
#include "settings/settings_widget.h"
|
||||||
#include "platform/platform_notifications_manager.h"
|
#include "platform/platform_notifications_manager.h"
|
||||||
#include "platform/platform_window_title.h"
|
|
||||||
#include "window/notifications_manager.h"
|
#include "window/notifications_manager.h"
|
||||||
#include "window/window_theme.h"
|
#include "window/window_theme.h"
|
||||||
#include "window/window_theme_warning.h"
|
#include "window/window_theme_warning.h"
|
||||||
|
@ -86,7 +85,7 @@ void ConnectingWidget::onReconnect() {
|
||||||
MTP::restart();
|
MTP::restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::MainWindow() : Platform::MainWindow(), _body(this) {
|
MainWindow::MainWindow() {
|
||||||
icon16 = icon256.scaledToWidth(16, Qt::SmoothTransformation);
|
icon16 = icon256.scaledToWidth(16, Qt::SmoothTransformation);
|
||||||
icon32 = icon256.scaledToWidth(32, Qt::SmoothTransformation);
|
icon32 = icon256.scaledToWidth(32, Qt::SmoothTransformation);
|
||||||
icon64 = icon256.scaledToWidth(64, Qt::SmoothTransformation);
|
icon64 = icon256.scaledToWidth(64, Qt::SmoothTransformation);
|
||||||
|
@ -105,15 +104,9 @@ MainWindow::MainWindow() : Platform::MainWindow(), _body(this) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (objectName().isEmpty()) {
|
resize(st::windowDefaultWidth, st::windowDefaultHeight);
|
||||||
setObjectName(qsl("MainWindow"));
|
|
||||||
}
|
|
||||||
resize(st::windowDefWidth, st::windowDefHeight);
|
|
||||||
|
|
||||||
setLocale(QLocale(QLocale::English, QLocale::UnitedStates));
|
setLocale(QLocale(QLocale::English, QLocale::UnitedStates));
|
||||||
setCentralWidget(_body);
|
|
||||||
|
|
||||||
QMetaObject::connectSlotsByName(this);
|
|
||||||
|
|
||||||
_inactiveTimer.setSingleShot(true);
|
_inactiveTimer.setSingleShot(true);
|
||||||
connect(&_inactiveTimer, SIGNAL(timeout()), this, SLOT(onInactiveTimer()));
|
connect(&_inactiveTimer, SIGNAL(timeout()), this, SLOT(onInactiveTimer()));
|
||||||
|
@ -162,26 +155,17 @@ void MainWindow::onStateChanged(Qt::WindowState state) {
|
||||||
if (state == Qt::WindowMinimized && cWorkMode() == dbiwmTrayOnly) {
|
if (state == Qt::WindowMinimized && cWorkMode() == dbiwmTrayOnly) {
|
||||||
App::wnd()->minimizeToTray();
|
App::wnd()->minimizeToTray();
|
||||||
}
|
}
|
||||||
psSavePosition(state);
|
savePosition(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::init() {
|
void MainWindow::init() {
|
||||||
psInitFrameless();
|
Platform::MainWindow::init();
|
||||||
setWindowIcon(wndIcon);
|
|
||||||
|
|
||||||
_title = Platform::CreateTitleWidget(this);
|
setWindowIcon(wndIcon);
|
||||||
|
|
||||||
Application::instance()->installEventFilter(this);
|
Application::instance()->installEventFilter(this);
|
||||||
connect(windowHandle(), SIGNAL(windowStateChanged(Qt::WindowState)), this, SLOT(onStateChanged(Qt::WindowState)));
|
connect(windowHandle(), SIGNAL(windowStateChanged(Qt::WindowState)), this, SLOT(onStateChanged(Qt::WindowState)));
|
||||||
connect(windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWindowActiveChanged()), Qt::QueuedConnection);
|
connect(windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWindowActiveChanged()), Qt::QueuedConnection);
|
||||||
|
|
||||||
QPalette p(palette());
|
|
||||||
p.setColor(QPalette::Window, st::windowBg->c);
|
|
||||||
setPalette(p);
|
|
||||||
|
|
||||||
setMinimumWidth(st::windowMinWidth);
|
|
||||||
setMinimumHeight(st::windowMinHeight);
|
|
||||||
psInitSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onWindowActiveChanged() {
|
void MainWindow::onWindowActiveChanged() {
|
||||||
|
@ -241,9 +225,7 @@ void MainWindow::clearWidgets() {
|
||||||
|
|
||||||
QPixmap MainWindow::grabInner() {
|
QPixmap MainWindow::grabInner() {
|
||||||
QPixmap result;
|
QPixmap result;
|
||||||
if (_settings) {
|
if (_intro) {
|
||||||
result = myGrab(_settings);
|
|
||||||
} else if (_intro) {
|
|
||||||
result = myGrab(_intro);
|
result = myGrab(_intro);
|
||||||
} else if (_main) {
|
} else if (_main) {
|
||||||
result = myGrab(_main);
|
result = myGrab(_main);
|
||||||
|
@ -274,13 +256,13 @@ void MainWindow::clearPasscode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupPasscode(bool anim) {
|
void MainWindow::setupPasscode(bool anim) {
|
||||||
QPixmap bg = grabInner();
|
auto bg = grabInner();
|
||||||
|
|
||||||
if (_passcode) {
|
if (_passcode) {
|
||||||
_passcode->stop_show();
|
_passcode->stop_show();
|
||||||
_passcode.destroyDelayed();
|
_passcode.destroyDelayed();
|
||||||
}
|
}
|
||||||
_passcode.create(_body);
|
_passcode.create(bodyWidget());
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
|
||||||
if (_main) _main->hide();
|
if (_main) _main->hide();
|
||||||
|
@ -332,7 +314,7 @@ void MainWindow::setupIntro(bool anim) {
|
||||||
QPixmap bg = anim ? grabInner() : QPixmap();
|
QPixmap bg = anim ? grabInner() : QPixmap();
|
||||||
|
|
||||||
clearWidgets();
|
clearWidgets();
|
||||||
_intro.create(_body);
|
_intro.create(bodyWidget());
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
|
||||||
if (anim) {
|
if (anim) {
|
||||||
|
@ -382,7 +364,7 @@ void MainWindow::sendServiceHistoryRequest() {
|
||||||
void MainWindow::setupMain(bool anim, const MTPUser *self) {
|
void MainWindow::setupMain(bool anim, const MTPUser *self) {
|
||||||
QPixmap bg = anim ? grabInner() : QPixmap();
|
QPixmap bg = anim ? grabInner() : QPixmap();
|
||||||
clearWidgets();
|
clearWidgets();
|
||||||
_main.create(_body);
|
_main.create(bodyWidget());
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
|
||||||
if (anim) {
|
if (anim) {
|
||||||
|
@ -418,7 +400,7 @@ void MainWindow::showSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_layerBg) {
|
if (!_layerBg) {
|
||||||
_layerBg.create(_body);
|
_layerBg.create(bodyWidget());
|
||||||
}
|
}
|
||||||
_settings.create(this);
|
_settings.create(this);
|
||||||
connect(_settings, SIGNAL(destroyed(QObject*)), this, SLOT(onSettingsDestroyed(QObject*)));
|
connect(_settings, SIGNAL(destroyed(QObject*)), this, SLOT(onSettingsDestroyed(QObject*)));
|
||||||
|
@ -492,7 +474,7 @@ void MainWindow::showDocument(DocumentData *doc, HistoryItem *item) {
|
||||||
void MainWindow::ui_showLayer(LayerWidget *box, ShowLayerOptions options) {
|
void MainWindow::ui_showLayer(LayerWidget *box, ShowLayerOptions options) {
|
||||||
if (box) {
|
if (box) {
|
||||||
if (!_layerBg) {
|
if (!_layerBg) {
|
||||||
_layerBg.create(_body);
|
_layerBg.create(bodyWidget());
|
||||||
}
|
}
|
||||||
if (options.testFlag(KeepOtherLayers)) {
|
if (options.testFlag(KeepOtherLayers)) {
|
||||||
if (options.testFlag(ShowAfterOtherLayers)) {
|
if (options.testFlag(ShowAfterOtherLayers)) {
|
||||||
|
@ -532,7 +514,7 @@ bool MainWindow::ui_isMediaViewShown() {
|
||||||
void MainWindow::ui_showMediaPreview(DocumentData *document) {
|
void MainWindow::ui_showMediaPreview(DocumentData *document) {
|
||||||
if (!document || ((!document->isAnimation() || !document->loaded()) && !document->sticker())) return;
|
if (!document || ((!document->isAnimation() || !document->loaded()) && !document->sticker())) return;
|
||||||
if (!_mediaPreview) {
|
if (!_mediaPreview) {
|
||||||
_mediaPreview.create(_body);
|
_mediaPreview.create(bodyWidget());
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
if (_mediaPreview->isHidden()) {
|
if (_mediaPreview->isHidden()) {
|
||||||
|
@ -544,7 +526,7 @@ void MainWindow::ui_showMediaPreview(DocumentData *document) {
|
||||||
void MainWindow::ui_showMediaPreview(PhotoData *photo) {
|
void MainWindow::ui_showMediaPreview(PhotoData *photo) {
|
||||||
if (!photo) return;
|
if (!photo) return;
|
||||||
if (!_mediaPreview) {
|
if (!_mediaPreview) {
|
||||||
_mediaPreview.create(_body);
|
_mediaPreview.create(bodyWidget());
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
if (_mediaPreview->isHidden()) {
|
if (_mediaPreview->isHidden()) {
|
||||||
|
@ -571,7 +553,7 @@ void MainWindow::showConnecting(const QString &text, const QString &reconnect) {
|
||||||
if (_connecting) {
|
if (_connecting) {
|
||||||
_connecting->set(text, reconnect);
|
_connecting->set(text, reconnect);
|
||||||
} else {
|
} else {
|
||||||
_connecting.create(_body, text, reconnect);
|
_connecting.create(bodyWidget(), text, reconnect);
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
fixOrder();
|
fixOrder();
|
||||||
}
|
}
|
||||||
|
@ -586,15 +568,13 @@ void MainWindow::hideConnecting() {
|
||||||
void MainWindow::themeUpdated(const Window::Theme::BackgroundUpdate &data) {
|
void MainWindow::themeUpdated(const Window::Theme::BackgroundUpdate &data) {
|
||||||
using Type = Window::Theme::BackgroundUpdate::Type;
|
using Type = Window::Theme::BackgroundUpdate::Type;
|
||||||
if (data.type == Type::TestingTheme) {
|
if (data.type == Type::TestingTheme) {
|
||||||
if (_title) _title->update();
|
|
||||||
if (!_testingThemeWarning) {
|
if (!_testingThemeWarning) {
|
||||||
_testingThemeWarning.create(_body);
|
_testingThemeWarning.create(bodyWidget());
|
||||||
_testingThemeWarning->setGeometry(rect());
|
_testingThemeWarning->setGeometry(rect());
|
||||||
_testingThemeWarning->setHiddenCallback([this] { _testingThemeWarning.destroyDelayed(); });
|
_testingThemeWarning->setHiddenCallback([this] { _testingThemeWarning.destroyDelayed(); });
|
||||||
}
|
}
|
||||||
_testingThemeWarning->showAnimated();
|
_testingThemeWarning->showAnimated();
|
||||||
} else if (data.type == Type::RevertingTheme || data.type == Type::ApplyingTheme) {
|
} else if (data.type == Type::RevertingTheme || data.type == Type::ApplyingTheme) {
|
||||||
if (_title) _title->update();
|
|
||||||
_testingThemeWarning->hideAnimated();
|
_testingThemeWarning->hideAnimated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -659,44 +639,6 @@ void MainWindow::setInnerFocus() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::HitTestResult MainWindow::hitTest(const QPoint &p) const {
|
|
||||||
int x(p.x()), y(p.y()), w(width()), h(height());
|
|
||||||
|
|
||||||
const int32 raw = psResizeRowWidth();
|
|
||||||
if (!windowState().testFlag(Qt::WindowMaximized)) {
|
|
||||||
if (y < raw) {
|
|
||||||
if (x < raw) {
|
|
||||||
return Window::HitTestResult::TopLeft;
|
|
||||||
} else if (x > w - raw - 1) {
|
|
||||||
return Window::HitTestResult::TopRight;
|
|
||||||
}
|
|
||||||
return Window::HitTestResult::Top;
|
|
||||||
} else if (y > h - raw - 1) {
|
|
||||||
if (x < raw) {
|
|
||||||
return Window::HitTestResult::BottomLeft;
|
|
||||||
} else if (x > w - raw - 1) {
|
|
||||||
return Window::HitTestResult::BottomRight;
|
|
||||||
}
|
|
||||||
return Window::HitTestResult::Bottom;
|
|
||||||
} else if (x < raw) {
|
|
||||||
return Window::HitTestResult::Left;
|
|
||||||
} else if (x > w - raw - 1) {
|
|
||||||
return Window::HitTestResult::Right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto titleTest = _title ? _title->hitTest(p - _title->geometry().topLeft()) : Window::HitTestResult::None;
|
|
||||||
if (titleTest != Window::HitTestResult::None) {
|
|
||||||
return titleTest;
|
|
||||||
} else if (x >= 0 && y >= 0 && x < w && y < h) {
|
|
||||||
return Window::HitTestResult::Client;
|
|
||||||
}
|
|
||||||
return Window::HitTestResult::None;
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect MainWindow::iconRect() const {
|
|
||||||
return _title ? _title->iconRect() : QRect();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::eventFilter(QObject *obj, QEvent *e) {
|
bool MainWindow::eventFilter(QObject *obj, QEvent *e) {
|
||||||
switch (e->type()) {
|
switch (e->type()) {
|
||||||
case QEvent::MouseButtonPress:
|
case QEvent::MouseButtonPress:
|
||||||
|
@ -757,7 +699,7 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *e) {
|
||||||
case QEvent::Move:
|
case QEvent::Move:
|
||||||
case QEvent::Resize:
|
case QEvent::Resize:
|
||||||
if (obj == this) {
|
if (obj == this) {
|
||||||
psUpdatedPosition();
|
positionUpdated();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -821,13 +763,17 @@ void MainWindow::updateTrayMenu(bool force) {
|
||||||
void MainWindow::onShowAddContact() {
|
void MainWindow::onShowAddContact() {
|
||||||
if (isHidden()) showFromTray();
|
if (isHidden()) showFromTray();
|
||||||
|
|
||||||
if (_main) _main->showAddContact();
|
if (App::self()) {
|
||||||
|
Ui::showLayer(new AddContactBox(), KeepOtherLayers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onShowNewGroup() {
|
void MainWindow::onShowNewGroup() {
|
||||||
if (isHidden()) showFromTray();
|
if (isHidden()) showFromTray();
|
||||||
|
|
||||||
if (_main) Ui::showLayer(new GroupInfoBox(CreatingGroupGroup, false), KeepOtherLayers);
|
if (App::self()) {
|
||||||
|
Ui::showLayer(new GroupInfoBox(CreatingGroupGroup, false), KeepOtherLayers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onShowNewChannel() {
|
void MainWindow::onShowNewChannel() {
|
||||||
|
@ -906,7 +852,6 @@ void MainWindow::layerFinishedHide(LayerStackWidget *was) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::fixOrder() {
|
void MainWindow::fixOrder() {
|
||||||
if (_title) _title->raise();
|
|
||||||
if (_layerBg) _layerBg->raise();
|
if (_layerBg) _layerBg->raise();
|
||||||
if (_mediaPreview) _mediaPreview->raise();
|
if (_mediaPreview) _mediaPreview->raise();
|
||||||
if (_connecting) _connecting->raise();
|
if (_connecting) _connecting->raise();
|
||||||
|
@ -980,7 +925,7 @@ void MainWindow::closeEvent(QCloseEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::resizeEvent(QResizeEvent *e) {
|
void MainWindow::resizeEvent(QResizeEvent *e) {
|
||||||
if (!_title) return;
|
Platform::MainWindow::resizeEvent(e);
|
||||||
|
|
||||||
Adaptive::Layout layout = Adaptive::OneColumnLayout;
|
Adaptive::Layout layout = Adaptive::OneColumnLayout;
|
||||||
if (width() > st::adaptiveWideWidth) {
|
if (width() > st::adaptiveWideWidth) {
|
||||||
|
@ -993,17 +938,11 @@ void MainWindow::resizeEvent(QResizeEvent *e) {
|
||||||
Adaptive::Changed().notify(true);
|
Adaptive::Changed().notify(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto bodyTop = 0;
|
|
||||||
if (_title) {
|
|
||||||
_title->setGeometry(0, bodyTop, width(), st::titleHeight);
|
|
||||||
bodyTop += _title->height();
|
|
||||||
}
|
|
||||||
_body->setGeometry(0, bodyTop, width(), height() - bodyTop);
|
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateControlsGeometry() {
|
void MainWindow::updateControlsGeometry() {
|
||||||
auto body = _body->rect();
|
auto body = bodyWidget()->rect();
|
||||||
if (_passcode) _passcode->setGeometry(body);
|
if (_passcode) _passcode->setGeometry(body);
|
||||||
if (_main) _main->setGeometry(body);
|
if (_main) _main->setGeometry(body);
|
||||||
if (_intro) _intro->setGeometry(body);
|
if (_intro) _intro->setGeometry(body);
|
||||||
|
|
|
@ -23,7 +23,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "pspecific.h"
|
#include "pspecific.h"
|
||||||
#include "ui/effects/rect_shadow.h"
|
#include "ui/effects/rect_shadow.h"
|
||||||
#include "platform/platform_main_window.h"
|
#include "platform/platform_main_window.h"
|
||||||
#include "window/window_title.h"
|
|
||||||
#include "core/single_timer.h"
|
#include "core/single_timer.h"
|
||||||
|
|
||||||
class MediaView;
|
class MediaView;
|
||||||
|
@ -71,7 +70,7 @@ private:
|
||||||
|
|
||||||
class MediaPreviewWidget;
|
class MediaPreviewWidget;
|
||||||
|
|
||||||
class MainWindow : public Platform::MainWindow, private base::Subscriber {
|
class MainWindow : public Platform::MainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -97,9 +96,6 @@ public:
|
||||||
|
|
||||||
void mtpStateChanged(int32 dc, int32 state);
|
void mtpStateChanged(int32 dc, int32 state);
|
||||||
|
|
||||||
Window::HitTestResult hitTest(const QPoint &p) const;
|
|
||||||
QRect iconRect() const;
|
|
||||||
|
|
||||||
IntroWidget *introWidget();
|
IntroWidget *introWidget();
|
||||||
MainWidget *mainWidget();
|
MainWidget *mainWidget();
|
||||||
PasscodeWidget *passcodeWidget();
|
PasscodeWidget *passcodeWidget();
|
||||||
|
@ -233,14 +229,10 @@ private:
|
||||||
void placeSmallCounter(QImage &img, int size, int count, const style::color &bg, const QPoint &shift, const style::color &color);
|
void placeSmallCounter(QImage &img, int size, int count, const style::color &bg, const QPoint &shift, const style::color &color);
|
||||||
QImage icon16, icon32, icon64, iconbig16, iconbig32, iconbig64;
|
QImage icon16, icon32, icon64, iconbig16, iconbig32, iconbig64;
|
||||||
|
|
||||||
QWidget *centralwidget;
|
|
||||||
|
|
||||||
typedef QPair<QString, MTPMessageMedia> DelayedServiceMsg;
|
typedef QPair<QString, MTPMessageMedia> DelayedServiceMsg;
|
||||||
QVector<DelayedServiceMsg> _delayedServiceMsgs;
|
QVector<DelayedServiceMsg> _delayedServiceMsgs;
|
||||||
mtpRequestId _serviceHistoryRequest = 0;
|
mtpRequestId _serviceHistoryRequest = 0;
|
||||||
|
|
||||||
Window::TitleWidget *_title = nullptr;
|
|
||||||
ChildWidget<TWidget> _body;
|
|
||||||
ChildWidget<PasscodeWidget> _passcode = { nullptr };
|
ChildWidget<PasscodeWidget> _passcode = { nullptr };
|
||||||
ChildWidget<IntroWidget> _intro = { nullptr };
|
ChildWidget<IntroWidget> _intro = { nullptr };
|
||||||
ChildWidget<MainWidget> _main = { nullptr };
|
ChildWidget<MainWidget> _main = { nullptr };
|
||||||
|
|
|
@ -125,11 +125,11 @@ mediaPlayerNextDisabledIcon: icon {
|
||||||
};
|
};
|
||||||
mediaPlayerPreviousButton: IconButton(mediaPlayerNextButton) {
|
mediaPlayerPreviousButton: IconButton(mediaPlayerNextButton) {
|
||||||
icon: icon {
|
icon: icon {
|
||||||
{ "player_previous", mediaPlayerActiveFg, mediaPlayerSkipIconPosition },
|
{ "player_next-flip_horizontal", mediaPlayerActiveFg, mediaPlayerSkipIconPosition },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
mediaPlayerPreviousDisabledIcon: icon {
|
mediaPlayerPreviousDisabledIcon: icon {
|
||||||
{ "player_previous", mediaPlayerInactiveFg, mediaPlayerSkipIconPosition },
|
{ "player_next-flip_horizontal", mediaPlayerInactiveFg, mediaPlayerSkipIconPosition },
|
||||||
};
|
};
|
||||||
mediaPlayerClose: IconButton(mediaPlayerRepeatButton) {
|
mediaPlayerClose: IconButton(mediaPlayerRepeatButton) {
|
||||||
width: 37px;
|
width: 37px;
|
||||||
|
@ -178,10 +178,10 @@ mediaPlayerPanelNextDisabledIcon: icon {
|
||||||
{ "player_panel_next", mediaPlayerInactiveFg, point(10px, 10px) },
|
{ "player_panel_next", mediaPlayerInactiveFg, point(10px, 10px) },
|
||||||
};
|
};
|
||||||
mediaPlayerPanelPreviousButton: IconButton(mediaPlayerPanelNextButton) {
|
mediaPlayerPanelPreviousButton: IconButton(mediaPlayerPanelNextButton) {
|
||||||
icon: icon {{ "player_panel_previous", mediaPlayerActiveFg, point(10px, 10px) }};
|
icon: icon {{ "player_panel_next-flip_horizontal", mediaPlayerActiveFg, point(10px, 10px) }};
|
||||||
}
|
}
|
||||||
mediaPlayerPanelPreviousDisabledIcon: icon {
|
mediaPlayerPanelPreviousDisabledIcon: icon {
|
||||||
{ "player_panel_previous", mediaPlayerInactiveFg, point(10px, 10px) },
|
{ "player_panel_next-flip_horizontal", mediaPlayerInactiveFg, point(10px, 10px) },
|
||||||
};
|
};
|
||||||
|
|
||||||
mediaPlayerPanelPadding: 16px;
|
mediaPlayerPanelPadding: 16px;
|
||||||
|
|
|
@ -81,7 +81,7 @@ mediaviewVolumeOnIconOver: icon {{ "media_volume", mediaviewPlaybackActiveOver,
|
||||||
mediaviewVolumeIconTop: 8px;
|
mediaviewVolumeIconTop: 8px;
|
||||||
mediaviewControllerRadius: 25px;
|
mediaviewControllerRadius: 25px;
|
||||||
|
|
||||||
mediaviewLeft: icon {{ "mediaview_previous", #ffffff }};
|
mediaviewLeft: icon {{ "mediaview_next-flip_horizontal", #ffffff }};
|
||||||
mediaviewRight: icon {{ "mediaview_next", #ffffff }};
|
mediaviewRight: icon {{ "mediaview_next", #ffffff }};
|
||||||
mediaviewClose: icon {{ "mediaview_close", #ffffff }};
|
mediaviewClose: icon {{ "mediaview_close", #ffffff }};
|
||||||
mediaviewSave: icon {{ "mediaview_download", #ffffff }};
|
mediaviewSave: icon {{ "mediaview_download", #ffffff }};
|
||||||
|
|
|
@ -54,7 +54,7 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, PeerD
|
||||||
, _history(App::history(_peer->id))
|
, _history(App::history(_peer->id))
|
||||||
, _channel(peerToChannel(_peer->id))
|
, _channel(peerToChannel(_peer->id))
|
||||||
, _rowWidth(st::msgMinWidth)
|
, _rowWidth(st::msgMinWidth)
|
||||||
, _search(this, st::dlgFilter, lang(lng_dlg_filter))
|
, _search(this, st::dialogsFilter, lang(lng_dlg_filter))
|
||||||
, _cancelSearch(this, st::dialogsCancelSearch)
|
, _cancelSearch(this, st::dialogsCancelSearch)
|
||||||
, _itemsToBeLoaded(LinksOverviewPerPage * 2)
|
, _itemsToBeLoaded(LinksOverviewPerPage * 2)
|
||||||
, _width(st::windowMinWidth) {
|
, _width(st::windowMinWidth) {
|
||||||
|
|
|
@ -431,89 +431,6 @@ void MainWindow::LibsLoaded() {
|
||||||
#endif // !TDESKTOP_DISABLE_UNITY_INTEGRATION
|
#endif // !TDESKTOP_DISABLE_UNITY_INTEGRATION
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::psInitSize() {
|
|
||||||
TWindowPos pos(cWindowPos());
|
|
||||||
QRect avail(QDesktopWidget().availableGeometry());
|
|
||||||
bool maximized = false;
|
|
||||||
QRect geom(avail.x() + (avail.width() - st::windowDefWidth) / 2, avail.y() + (avail.height() - st::windowDefHeight) / 2, st::windowDefWidth, st::windowDefHeight);
|
|
||||||
if (pos.w && pos.h) {
|
|
||||||
QList<QScreen*> screens = Application::screens();
|
|
||||||
for (QList<QScreen*>::const_iterator i = screens.cbegin(), e = screens.cend(); i != e; ++i) {
|
|
||||||
QByteArray name = (*i)->name().toUtf8();
|
|
||||||
if (pos.moncrc == hashCrc32(name.constData(), name.size())) {
|
|
||||||
QRect screen((*i)->geometry());
|
|
||||||
int32 w = screen.width(), h = screen.height();
|
|
||||||
if (w >= st::windowMinWidth && h >= st::windowMinHeight) {
|
|
||||||
if (pos.w > w) pos.w = w;
|
|
||||||
if (pos.h > h) pos.h = h;
|
|
||||||
pos.x += screen.x();
|
|
||||||
pos.y += screen.y();
|
|
||||||
if (pos.x < screen.x() + screen.width() - 10 && pos.y < screen.y() + screen.height() - 10) {
|
|
||||||
geom = QRect(pos.x, pos.y, pos.w, pos.h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos.y < 0) pos.y = 0;
|
|
||||||
maximized = pos.maximized;
|
|
||||||
}
|
|
||||||
setGeometry(geom);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::psInitFrameless() {
|
|
||||||
psUpdatedPositionTimer.setSingleShot(true);
|
|
||||||
connect(&psUpdatedPositionTimer, SIGNAL(timeout()), this, SLOT(psSavePosition()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::psSavePosition(Qt::WindowState state) {
|
|
||||||
if (state == Qt::WindowActive) state = windowHandle()->windowState();
|
|
||||||
if (state == Qt::WindowMinimized || !posInited) return;
|
|
||||||
|
|
||||||
TWindowPos pos(cWindowPos()), curPos = pos;
|
|
||||||
|
|
||||||
if (state == Qt::WindowMaximized) {
|
|
||||||
curPos.maximized = 1;
|
|
||||||
} else {
|
|
||||||
QRect r(geometry());
|
|
||||||
curPos.x = r.x();
|
|
||||||
curPos.y = r.y();
|
|
||||||
curPos.w = r.width();
|
|
||||||
curPos.h = r.height();
|
|
||||||
curPos.maximized = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int px = curPos.x + curPos.w / 2, py = curPos.y + curPos.h / 2, d = 0;
|
|
||||||
QScreen *chosen = 0;
|
|
||||||
QList<QScreen*> screens = Application::screens();
|
|
||||||
for (QList<QScreen*>::const_iterator i = screens.cbegin(), e = screens.cend(); i != e; ++i) {
|
|
||||||
int dx = (*i)->geometry().x() + (*i)->geometry().width() / 2 - px; if (dx < 0) dx = -dx;
|
|
||||||
int dy = (*i)->geometry().y() + (*i)->geometry().height() / 2 - py; if (dy < 0) dy = -dy;
|
|
||||||
if (!chosen || dx + dy < d) {
|
|
||||||
d = dx + dy;
|
|
||||||
chosen = *i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (chosen) {
|
|
||||||
curPos.x -= chosen->geometry().x();
|
|
||||||
curPos.y -= chosen->geometry().y();
|
|
||||||
QByteArray name = chosen->name().toUtf8();
|
|
||||||
curPos.moncrc = hashCrc32(name.constData(), name.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (curPos.w >= st::wndMinWidth && curPos.h >= st::wndMinHeight) {
|
|
||||||
if (curPos.x != pos.x || curPos.y != pos.y || curPos.w != pos.w || curPos.h != pos.h || curPos.moncrc != pos.moncrc || curPos.maximized != pos.maximized) {
|
|
||||||
cSetWindowPos(curPos);
|
|
||||||
Local::writeSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::psUpdatedPosition() {
|
|
||||||
psUpdatedPositionTimer.start(SaveWindowPositionTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::psCreateTrayIcon() {
|
void MainWindow::psCreateTrayIcon() {
|
||||||
if (!noQtTrayIcon) {
|
if (!noQtTrayIcon) {
|
||||||
cSetSupportTray(QSystemTrayIcon::isSystemTrayAvailable());
|
cSetSupportTray(QSystemTrayIcon::isSystemTrayAvailable());
|
||||||
|
@ -641,7 +558,7 @@ void MainWindow::psFirstShow() {
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
posInited = true;
|
setPositionInited();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::psInitSysMenu() {
|
void MainWindow::psInitSysMenu() {
|
||||||
|
|
|
@ -30,18 +30,10 @@ class MainWindow : public Window::MainWindow {
|
||||||
public:
|
public:
|
||||||
MainWindow();
|
MainWindow();
|
||||||
|
|
||||||
int32 psResizeRowWidth() const {
|
|
||||||
return 0;//st::wndResizeAreaWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
void psInitFrameless();
|
|
||||||
void psInitSize();
|
|
||||||
|
|
||||||
void psFirstShow();
|
void psFirstShow();
|
||||||
void psInitSysMenu();
|
void psInitSysMenu();
|
||||||
void psUpdateSysMenu(Qt::WindowState state);
|
void psUpdateSysMenu(Qt::WindowState state);
|
||||||
void psUpdateMargins();
|
void psUpdateMargins();
|
||||||
void psUpdatedPosition();
|
|
||||||
|
|
||||||
void psFlash();
|
void psFlash();
|
||||||
void psNotifySettingGot();
|
void psNotifySettingGot();
|
||||||
|
@ -51,10 +43,6 @@ public:
|
||||||
void psRefreshTaskbarIcon() {
|
void psRefreshTaskbarIcon() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool psPosInited() const {
|
|
||||||
return posInited;
|
|
||||||
}
|
|
||||||
|
|
||||||
void psUpdateCounter();
|
void psUpdateCounter();
|
||||||
|
|
||||||
bool psHasNativeNotifications();
|
bool psHasNativeNotifications();
|
||||||
|
@ -66,7 +54,6 @@ public:
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void psSavePosition(Qt::WindowState state = Qt::WindowActive);
|
|
||||||
void psShowTrayMenu();
|
void psShowTrayMenu();
|
||||||
|
|
||||||
void psStatusIconCheck();
|
void psStatusIconCheck();
|
||||||
|
@ -76,7 +63,6 @@ protected:
|
||||||
|
|
||||||
bool psHasTrayIcon() const;
|
bool psHasTrayIcon() const;
|
||||||
|
|
||||||
bool posInited = false;
|
|
||||||
QSystemTrayIcon *trayIcon = nullptr;
|
QSystemTrayIcon *trayIcon = nullptr;
|
||||||
QMenu *trayIconMenu = nullptr;
|
QMenu *trayIconMenu = nullptr;
|
||||||
QImage icon256, iconbig256;
|
QImage icon256, iconbig256;
|
||||||
|
|
|
@ -38,18 +38,10 @@ class MainWindow : public Window::MainWindow {
|
||||||
public:
|
public:
|
||||||
MainWindow();
|
MainWindow();
|
||||||
|
|
||||||
int32 psResizeRowWidth() const {
|
|
||||||
return 0;//st::wndResizeAreaWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
void psInitFrameless();
|
|
||||||
void psInitSize();
|
|
||||||
|
|
||||||
void psFirstShow();
|
void psFirstShow();
|
||||||
void psInitSysMenu();
|
void psInitSysMenu();
|
||||||
void psUpdateSysMenu(Qt::WindowState state);
|
void psUpdateSysMenu(Qt::WindowState state);
|
||||||
void psUpdateMargins();
|
void psUpdateMargins();
|
||||||
void psUpdatedPosition();
|
|
||||||
|
|
||||||
void psFlash();
|
void psFlash();
|
||||||
|
|
||||||
|
@ -58,10 +50,6 @@ public:
|
||||||
void psRefreshTaskbarIcon() {
|
void psRefreshTaskbarIcon() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool psPosInited() const {
|
|
||||||
return posInited;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool psFilterNativeEvent(void *event);
|
bool psFilterNativeEvent(void *event);
|
||||||
|
|
||||||
bool eventFilter(QObject *obj, QEvent *evt) override;
|
bool eventFilter(QObject *obj, QEvent *evt) override;
|
||||||
|
@ -79,7 +67,6 @@ public:
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void psSavePosition(Qt::WindowState state = Qt::WindowActive);
|
|
||||||
void psShowTrayMenu();
|
void psShowTrayMenu();
|
||||||
|
|
||||||
void psMacUndo();
|
void psMacUndo();
|
||||||
|
@ -103,7 +90,6 @@ protected:
|
||||||
|
|
||||||
void psMacUpdateMenu();
|
void psMacUpdateMenu();
|
||||||
|
|
||||||
bool posInited;
|
|
||||||
QSystemTrayIcon *trayIcon = nullptr;
|
QSystemTrayIcon *trayIcon = nullptr;
|
||||||
QMenu *trayIconMenu = nullptr;
|
QMenu *trayIconMenu = nullptr;
|
||||||
QImage icon256, iconbig256;
|
QImage icon256, iconbig256;
|
||||||
|
@ -118,6 +104,8 @@ protected:
|
||||||
QTimer psUpdatedPositionTimer;
|
QTimer psUpdatedPositionTimer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void createGlobalMenu();
|
||||||
|
|
||||||
MacPrivate _private;
|
MacPrivate _private;
|
||||||
|
|
||||||
mutable bool psIdle;
|
mutable bool psIdle;
|
||||||
|
|
|
@ -52,8 +52,7 @@ void MacPrivate::darkModeChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow()
|
||||||
: posInited(false)
|
: icon256(qsl(":/gui/art/icon256.png"))
|
||||||
, icon256(qsl(":/gui/art/icon256.png"))
|
|
||||||
, iconbig256(qsl(":/gui/art/iconbig256.png"))
|
, iconbig256(qsl(":/gui/art/iconbig256.png"))
|
||||||
, wndIcon(QPixmap::fromImage(iconbig256, Qt::ColorOnly)) {
|
, wndIcon(QPixmap::fromImage(iconbig256, Qt::ColorOnly)) {
|
||||||
QImage tray(qsl(":/gui/art/osxtray.png"));
|
QImage tray(qsl(":/gui/art/osxtray.png"));
|
||||||
|
@ -190,89 +189,11 @@ void MainWindow::psUpdateCounter() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::psInitSize() {
|
|
||||||
TWindowPos pos(cWindowPos());
|
|
||||||
QRect avail(QDesktopWidget().availableGeometry());
|
|
||||||
bool maximized = false;
|
|
||||||
QRect geom(avail.x() + (avail.width() - st::windowDefWidth) / 2, avail.y() + (avail.height() - st::windowDefHeight) / 2, st::windowDefWidth, st::windowDefHeight);
|
|
||||||
if (pos.w && pos.h) {
|
|
||||||
QList<QScreen*> screens = Application::screens();
|
|
||||||
for (QList<QScreen*>::const_iterator i = screens.cbegin(), e = screens.cend(); i != e; ++i) {
|
|
||||||
QByteArray name = (*i)->name().toUtf8();
|
|
||||||
if (pos.moncrc == hashCrc32(name.constData(), name.size())) {
|
|
||||||
QRect screen((*i)->geometry());
|
|
||||||
int32 w = screen.width(), h = screen.height();
|
|
||||||
if (w >= st::windowMinWidth && h >= st::windowMinHeight) {
|
|
||||||
if (pos.w > w) pos.w = w;
|
|
||||||
if (pos.h > h) pos.h = h;
|
|
||||||
pos.x += screen.x();
|
|
||||||
pos.y += screen.y();
|
|
||||||
if (pos.x < screen.x() + screen.width() - 10 && pos.y < screen.y() + screen.height() - 10) {
|
|
||||||
geom = QRect(pos.x, pos.y, pos.w, pos.h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos.y < 0) pos.y = 0;
|
|
||||||
maximized = pos.maximized;
|
|
||||||
}
|
|
||||||
setGeometry(geom);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::psInitFrameless() {
|
void MainWindow::psInitFrameless() {
|
||||||
psUpdatedPositionTimer.setSingleShot(true);
|
psUpdatedPositionTimer.setSingleShot(true);
|
||||||
connect(&psUpdatedPositionTimer, SIGNAL(timeout()), this, SLOT(psSavePosition()));
|
connect(&psUpdatedPositionTimer, SIGNAL(timeout()), this, SLOT(psSavePosition()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::psSavePosition(Qt::WindowState state) {
|
|
||||||
if (state == Qt::WindowActive) state = windowHandle()->windowState();
|
|
||||||
if (state == Qt::WindowMinimized || !posInited) return;
|
|
||||||
|
|
||||||
TWindowPos pos(cWindowPos()), curPos = pos;
|
|
||||||
|
|
||||||
if (state == Qt::WindowMaximized) {
|
|
||||||
curPos.maximized = 1;
|
|
||||||
} else {
|
|
||||||
QRect r(geometry());
|
|
||||||
curPos.x = r.x();
|
|
||||||
curPos.y = r.y();
|
|
||||||
curPos.w = r.width();
|
|
||||||
curPos.h = r.height();
|
|
||||||
curPos.maximized = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int px = curPos.x + curPos.w / 2, py = curPos.y + curPos.h / 2, d = 0;
|
|
||||||
QScreen *chosen = 0;
|
|
||||||
QList<QScreen*> screens = Application::screens();
|
|
||||||
for (QList<QScreen*>::const_iterator i = screens.cbegin(), e = screens.cend(); i != e; ++i) {
|
|
||||||
int dx = (*i)->geometry().x() + (*i)->geometry().width() / 2 - px; if (dx < 0) dx = -dx;
|
|
||||||
int dy = (*i)->geometry().y() + (*i)->geometry().height() / 2 - py; if (dy < 0) dy = -dy;
|
|
||||||
if (!chosen || dx + dy < d) {
|
|
||||||
d = dx + dy;
|
|
||||||
chosen = *i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (chosen) {
|
|
||||||
curPos.x -= chosen->geometry().x();
|
|
||||||
curPos.y -= chosen->geometry().y();
|
|
||||||
QByteArray name = chosen->name().toUtf8();
|
|
||||||
curPos.moncrc = hashCrc32(name.constData(), name.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (curPos.w >= st::wndMinWidth && curPos.h >= st::wndMinHeight) {
|
|
||||||
if (curPos.x != pos.x || curPos.y != pos.y || curPos.w != pos.w || curPos.h != pos.h || curPos.moncrc != pos.moncrc || curPos.maximized != pos.maximized) {
|
|
||||||
cSetWindowPos(curPos);
|
|
||||||
Local::writeSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::psUpdatedPosition() {
|
|
||||||
psUpdatedPositionTimer.start(SaveWindowPositionTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::psFirstShow() {
|
void MainWindow::psFirstShow() {
|
||||||
psUpdateMargins();
|
psUpdateMargins();
|
||||||
|
|
||||||
|
@ -296,9 +217,14 @@ void MainWindow::psFirstShow() {
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
posInited = true;
|
setPositionInited();
|
||||||
|
|
||||||
// init global menu
|
createGlobalMenu();
|
||||||
|
|
||||||
|
psMacUpdateMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::createGlobalMenu() {
|
||||||
auto main = psMainMenu.addMenu(qsl("Telegram"));
|
auto main = psMainMenu.addMenu(qsl("Telegram"));
|
||||||
auto about = main->addAction(lng_mac_menu_about_telegram(lt_telegram, qsl("Telegram")));
|
auto about = main->addAction(lng_mac_menu_about_telegram(lt_telegram, qsl("Telegram")));
|
||||||
connect(about, SIGNAL(triggered()), base::lambda_slot(about, [] {
|
connect(about, SIGNAL(triggered()), base::lambda_slot(about, [] {
|
||||||
|
@ -339,8 +265,6 @@ void MainWindow::psFirstShow() {
|
||||||
psNewChannel = window->addAction(lang(lng_mac_menu_new_channel), App::wnd(), SLOT(onShowNewChannel()));
|
psNewChannel = window->addAction(lang(lng_mac_menu_new_channel), App::wnd(), SLOT(onShowNewChannel()));
|
||||||
window->addSeparator();
|
window->addSeparator();
|
||||||
psShowTelegram = window->addAction(lang(lng_mac_menu_show), App::wnd(), SLOT(showFromTray()));
|
psShowTelegram = window->addAction(lang(lng_mac_menu_show), App::wnd(), SLOT(showFromTray()));
|
||||||
|
|
||||||
psMacUpdateMenu();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -398,23 +322,23 @@ void MainWindow::psUpdateMargins() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::psMacUpdateMenu() {
|
void MainWindow::psMacUpdateMenu() {
|
||||||
if (!posInited) return;
|
if (!positionInited()) return;
|
||||||
|
|
||||||
QWidget *focused = QApplication::focusWidget();
|
QWidget *focused = QApplication::focusWidget();
|
||||||
bool isLogged = !!App::self(), canUndo = false, canRedo = false, canCut = false, canCopy = false, canPaste = false, canDelete = false, canSelectAll = false;
|
bool isLogged = !!App::self(), canUndo = false, canRedo = false, canCut = false, canCopy = false, canPaste = false, canDelete = false, canSelectAll = false;
|
||||||
if (QLineEdit *edit = qobject_cast<QLineEdit*>(focused)) {
|
if (auto edit = qobject_cast<QLineEdit*>(focused)) {
|
||||||
canCut = canCopy = canDelete = edit->hasSelectedText();
|
canCut = canCopy = canDelete = edit->hasSelectedText();
|
||||||
canSelectAll = !edit->text().isEmpty();
|
canSelectAll = !edit->text().isEmpty();
|
||||||
canUndo = edit->isUndoAvailable();
|
canUndo = edit->isUndoAvailable();
|
||||||
canRedo = edit->isRedoAvailable();
|
canRedo = edit->isRedoAvailable();
|
||||||
canPaste = !Application::clipboard()->text().isEmpty();
|
canPaste = !Application::clipboard()->text().isEmpty();
|
||||||
} else if (FlatTextarea *edit = qobject_cast<FlatTextarea*>(focused)) {
|
} else if (auto edit = qobject_cast<FlatTextarea*>(focused)) {
|
||||||
canCut = canCopy = canDelete = edit->textCursor().hasSelection();
|
canCut = canCopy = canDelete = edit->textCursor().hasSelection();
|
||||||
canSelectAll = !edit->isEmpty();
|
canSelectAll = !edit->isEmpty();
|
||||||
canUndo = edit->isUndoAvailable();
|
canUndo = edit->isUndoAvailable();
|
||||||
canRedo = edit->isRedoAvailable();
|
canRedo = edit->isRedoAvailable();
|
||||||
canPaste = !Application::clipboard()->text().isEmpty();
|
canPaste = !Application::clipboard()->text().isEmpty();
|
||||||
} else if (HistoryInner *list = qobject_cast<HistoryInner*>(focused)) {
|
} else if (auto list = qobject_cast<HistoryInner*>(focused)) {
|
||||||
canCopy = list->canCopySelected();
|
canCopy = list->canCopySelected();
|
||||||
canDelete = list->canDeleteSelected();
|
canDelete = list->canDeleteSelected();
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,7 +194,7 @@ public:
|
||||||
max_w = avail.width();
|
max_w = avail.width();
|
||||||
accumulate_max(max_w, st::windowMinWidth);
|
accumulate_max(max_w, st::windowMinWidth);
|
||||||
max_h = avail.height();
|
max_h = avail.height();
|
||||||
accumulate_max(max_h, st::windowMinHeight);
|
accumulate_max(max_h, st::titleHeight + st::windowMinHeight);
|
||||||
|
|
||||||
HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0);
|
HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0);
|
||||||
HWND hwnd = App::wnd() ? App::wnd()->psHwnd() : 0;
|
HWND hwnd = App::wnd() ? App::wnd()->psHwnd() : 0;
|
||||||
|
@ -350,7 +350,7 @@ public:
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!App::wnd()->psPosInited()) return;
|
if (!App::wnd()->positionInited()) return;
|
||||||
|
|
||||||
int x = _x, y = _y, w = _w, h = _h;
|
int x = _x, y = _y, w = _w, h = _h;
|
||||||
if (pos && (!(pos->flags & SWP_NOMOVE) || !(pos->flags & SWP_NOSIZE) || !(pos->flags & SWP_NOREPOSITION))) {
|
if (pos && (!(pos->flags & SWP_NOMOVE) || !(pos->flags & SWP_NOSIZE) || !(pos->flags & SWP_NOREPOSITION))) {
|
||||||
|
@ -644,6 +644,17 @@ void MainWindow::psShowTrayMenu() {
|
||||||
trayIconMenu->popup(QCursor::pos());
|
trayIconMenu->popup(QCursor::pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 MainWindow::screenNameChecksum(const QString &name) const {
|
||||||
|
constexpr int DeviceNameSize = base::array_size(MONITORINFOEX().szDevice);
|
||||||
|
wchar_t buffer[DeviceNameSize] = { 0 };
|
||||||
|
if (name.size() < DeviceNameSize) {
|
||||||
|
name.toWCharArray(buffer);
|
||||||
|
} else {
|
||||||
|
memcpy(buffer, name.toStdWString().data(), sizeof(buffer));
|
||||||
|
}
|
||||||
|
return hashCrc32(buffer, sizeof(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::psRefreshTaskbarIcon() {
|
void MainWindow::psRefreshTaskbarIcon() {
|
||||||
QWidget *w = new QWidget(this);
|
QWidget *w = new QWidget(this);
|
||||||
w->setWindowFlags(static_cast<Qt::WindowFlags>(Qt::Tool) | Qt::FramelessWindowHint);
|
w->setWindowFlags(static_cast<Qt::WindowFlags>(Qt::Tool) | Qt::FramelessWindowHint);
|
||||||
|
@ -754,58 +765,7 @@ void MainWindow::psUpdateCounter() {
|
||||||
SetWindowPos(ps_hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
SetWindowPos(ps_hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
void MainWindow::initHook() {
|
||||||
HMONITOR enumMonitor = 0;
|
|
||||||
RECT enumMonitorWork;
|
|
||||||
|
|
||||||
BOOL CALLBACK _monitorEnumProc(
|
|
||||||
_In_ HMONITOR hMonitor,
|
|
||||||
_In_ HDC hdcMonitor,
|
|
||||||
_In_ LPRECT lprcMonitor,
|
|
||||||
_In_ LPARAM dwData
|
|
||||||
) {
|
|
||||||
MONITORINFOEX info;
|
|
||||||
info.cbSize = sizeof(info);
|
|
||||||
GetMonitorInfo(hMonitor, &info);
|
|
||||||
if (dwData == hashCrc32(info.szDevice, sizeof(info.szDevice))) {
|
|
||||||
enumMonitor = hMonitor;
|
|
||||||
enumMonitorWork = info.rcWork;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void MainWindow::psInitSize() {
|
|
||||||
TWindowPos pos(cWindowPos());
|
|
||||||
QRect avail(Sandbox::availableGeometry());
|
|
||||||
bool maximized = false;
|
|
||||||
QRect geom(avail.x() + (avail.width() - st::windowDefWidth) / 2, avail.y() + (avail.height() - st::windowDefHeight) / 2, st::windowDefWidth, st::windowDefHeight);
|
|
||||||
if (pos.w && pos.h) {
|
|
||||||
if (pos.y < 0) pos.y = 0;
|
|
||||||
enumMonitor = 0;
|
|
||||||
EnumDisplayMonitors(0, 0, &_monitorEnumProc, pos.moncrc);
|
|
||||||
if (enumMonitor) {
|
|
||||||
int32 w = enumMonitorWork.right - enumMonitorWork.left, h = enumMonitorWork.bottom - enumMonitorWork.top;
|
|
||||||
if (w >= st::windowMinWidth && h >= st::windowMinHeight) {
|
|
||||||
if (pos.w > w) pos.w = w;
|
|
||||||
if (pos.h > h) pos.h = h;
|
|
||||||
pos.x += enumMonitorWork.left;
|
|
||||||
pos.y += enumMonitorWork.top;
|
|
||||||
if (pos.x < enumMonitorWork.right - 10 && pos.y < enumMonitorWork.bottom - 10) {
|
|
||||||
geom = QRect(pos.x, pos.y, pos.w, pos.h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
maximized = pos.maximized;
|
|
||||||
}
|
|
||||||
setGeometry(geom);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::psInitFrameless() {
|
|
||||||
psUpdatedPositionTimer.setSingleShot(true);
|
|
||||||
connect(&psUpdatedPositionTimer, SIGNAL(timeout()), this, SLOT(psSavePosition()));
|
|
||||||
|
|
||||||
auto platformInterface = QGuiApplication::platformNativeInterface();
|
auto platformInterface = QGuiApplication::platformNativeInterface();
|
||||||
ps_hWnd = static_cast<HWND>(platformInterface->nativeResourceForWindow(QByteArrayLiteral("handle"), windowHandle()));
|
ps_hWnd = static_cast<HWND>(platformInterface->nativeResourceForWindow(QByteArrayLiteral("handle"), windowHandle()));
|
||||||
|
|
||||||
|
@ -816,53 +776,9 @@ void MainWindow::psInitFrameless() {
|
||||||
Dlls::WTSRegisterSessionNotification(ps_hWnd, NOTIFY_FOR_THIS_SESSION);
|
Dlls::WTSRegisterSessionNotification(ps_hWnd, NOTIFY_FOR_THIS_SESSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterApplicationRestart(NULL, 0);
|
|
||||||
|
|
||||||
psInitSysMenu();
|
psInitSysMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::psSavePosition(Qt::WindowState state) {
|
|
||||||
if (state == Qt::WindowActive) state = windowHandle()->windowState();
|
|
||||||
if (state == Qt::WindowMinimized || !posInited) return;
|
|
||||||
|
|
||||||
TWindowPos pos(cWindowPos()), curPos = pos;
|
|
||||||
|
|
||||||
if (state == Qt::WindowMaximized) {
|
|
||||||
curPos.maximized = 1;
|
|
||||||
} else {
|
|
||||||
RECT w;
|
|
||||||
GetWindowRect(ps_hWnd, &w);
|
|
||||||
curPos.x = w.left;
|
|
||||||
curPos.y = w.top;
|
|
||||||
curPos.w = w.right - w.left;
|
|
||||||
curPos.h = w.bottom - w.top;
|
|
||||||
curPos.maximized = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
HMONITOR hMonitor = MonitorFromWindow(ps_hWnd, MONITOR_DEFAULTTONEAREST);
|
|
||||||
if (hMonitor) {
|
|
||||||
MONITORINFOEX info;
|
|
||||||
info.cbSize = sizeof(info);
|
|
||||||
GetMonitorInfo(hMonitor, &info);
|
|
||||||
if (!curPos.maximized) {
|
|
||||||
curPos.x -= info.rcWork.left;
|
|
||||||
curPos.y -= info.rcWork.top;
|
|
||||||
}
|
|
||||||
curPos.moncrc = hashCrc32(info.szDevice, sizeof(info.szDevice));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (curPos.w >= st::windowMinWidth && curPos.h >= st::windowMinHeight) {
|
|
||||||
if (curPos.x != pos.x || curPos.y != pos.y || curPos.w != pos.w || curPos.h != pos.h || curPos.moncrc != pos.moncrc || curPos.maximized != pos.maximized) {
|
|
||||||
cSetWindowPos(curPos);
|
|
||||||
Local::writeSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::psUpdatedPosition() {
|
|
||||||
psUpdatedPositionTimer.start(SaveWindowPositionTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::psHasNativeNotifications() {
|
bool MainWindow::psHasNativeNotifications() {
|
||||||
return Notifications::supported();
|
return Notifications::supported();
|
||||||
}
|
}
|
||||||
|
@ -894,7 +810,7 @@ void MainWindow::psFirstShow() {
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
posInited = true;
|
setPositionInited();
|
||||||
if (showShadows) {
|
if (showShadows) {
|
||||||
shadowsUpdate(ShadowsChange::Moved | ShadowsChange::Resized | ShadowsChange::Shown);
|
shadowsUpdate(ShadowsChange::Moved | ShadowsChange::Resized | ShadowsChange::Shown);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,12 +35,6 @@ class MainWindow : public Window::MainWindow {
|
||||||
public:
|
public:
|
||||||
MainWindow();
|
MainWindow();
|
||||||
|
|
||||||
int32 psResizeRowWidth() const {
|
|
||||||
return 0;//st::wndResizeAreaWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
void psInitFrameless();
|
|
||||||
void psInitSize();
|
|
||||||
HWND psHwnd() const;
|
HWND psHwnd() const;
|
||||||
HMENU psMenu() const;
|
HMENU psMenu() const;
|
||||||
|
|
||||||
|
@ -48,7 +42,6 @@ public:
|
||||||
void psInitSysMenu();
|
void psInitSysMenu();
|
||||||
void psUpdateSysMenu(Qt::WindowState state);
|
void psUpdateSysMenu(Qt::WindowState state);
|
||||||
void psUpdateMargins();
|
void psUpdateMargins();
|
||||||
void psUpdatedPosition();
|
|
||||||
|
|
||||||
void psFlash();
|
void psFlash();
|
||||||
void psNotifySettingGot();
|
void psNotifySettingGot();
|
||||||
|
@ -57,10 +50,6 @@ public:
|
||||||
|
|
||||||
void psRefreshTaskbarIcon();
|
void psRefreshTaskbarIcon();
|
||||||
|
|
||||||
bool psPosInited() const {
|
|
||||||
return posInited;
|
|
||||||
}
|
|
||||||
|
|
||||||
void psUpdateCounter();
|
void psUpdateCounter();
|
||||||
|
|
||||||
bool psHasNativeNotifications();
|
bool psHasNativeNotifications();
|
||||||
|
@ -99,15 +88,16 @@ public:
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void psSavePosition(Qt::WindowState state = Qt::WindowActive);
|
|
||||||
void psShowTrayMenu();
|
void psShowTrayMenu();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void initHook() override;
|
||||||
|
int32 screenNameChecksum(const QString &name) const override;
|
||||||
|
|
||||||
bool psHasTrayIcon() const {
|
bool psHasTrayIcon() const {
|
||||||
return trayIcon;
|
return trayIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool posInited = false;
|
|
||||||
QSystemTrayIcon *trayIcon = nullptr;
|
QSystemTrayIcon *trayIcon = nullptr;
|
||||||
Ui::PopupMenu *trayIconMenu = nullptr;
|
Ui::PopupMenu *trayIconMenu = nullptr;
|
||||||
QImage icon256, iconbig256;
|
QImage icon256, iconbig256;
|
||||||
|
|
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "platform/win/window_title_win.h"
|
#include "platform/win/window_title_win.h"
|
||||||
|
|
||||||
#include "ui/buttons/icon_button.h"
|
#include "ui/buttons/icon_button.h"
|
||||||
|
#include "ui/widgets/shadow.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
@ -30,7 +31,8 @@ TitleWidget::TitleWidget(QWidget *parent) : Window::TitleWidget(parent)
|
||||||
, _minimize(this, st::titleButtonMinimize)
|
, _minimize(this, st::titleButtonMinimize)
|
||||||
, _maximizeRestore(this, st::titleButtonMaximize)
|
, _maximizeRestore(this, st::titleButtonMaximize)
|
||||||
, _close(this, st::titleButtonClose)
|
, _close(this, st::titleButtonClose)
|
||||||
, _maximized(parent->window()->windowState() & Qt::WindowMaximized) {
|
, _maximized(parent->window()->windowState() & Qt::WindowMaximized)
|
||||||
|
, _shadow(this, st::titleShadow) {
|
||||||
_minimize->setClickedCallback([this]() {
|
_minimize->setClickedCallback([this]() {
|
||||||
window()->setWindowState(Qt::WindowMinimized);
|
window()->setWindowState(Qt::WindowMinimized);
|
||||||
_minimize->clearState();
|
_minimize->clearState();
|
||||||
|
@ -65,6 +67,7 @@ void TitleWidget::updateControlsPosition() {
|
||||||
|
|
||||||
void TitleWidget::resizeEvent(QResizeEvent *e) {
|
void TitleWidget::resizeEvent(QResizeEvent *e) {
|
||||||
updateControlsPosition();
|
updateControlsPosition();
|
||||||
|
_shadow->setGeometry(0, height() - st::lineWidth, width(), st::lineWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TitleWidget::updateControlsVisibility() {
|
void TitleWidget::updateControlsVisibility() {
|
||||||
|
|
|
@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class IconButton;
|
class IconButton;
|
||||||
|
class PlainShadow;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
@ -51,6 +52,7 @@ private:
|
||||||
ChildWidget<Ui::IconButton> _minimize;
|
ChildWidget<Ui::IconButton> _minimize;
|
||||||
ChildWidget<Ui::IconButton> _maximizeRestore;
|
ChildWidget<Ui::IconButton> _maximizeRestore;
|
||||||
ChildWidget<Ui::IconButton> _close;
|
ChildWidget<Ui::IconButton> _close;
|
||||||
|
ChildWidget<Ui::PlainShadow> _shadow;
|
||||||
|
|
||||||
bool _maximized = false;
|
bool _maximized = false;
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,7 @@ bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
|
||||||
}
|
}
|
||||||
emit App::wnd()->windowHandle()->windowStateChanged(state);
|
emit App::wnd()->windowHandle()->windowStateChanged(state);
|
||||||
} else {
|
} else {
|
||||||
App::wnd()->psUpdatedPosition();
|
App::wnd()->positionUpdated();
|
||||||
}
|
}
|
||||||
App::wnd()->psUpdateMargins();
|
App::wnd()->psUpdateMargins();
|
||||||
MainWindow::ShadowsChanges changes = (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXIMIZED) ? ShadowsChange::Hidden : (ShadowsChange::Resized | ShadowsChange::Shown);
|
MainWindow::ShadowsChanges changes = (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXIMIZED) ? ShadowsChange::Hidden : (ShadowsChange::Resized | ShadowsChange::Shown);
|
||||||
|
@ -172,7 +172,7 @@ bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
|
||||||
|
|
||||||
case WM_MOVE: {
|
case WM_MOVE: {
|
||||||
App::wnd()->shadowsUpdate(ShadowsChange::Moved);
|
App::wnd()->shadowsUpdate(ShadowsChange::Moved);
|
||||||
App::wnd()->psUpdatedPosition();
|
App::wnd()->positionUpdated();
|
||||||
} return false;
|
} return false;
|
||||||
|
|
||||||
case WM_NCHITTEST: {
|
case WM_NCHITTEST: {
|
||||||
|
@ -185,7 +185,6 @@ bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
|
||||||
switch (res) {
|
switch (res) {
|
||||||
case Window::HitTestResult::Client:
|
case Window::HitTestResult::Client:
|
||||||
case Window::HitTestResult::SysButton: *result = HTCLIENT; break;
|
case Window::HitTestResult::SysButton: *result = HTCLIENT; break;
|
||||||
case Window::HitTestResult::Icon: *result = HTCAPTION; break;
|
|
||||||
case Window::HitTestResult::Caption: *result = HTCAPTION; break;
|
case Window::HitTestResult::Caption: *result = HTCAPTION; break;
|
||||||
case Window::HitTestResult::Top: *result = HTTOP; break;
|
case Window::HitTestResult::Top: *result = HTTOP; break;
|
||||||
case Window::HitTestResult::TopRight: *result = HTTOPRIGHT; break;
|
case Window::HitTestResult::TopRight: *result = HTTOPRIGHT; break;
|
||||||
|
@ -204,42 +203,6 @@ bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
|
||||||
SendMessage(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
|
SendMessage(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
|
||||||
} return true;
|
} return true;
|
||||||
|
|
||||||
case WM_NCLBUTTONDOWN: {
|
|
||||||
POINTS p = MAKEPOINTS(lParam);
|
|
||||||
RECT r;
|
|
||||||
GetWindowRect(hWnd, &r);
|
|
||||||
auto res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
|
|
||||||
switch (res) {
|
|
||||||
case Window::HitTestResult::Icon:
|
|
||||||
if (menuHidden && getms() < menuHidden + 10) {
|
|
||||||
menuHidden = 0;
|
|
||||||
if (getms() < menuShown + GetDoubleClickTime()) {
|
|
||||||
App::wnd()->close();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
QRect icon = App::wnd()->iconRect();
|
|
||||||
p.x = r.left - App::wnd()->deltaLeft() + icon.left();
|
|
||||||
p.y = r.top - App::wnd()->deltaTop() + icon.top() + icon.height();
|
|
||||||
App::wnd()->psUpdateSysMenu(App::wnd()->windowHandle()->windowState());
|
|
||||||
menuShown = getms();
|
|
||||||
menuHidden = 0;
|
|
||||||
TrackPopupMenu(App::wnd()->psMenu(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON, p.x, p.y, 0, hWnd, 0);
|
|
||||||
menuHidden = getms();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
} return false;
|
|
||||||
|
|
||||||
case WM_NCLBUTTONDBLCLK: {
|
|
||||||
POINTS p = MAKEPOINTS(lParam);
|
|
||||||
RECT r;
|
|
||||||
GetWindowRect(hWnd, &r);
|
|
||||||
auto res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
|
|
||||||
switch (res) {
|
|
||||||
case Window::HitTestResult::Icon: App::wnd()->close(); return true;
|
|
||||||
};
|
|
||||||
} return false;
|
|
||||||
|
|
||||||
case WM_SYSCOMMAND: {
|
case WM_SYSCOMMAND: {
|
||||||
if (wParam == SC_MOUSEMENU) {
|
if (wParam == SC_MOUSEMENU) {
|
||||||
POINTS p = MAKEPOINTS(lParam);
|
POINTS p = MAKEPOINTS(lParam);
|
||||||
|
|
|
@ -924,7 +924,7 @@ void psUpdateOverlayed(TWidget *widget) {
|
||||||
if (!wv) widget->setAttribute(Qt::WA_WState_Visible, true);
|
if (!wv) widget->setAttribute(Qt::WA_WState_Visible, true);
|
||||||
widget->update();
|
widget->update();
|
||||||
QEvent e(QEvent::UpdateRequest);
|
QEvent e(QEvent::UpdateRequest);
|
||||||
widget->event(&e);
|
QGuiApplication::sendEvent(widget, &e);
|
||||||
if (!wm) widget->setAttribute(Qt::WA_Mapped, false);
|
if (!wm) widget->setAttribute(Qt::WA_Mapped, false);
|
||||||
if (!wv) widget->setAttribute(Qt::WA_WState_Visible, false);
|
if (!wv) widget->setAttribute(Qt::WA_WState_Visible, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,10 +74,11 @@ settingsButtonTop: 75px;
|
||||||
settingsButtonSkip: 10px;
|
settingsButtonSkip: 10px;
|
||||||
settingsPrimaryButton: defaultActiveButton;
|
settingsPrimaryButton: defaultActiveButton;
|
||||||
settingsSecondaryButton: defaultLightButton;
|
settingsSecondaryButton: defaultLightButton;
|
||||||
settingsEditButton: IconButton(dialogsNewChatButton) {
|
settingsEditButton: IconButton {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
|
|
||||||
|
icon: icon {{ "settings_edit_name", #b7b7b7 }};
|
||||||
iconPosition: point(3px, 9px);
|
iconPosition: point(3px, 9px);
|
||||||
iconPositionDown: point(3px, 10px);
|
iconPositionDown: point(3px, 10px);
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,8 +136,8 @@ emojiColorsSepColor: #d5d5d5;
|
||||||
emojiSwitchSkip: 27px;
|
emojiSwitchSkip: 27px;
|
||||||
emojiSwitchImgSkip: 21px;
|
emojiSwitchImgSkip: 21px;
|
||||||
emojiSwitchColor: #42a8db;
|
emojiSwitchColor: #42a8db;
|
||||||
emojiSwitchStickers: icon {{ "emoji_switch_right", emojiSwitchColor }};
|
emojiSwitchStickers: icon {{ "emoji_switch", emojiSwitchColor }};
|
||||||
emojiSwitchEmoji: icon {{ "emoji_switch_left", emojiSwitchColor }};
|
emojiSwitchEmoji: icon {{ "emoji_switch-flip_horizontal", emojiSwitchColor }};
|
||||||
|
|
||||||
stickerPanSize: size(64px, 64px);
|
stickerPanSize: size(64px, 64px);
|
||||||
stickerPanPadding: 11px;
|
stickerPanPadding: 11px;
|
||||||
|
|
|
@ -138,9 +138,6 @@ class TWidget : public QWidget {
|
||||||
public:
|
public:
|
||||||
TWidget(QWidget *parent = nullptr) : QWidget(parent) {
|
TWidget(QWidget *parent = nullptr) : QWidget(parent) {
|
||||||
}
|
}
|
||||||
bool event(QEvent *e) override {
|
|
||||||
return QWidget::event(e);
|
|
||||||
}
|
|
||||||
virtual void grabStart() {
|
virtual void grabStart() {
|
||||||
}
|
}
|
||||||
virtual void grabFinish() {
|
virtual void grabFinish() {
|
||||||
|
@ -238,39 +235,39 @@ private:
|
||||||
|
|
||||||
// A simple wrap around T* to explicitly state ownership
|
// A simple wrap around T* to explicitly state ownership
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ChildWidget {
|
class ChildObject {
|
||||||
public:
|
public:
|
||||||
ChildWidget(std_::nullptr_t) : _widget(nullptr) {
|
ChildObject(std_::nullptr_t) : _object(nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// No default constructor, but constructors with at least
|
// No default constructor, but constructors with at least
|
||||||
// one argument are simply make functions.
|
// one argument are simply make functions.
|
||||||
template <typename Parent, typename... Args>
|
template <typename Parent, typename... Args>
|
||||||
ChildWidget(Parent &&parent, Args&&... args) : _widget(new T(std_::forward<Parent>(parent), std_::forward<Args>(args)...)) {
|
ChildObject(Parent &&parent, Args&&... args) : _object(new T(std_::forward<Parent>(parent), std_::forward<Args>(args)...)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ChildWidget(const ChildWidget<T> &other) = delete;
|
ChildObject(const ChildObject<T> &other) = delete;
|
||||||
ChildWidget<T> &operator=(const ChildWidget<T> &other) = delete;
|
ChildObject<T> &operator=(const ChildObject<T> &other) = delete;
|
||||||
|
|
||||||
ChildWidget<T> &operator=(std_::nullptr_t) {
|
ChildObject<T> &operator=(std_::nullptr_t) {
|
||||||
_widget = nullptr;
|
_object = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ChildWidget<T> &operator=(T *widget) {
|
ChildObject<T> &operator=(T *object) {
|
||||||
_widget = widget;
|
_object = object;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
T *operator->() const {
|
T *operator->() const {
|
||||||
return _widget;
|
return _object;
|
||||||
}
|
}
|
||||||
T &operator*() const {
|
T &operator*() const {
|
||||||
return *_widget;
|
return *_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
// So we can pass this pointer to methods like connect().
|
// So we can pass this pointer to methods like connect().
|
||||||
T *ptr() const {
|
T *ptr() const {
|
||||||
return _widget;
|
return _object;
|
||||||
}
|
}
|
||||||
operator T*() const {
|
operator T*() const {
|
||||||
return ptr();
|
return ptr();
|
||||||
|
@ -279,28 +276,30 @@ public:
|
||||||
// Use that instead "= new T(parent, ...)"
|
// Use that instead "= new T(parent, ...)"
|
||||||
template <typename Parent, typename... Args>
|
template <typename Parent, typename... Args>
|
||||||
void create(Parent &&parent, Args&&... args) {
|
void create(Parent &&parent, Args&&... args) {
|
||||||
delete _widget;
|
delete _object;
|
||||||
_widget = new T(std_::forward<Parent>(parent), std_::forward<Args>(args)...);
|
_object = new T(std_::forward<Parent>(parent), std_::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
void destroy() {
|
void destroy() {
|
||||||
if (_widget) {
|
delete base::take(_object);
|
||||||
delete _widget;
|
|
||||||
_widget = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void destroyDelayed() {
|
void destroyDelayed() {
|
||||||
if (_widget) {
|
if (_object) {
|
||||||
_widget->hide();
|
if (auto widget = base::up_cast<QWidget*>(_object)) {
|
||||||
_widget->deleteLater();
|
widget->hide();
|
||||||
_widget = nullptr;
|
}
|
||||||
|
_object->deleteLater();
|
||||||
|
_object = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T *_widget;
|
T *_object;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using ChildWidget = ChildObject<T>;
|
||||||
|
|
||||||
void sendSynteticMouseEvent(QWidget *widget, QEvent::Type type, Qt::MouseButton button, const QPoint &globalPoint);
|
void sendSynteticMouseEvent(QWidget *widget, QEvent::Type type, Qt::MouseButton button, const QPoint &globalPoint);
|
||||||
|
|
||||||
inline void sendSynteticMouseEvent(QWidget *widget, QEvent::Type type, Qt::MouseButton button) {
|
inline void sendSynteticMouseEvent(QWidget *widget, QEvent::Type type, Qt::MouseButton button) {
|
||||||
|
|
|
@ -68,6 +68,10 @@ QAction *DropdownMenu::addAction(const QString &text, const QObject *receiver, c
|
||||||
return _menu->addAction(text, receiver, member, icon, iconOver);
|
return _menu->addAction(text, receiver, member, icon, iconOver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAction *DropdownMenu::addAction(const QString &text, base::lambda_unique<void()> callback, const style::icon *icon, const style::icon *iconOver) {
|
||||||
|
return _menu->addAction(text, std_::move(callback), icon, iconOver);
|
||||||
|
}
|
||||||
|
|
||||||
QAction *DropdownMenu::addSeparator() {
|
QAction *DropdownMenu::addSeparator() {
|
||||||
return _menu->addSeparator();
|
return _menu->addSeparator();
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ public:
|
||||||
DropdownMenu(QWidget *parent, const style::DropdownMenu &st = st::defaultDropdownMenu);
|
DropdownMenu(QWidget *parent, const style::DropdownMenu &st = st::defaultDropdownMenu);
|
||||||
|
|
||||||
QAction *addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
QAction *addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
||||||
|
QAction *addAction(const QString &text, base::lambda_unique<void()> callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
||||||
QAction *addSeparator();
|
QAction *addSeparator();
|
||||||
void clearActions();
|
void clearActions();
|
||||||
|
|
||||||
|
|
|
@ -50,9 +50,15 @@ void Menu::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QAction *Menu::addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon, const style::icon *iconOver) {
|
QAction *Menu::addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon, const style::icon *iconOver) {
|
||||||
auto action = new QAction(text, this);
|
auto action = addAction(new QAction(text, this), icon, iconOver);
|
||||||
connect(action, SIGNAL(triggered(bool)), receiver, member, Qt::QueuedConnection);
|
connect(action, SIGNAL(triggered(bool)), receiver, member, Qt::QueuedConnection);
|
||||||
return addAction(action, icon, iconOver);
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
QAction *Menu::addAction(const QString &text, base::lambda_unique<void()> callback, const style::icon *icon, const style::icon *iconOver) {
|
||||||
|
auto action = addAction(new QAction(text, this), icon, iconOver);
|
||||||
|
connect(action, SIGNAL(triggered(bool)), base::lambda_slot(action, std_::move(callback)), SLOT(action()), Qt::QueuedConnection);
|
||||||
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
QAction *Menu::addAction(QAction *action, const style::icon *icon, const style::icon *iconOver) {
|
QAction *Menu::addAction(QAction *action, const style::icon *icon, const style::icon *iconOver) {
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
Menu(QWidget *parent, QMenu *menu, const style::Menu &st = st::defaultMenu);
|
Menu(QWidget *parent, QMenu *menu, const style::Menu &st = st::defaultMenu);
|
||||||
|
|
||||||
QAction *addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
QAction *addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
||||||
|
QAction *addAction(const QString &text, base::lambda_unique<void()> callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
||||||
QAction *addSeparator();
|
QAction *addSeparator();
|
||||||
void clearActions();
|
void clearActions();
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,10 @@ QAction *PopupMenu::addAction(const QString &text, const QObject *receiver, cons
|
||||||
return _menu->addAction(text, receiver, member, icon, iconOver);
|
return _menu->addAction(text, receiver, member, icon, iconOver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAction *PopupMenu::addAction(const QString &text, base::lambda_unique<void()> callback, const style::icon *icon, const style::icon *iconOver) {
|
||||||
|
return _menu->addAction(text, std_::move(callback), icon, iconOver);
|
||||||
|
}
|
||||||
|
|
||||||
QAction *PopupMenu::addSeparator() {
|
QAction *PopupMenu::addSeparator() {
|
||||||
return _menu->addSeparator();
|
return _menu->addSeparator();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ public:
|
||||||
PopupMenu(QMenu *menu, const style::PopupMenu &st = st::defaultPopupMenu);
|
PopupMenu(QMenu *menu, const style::PopupMenu &st = st::defaultPopupMenu);
|
||||||
|
|
||||||
QAction *addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
QAction *addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
||||||
|
QAction *addAction(const QString &text, base::lambda_unique<void()> callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
||||||
QAction *addSeparator();
|
QAction *addSeparator();
|
||||||
void clearActions();
|
void clearActions();
|
||||||
|
|
||||||
|
|
|
@ -190,6 +190,9 @@ defaultMaskButton: MaskButton {
|
||||||
widgetSlideDuration: 200;
|
widgetSlideDuration: 200;
|
||||||
widgetFadeDuration: 200;
|
widgetFadeDuration: 200;
|
||||||
|
|
||||||
|
fieldSearchIcon: icon {{ "box_search", #aaaaaa, point(9px, 8px) }};
|
||||||
|
boxFieldSearchIcon: icon {{ "box_search", #aaaaaa, point(10px, 9px) }};
|
||||||
|
|
||||||
discreteSliderHeight: 39px;
|
discreteSliderHeight: 39px;
|
||||||
discreteSliderTop: 5px;
|
discreteSliderTop: 5px;
|
||||||
discreteSliderSkip: 3px;
|
discreteSliderSkip: 3px;
|
||||||
|
|
|
@ -21,9 +21,147 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "window/main_window.h"
|
#include "window/main_window.h"
|
||||||
|
|
||||||
|
#include "localstorage.h"
|
||||||
|
#include "styles/style_window.h"
|
||||||
|
#include "platform/platform_window_title.h"
|
||||||
|
#include "window/window_theme.h"
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
|
||||||
MainWindow::MainWindow() {
|
MainWindow::MainWindow() : QMainWindow()
|
||||||
|
, _positionUpdatedTimer(this)
|
||||||
|
, _body(this) {
|
||||||
|
setCentralWidget(_body);
|
||||||
|
subscribe(Theme::Background(), [this](const Theme::BackgroundUpdate &data) {
|
||||||
|
using Type = Theme::BackgroundUpdate::Type;
|
||||||
|
if (data.type == Type::TestingTheme || data.type == Type::RevertingTheme || data.type == Type::ApplyingTheme) {
|
||||||
|
if (_title) {
|
||||||
|
_title->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::init() {
|
||||||
|
_positionUpdatedTimer->setSingleShot(true);
|
||||||
|
connect(_positionUpdatedTimer, SIGNAL(timeout()), this, SLOT(savePositionByTimer()));
|
||||||
|
|
||||||
|
_title = Platform::CreateTitleWidget(this);
|
||||||
|
|
||||||
|
auto p = palette();
|
||||||
|
p.setColor(QPalette::Window, st::windowBg->c);
|
||||||
|
setPalette(p);
|
||||||
|
|
||||||
|
initSize();
|
||||||
|
|
||||||
|
initHook();
|
||||||
|
}
|
||||||
|
|
||||||
|
HitTestResult MainWindow::hitTest(const QPoint &p) const {
|
||||||
|
auto titleResult = _title ? _title->hitTest(p - _title->geometry().topLeft()) : Window::HitTestResult::None;
|
||||||
|
if (titleResult != Window::HitTestResult::None) {
|
||||||
|
return titleResult;
|
||||||
|
} else if (rect().contains(p)) {
|
||||||
|
return Window::HitTestResult::Client;
|
||||||
|
}
|
||||||
|
return Window::HitTestResult::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::initSize() {
|
||||||
|
setMinimumWidth(st::windowMinWidth);
|
||||||
|
setMinimumHeight((_title ? _title->height() : 0) + st::windowMinHeight);
|
||||||
|
|
||||||
|
auto pos = cWindowPos();
|
||||||
|
auto avail = QDesktopWidget().availableGeometry();
|
||||||
|
bool maximized = false;
|
||||||
|
auto geom = QRect(avail.x() + (avail.width() - st::windowDefaultWidth) / 2, avail.y() + (avail.height() - st::windowDefaultHeight) / 2, st::windowDefaultWidth, st::windowDefaultHeight);
|
||||||
|
if (pos.w && pos.h) {
|
||||||
|
for (auto screen : QGuiApplication::screens()) {
|
||||||
|
if (pos.moncrc == screenNameChecksum(screen->name())) {
|
||||||
|
auto screenGeometry = screen->geometry();
|
||||||
|
auto w = screenGeometry.width(), h = screenGeometry.height();
|
||||||
|
if (w >= st::windowMinWidth && h >= st::windowMinHeight) {
|
||||||
|
if (pos.w > w) pos.w = w;
|
||||||
|
if (pos.h > h) pos.h = h;
|
||||||
|
pos.x += screenGeometry.x();
|
||||||
|
pos.y += screenGeometry.y();
|
||||||
|
if (pos.x + st::windowMinWidth <= screenGeometry.x() + screenGeometry.width() &&
|
||||||
|
pos.y + st::windowMinHeight <= screenGeometry.y() + screenGeometry.height()) {
|
||||||
|
geom = QRect(pos.x, pos.y, pos.w, pos.h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos.y < 0) pos.y = 0;
|
||||||
|
maximized = pos.maximized;
|
||||||
|
}
|
||||||
|
setGeometry(geom);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::positionUpdated() {
|
||||||
|
_positionUpdatedTimer->start(SaveWindowPositionTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 MainWindow::screenNameChecksum(const QString &name) const {
|
||||||
|
auto bytes = name.toUtf8();
|
||||||
|
return hashCrc32(bytes.constData(), bytes.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setPositionInited() {
|
||||||
|
_positionInited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::resizeEvent(QResizeEvent *e) {
|
||||||
|
auto bodyTop = 0;
|
||||||
|
if (_title) {
|
||||||
|
_title->setGeometry(0, bodyTop, width(), st::titleHeight);
|
||||||
|
bodyTop += _title->height();
|
||||||
|
}
|
||||||
|
_body->setGeometry(0, bodyTop, width(), height() - bodyTop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::savePosition(Qt::WindowState state) {
|
||||||
|
if (state == Qt::WindowActive) state = windowHandle()->windowState();
|
||||||
|
if (state == Qt::WindowMinimized || !positionInited()) return;
|
||||||
|
|
||||||
|
TWindowPos pos(cWindowPos()), curPos = pos;
|
||||||
|
|
||||||
|
if (state == Qt::WindowMaximized) {
|
||||||
|
curPos.maximized = 1;
|
||||||
|
} else {
|
||||||
|
QRect r(geometry());
|
||||||
|
curPos.x = r.x();
|
||||||
|
curPos.y = r.y();
|
||||||
|
curPos.w = r.width();
|
||||||
|
curPos.h = r.height();
|
||||||
|
curPos.maximized = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int px = curPos.x + curPos.w / 2, py = curPos.y + curPos.h / 2;
|
||||||
|
int minDelta = 0;
|
||||||
|
QScreen *chosen = 0;
|
||||||
|
auto screens = QGuiApplication::screens();
|
||||||
|
for (auto screen : QGuiApplication::screens()) {
|
||||||
|
auto delta = (screen->geometry().center() - QPoint(px, py)).manhattanLength();
|
||||||
|
if (!chosen || delta < minDelta) {
|
||||||
|
minDelta = delta;
|
||||||
|
chosen = screen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (chosen) {
|
||||||
|
curPos.x -= chosen->geometry().x();
|
||||||
|
curPos.y -= chosen->geometry().y();
|
||||||
|
curPos.moncrc = screenNameChecksum(chosen->name());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curPos.w >= st::windowMinWidth && curPos.h >= st::windowMinHeight) {
|
||||||
|
if (curPos.x != pos.x || curPos.y != pos.y || curPos.w != pos.w || curPos.h != pos.h || curPos.moncrc != pos.moncrc || curPos.maximized != pos.maximized) {
|
||||||
|
cSetWindowPos(curPos);
|
||||||
|
Local::writeSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() {
|
MainWindow::~MainWindow() {
|
||||||
|
|
|
@ -20,20 +20,63 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "window/window_title.h"
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
|
||||||
class MainWindow : public QMainWindow {
|
class TitleWidget;
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow, protected base::Subscriber {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MainWindow();
|
MainWindow();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
HitTestResult hitTest(const QPoint &p) const;
|
||||||
|
|
||||||
|
bool positionInited() const {
|
||||||
|
return _positionInited;
|
||||||
|
}
|
||||||
|
void positionUpdated();
|
||||||
|
|
||||||
virtual void closeWithoutDestroy();
|
virtual void closeWithoutDestroy();
|
||||||
|
|
||||||
virtual ~MainWindow();
|
virtual ~MainWindow();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
|
QWidget *bodyWidget() { // temp
|
||||||
|
return _body;
|
||||||
|
}
|
||||||
|
void savePosition(Qt::WindowState state = Qt::WindowActive);
|
||||||
|
|
||||||
|
virtual void initHook() {
|
||||||
|
}
|
||||||
|
|
||||||
virtual void stateChangedHook(Qt::WindowState state) {
|
virtual void stateChangedHook(Qt::WindowState state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This one is overriden in Windows for historical reasons.
|
||||||
|
virtual int32 screenNameChecksum(const QString &name) const;
|
||||||
|
|
||||||
|
void setPositionInited();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void savePositionByTimer() {
|
||||||
|
savePosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initSize();
|
||||||
|
|
||||||
|
ChildObject<QTimer> _positionUpdatedTimer;
|
||||||
|
bool _positionInited = false;
|
||||||
|
|
||||||
|
ChildWidget<TitleWidget> _title = { nullptr };
|
||||||
|
ChildWidget<QWidget> _body;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
|
@ -446,6 +446,7 @@ void Widget::addToHeight(int add) {
|
||||||
auto newHeight = height() + add;
|
auto newHeight = height() + add;
|
||||||
auto newPosition = computePosition(newHeight);
|
auto newPosition = computePosition(newHeight);
|
||||||
updateGeometry(newPosition.x(), newPosition.y(), width(), newHeight);
|
updateGeometry(newPosition.x(), newPosition.y(), width(), newHeight);
|
||||||
|
psUpdateOverlayed(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::updateGeometry(int x, int y, int width, int height) {
|
void Widget::updateGeometry(int x, int y, int width, int height) {
|
||||||
|
|
|
@ -24,8 +24,8 @@ using "ui/widgets/widgets.style";
|
||||||
|
|
||||||
windowMinWidth: 380px;
|
windowMinWidth: 380px;
|
||||||
windowMinHeight: 480px;
|
windowMinHeight: 480px;
|
||||||
windowDefWidth: 800px;
|
windowDefaultWidth: 800px;
|
||||||
windowDefHeight: 600px;
|
windowDefaultHeight: 600px;
|
||||||
windowShadow: icon {{ "window_shadow", windowShadowFg }};
|
windowShadow: icon {{ "window_shadow", windowShadowFg }};
|
||||||
windowShadowShift: 1px;
|
windowShadowShift: 1px;
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ enum class HitTestResult {
|
||||||
None = 0,
|
None = 0,
|
||||||
Client,
|
Client,
|
||||||
SysButton,
|
SysButton,
|
||||||
Icon,
|
|
||||||
Caption,
|
Caption,
|
||||||
Top,
|
Top,
|
||||||
TopRight,
|
TopRight,
|
||||||
|
|