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);
|
||||
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;
|
||||
topBarDuration: 200;
|
||||
topBarForward: icon {{ "title_next", #a3a3a3 }};
|
||||
topBarBackward: icon {{ "title_previous", #a3a3a3 }};
|
||||
topBarForward: icon {{ "title_back-flip_horizontal", #a3a3a3 }};
|
||||
topBarBackward: icon {{ "title_back", #a3a3a3 }};
|
||||
topBarForwardAlpha: 0.6;
|
||||
topBarBack: icon {{ "title_previous", #259fd8 }};
|
||||
topBarBack: icon {{ "title_back", #259fd8 }};
|
||||
topBarBackAlpha: 0.8;
|
||||
topBarBackColor: #005faf;
|
||||
topBarBackFont: font(16px);
|
||||
|
@ -1104,15 +1091,15 @@ infoButton: PeerAvatarButton {
|
|||
photoSize: 42px;
|
||||
}
|
||||
|
||||
// forward declaration for single "title_previous" usage.
|
||||
// forward declaration for single "title_back" usage.
|
||||
profileTopBarBackIconFg: #0290d7;
|
||||
profileTopBarBackIcon: icon {{ "title_previous", profileTopBarBackIconFg }};
|
||||
profileTopBarBackIcon: icon {{ "title_back", profileTopBarBackIconFg }};
|
||||
|
||||
historyReplyCancelIcon: icon {{ "box_button_close-invert", historyReplyBg }};
|
||||
boxSearchCancelIcon: icon {{ "box_button_close-invert", boxSearchBg }};
|
||||
settingsFixedBarCloseIcon: icon {{ "box_button_close-invert", settingsFixedBarBg }};
|
||||
|
||||
notifyFadeRight: icon {{ "fade_horizontal_right", notificationBg }};
|
||||
notifyFadeRight: icon {{ "fade_horizontal", notificationBg }};
|
||||
|
||||
stickerIconLeft: icon {{ "fade_horizontal_left", emojiPanCategories }};
|
||||
stickerIconRight: icon {{ "fade_horizontal_right", emojiPanCategories }};
|
||||
stickerIconLeft: icon {{ "fade_horizontal-flip_horizontal", emojiPanCategories }};
|
||||
stickerIconRight: icon {{ "fade_horizontal", emojiPanCategories }};
|
||||
|
|
|
@ -24,7 +24,7 @@ windowBg: #ffffff; // white: fallback for background
|
|||
windowTextFg: #000000; // black: fallback for text color
|
||||
windowSubTextFg: #8a8a8a; // gray: fallback for subtext color
|
||||
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
|
||||
windowActiveTextFg: #1485c2; // online blue: fallback for active color
|
||||
windowShadowFg: #000000; // black: fallback for shadow color
|
||||
|
@ -32,22 +32,7 @@ windowShadowFg: #000000; // black: fallback for shadow color
|
|||
imageBg: #000000;
|
||||
imageBgTransparent: #ffffff;
|
||||
|
||||
// custom title bar for Windows
|
||||
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;
|
||||
|
||||
// widgets
|
||||
cancelIconFg: #a2a2a2;
|
||||
cancelIconFgOver: #808080;
|
||||
|
||||
|
@ -63,6 +48,24 @@ lightButtonBgOver: #f2f7fa | lightButtonBg;
|
|||
lightButtonFg: #2b99d5;
|
||||
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
|
||||
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_create" = "Create";
|
||||
"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_about" = "Channels are a tool for broadcasting your messages to unlimited audiences";
|
||||
"lng_create_public_channel_title" = "Public Channel";
|
||||
"lng_create_public_channel_about" = "Anyone can find the channel in search and join";
|
||||
"lng_create_private_channel_title" = "Private Channel";
|
||||
|
|
|
@ -25,24 +25,12 @@ windowBg: #ffffff;
|
|||
windowTextFg: #000000;
|
||||
windowSubTextFg: #8a8a8a;
|
||||
windowActiveFill: #40ace3;
|
||||
windowOverBg: #edf2f5;
|
||||
windowOverBg: #f3f3f3;
|
||||
windowSubTextFgOver: #7c99b2;
|
||||
windowActiveTextFg: #1485c2;
|
||||
windowShadowFg: #000000;
|
||||
imageBg: #000000;
|
||||
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;
|
||||
cancelIconFgOver: #808080;
|
||||
activeButtonBg: windowActiveFill;
|
||||
|
@ -55,6 +43,19 @@ lightButtonBg: windowBg;
|
|||
lightButtonBgOver: #f2f7fa; // lightButtonBg;
|
||||
lightButtonFg: #2b99d5;
|
||||
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;
|
||||
boxBg: windowBg;
|
||||
boxTextFg: windowTextFg;
|
||||
|
|
|
@ -260,64 +260,6 @@ void AddContactBox::onRetry() {
|
|||
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(),
|
||||
_creating(creating),
|
||||
a_photoOver(0, 0),
|
||||
|
|
|
@ -78,34 +78,6 @@ private:
|
|||
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 {
|
||||
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
|
||||
*/
|
||||
using "basic.style";
|
||||
|
||||
using "ui/widgets/widgets.style";
|
||||
using "intro/intro.style";
|
||||
|
||||
|
@ -143,7 +144,7 @@ contactsMultiSelect: MultiSelect {
|
|||
font: normalFont;
|
||||
}
|
||||
fieldMinWidth: 42px;
|
||||
fieldIcon: fieldSearchIcon;
|
||||
fieldIcon: boxFieldSearchIcon;
|
||||
fieldIconSkip: 36px;
|
||||
|
||||
fieldCancel: MaskButton(defaultMaskButton) {
|
||||
|
|
|
@ -38,8 +38,8 @@ namespace codegen {
|
|||
namespace style {
|
||||
namespace {
|
||||
|
||||
constexpr int kErrorBadIconSize = 861;
|
||||
constexpr int kErrorBadIconFormat = 862;
|
||||
constexpr int kErrorBadIconSize = 861;
|
||||
constexpr int kErrorBadIconFormat = 862;
|
||||
|
||||
// crc32 hash, taken somewhere from the internet
|
||||
|
||||
|
@ -1017,10 +1017,10 @@ QByteArray iconMaskValueSize(int width, int height) {
|
|||
QByteArray iconMaskValuePng(QString filepath) {
|
||||
QByteArray result;
|
||||
|
||||
auto inverted = filepath.endsWith("-invert");
|
||||
if (inverted) {
|
||||
filepath.chop(QLatin1String("-invert").size());
|
||||
}
|
||||
auto pathAndModifiers = filepath.split('-');
|
||||
filepath = pathAndModifiers[0];
|
||||
auto modifiers = pathAndModifiers.mid(1);
|
||||
|
||||
QImage png100x(filepath + ".png");
|
||||
QImage png200x(filepath + "@2x.png");
|
||||
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();
|
||||
return result;
|
||||
}
|
||||
if (inverted) {
|
||||
png100x.invertPixels();
|
||||
png200x.invertPixels();
|
||||
for (auto modifierName : modifiers) {
|
||||
if (auto modifier = GetModifier(modifierName)) {
|
||||
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 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 kErrorBadString = 806;
|
||||
constexpr int kErrorIconDuplicate = 807;
|
||||
constexpr int kErrorBadIconModifier = 808;
|
||||
|
||||
QString findInputFile(const Options &options) {
|
||||
for (const auto &dir : options.includePaths) {
|
||||
|
@ -151,6 +152,25 @@ bool validateAlignString(const QString &value) {
|
|||
|
||||
} // 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)
|
||||
: filePath_(findInputFile(options))
|
||||
, file_(filePath_)
|
||||
|
@ -821,21 +841,26 @@ structure::data::monoicon ParsedFile::readMonoIconFields() {
|
|||
QString ParsedFile::readMonoIconFilename() {
|
||||
if (auto filename = readValue()) {
|
||||
if (filename.type().tag == structure::TypeTag::String) {
|
||||
auto filepath = QString::fromStdString(filename.String());
|
||||
auto inverted = filepath.endsWith("-invert");
|
||||
if (inverted) {
|
||||
filepath.chop(QLatin1String("-invert").size());
|
||||
}
|
||||
for (const auto &path : options_.includePaths) {
|
||||
QFileInfo fileinfo(path + '/' + filepath + ".png");
|
||||
if (fileinfo.exists()) {
|
||||
return path + '/' + filepath + (inverted ? "-invert" : "");
|
||||
auto fullpath = QString::fromStdString(filename.String());
|
||||
auto pathAndModifiers = fullpath.split('-');
|
||||
auto filepath = pathAndModifiers[0];
|
||||
auto modifiers = pathAndModifiers.mid(1);
|
||||
for (auto modifierName : modifiers) {
|
||||
if (!GetModifier(modifierName)) {
|
||||
logError(kErrorBadIconModifier) << "unknown modifier: " << modifierName.toStdString();
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
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");
|
||||
if (fileinfo.exists()) {
|
||||
return path + "/icons/" + filepath + (inverted ? "-invert" : "");
|
||||
return path + "/icons/" + fullpath;
|
||||
}
|
||||
}
|
||||
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 <string>
|
||||
#include <functional>
|
||||
#include <QImage>
|
||||
#include "codegen/common/basic_tokenized_file.h"
|
||||
#include "codegen/style/options.h"
|
||||
#include "codegen/style/module.h"
|
||||
|
@ -29,6 +31,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
namespace codegen {
|
||||
namespace style {
|
||||
|
||||
using Modifier = std::function<void(QImage &png100x, QImage &png200x)>;
|
||||
Modifier GetModifier(const QString &name);
|
||||
|
||||
// Parses an input file to the internal struct.
|
||||
class ParsedFile {
|
||||
public:
|
||||
|
@ -44,7 +49,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
bool failed() const {
|
||||
return failed_ || file_.failed();
|
||||
}
|
||||
|
|
|
@ -59,6 +59,8 @@ template <typename T>
|
|||
struct remove_reference<T&&> {
|
||||
using type = T;
|
||||
};
|
||||
template <typename T>
|
||||
using remove_reference_t = typename remove_reference<T>::type;
|
||||
|
||||
template <typename T>
|
||||
struct is_lvalue_reference : false_type {
|
||||
|
|
|
@ -25,7 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
namespace base {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,27 @@ inline T take(T &source, T &&new_value = T()) {
|
|||
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
|
||||
|
||||
template <typename Enum>
|
||||
|
|
|
@ -48,7 +48,7 @@ dialogsNameFg: #000000;
|
|||
dialogsNameTop: 2px;
|
||||
|
||||
dialogsRowHeight: 62px;
|
||||
dialogsFilterPadding: 10px;
|
||||
dialogsFilterPadding: point(11px, 11px);
|
||||
dialogsPhotoSize: 46px;
|
||||
dialogsPhotoPadding: 12px;
|
||||
dialogsPadding: point(10px, 8px);
|
||||
|
@ -83,24 +83,44 @@ dialogsTextStyleDraftActive: textStyle(dialogsTextStyle) {
|
|||
linkFgDown: #c6e1f7;
|
||||
}
|
||||
|
||||
dialogsNewChatIcon: icon {{ "dialogs_new_chat", #b7b7b7 }};
|
||||
dialogsNewChatButton: IconButton {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
dialogsMenuToggle: IconButton {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
|
||||
icon: dialogsNewChatIcon;
|
||||
iconPosition: point(9px, 10px);
|
||||
iconPositionDown: point(9px, 11px);
|
||||
icon: icon {{ "dialogs_menu", #999999 }};
|
||||
iconPosition: point(6px, 6px);
|
||||
iconPositionDown: point(6px, 6px);
|
||||
}
|
||||
dialogsAddContact: IconButton(dialogsNewChatButton) {
|
||||
icon: icon {{ "dialogs_add_contact", #a6a6a6 }};
|
||||
iconPosition: point(8px, 8px);
|
||||
iconPositionDown: point(8px, 9px);
|
||||
dialogsFilter: flatInput(inpDefGray) {
|
||||
font: font(fsize);
|
||||
bgColor: #f2f2f2;
|
||||
phColor: #949494;
|
||||
phFocusColor: #a4a4a4;
|
||||
icon: fieldSearchIcon;
|
||||
|
||||
width: 240px;
|
||||
height: 32px;
|
||||
textMrg: margins(32px, 3px, 32px, 3px);
|
||||
}
|
||||
dialogsCancelSearch: IconButton(dialogsAddContact) {
|
||||
icon: icon {{ "dialogs_cancel_search", #a6a6a6 }};
|
||||
dialogsCancelSearch: IconButton(dialogsMenuToggle) {
|
||||
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;
|
||||
dialogsChatIcon: icon {{ "dialogs_chat", #373737, 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/contactsbox.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "boxes/aboutbox.h"
|
||||
#include "localstorage.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))
|
||||
, contactsNoDialogs(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;
|
||||
}
|
||||
|
||||
DialogsWidget::DialogsWidget(MainWidget *parent) : TWidget(parent)
|
||||
, _dragInScroll(false)
|
||||
, _dragForward(false)
|
||||
, _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)
|
||||
DialogsWidget::DialogsWidget(QWidget *parent) : TWidget(parent)
|
||||
, _mainMenuToggle(this, st::dialogsMenuToggle)
|
||||
, _filter(this, st::dialogsFilter, lang(lng_dlg_filter))
|
||||
, _cancelSearch(this, st::dialogsCancelSearch)
|
||||
, _scroll(this, st::dialogsScroll)
|
||||
, _inner(&_scroll, parent)
|
||||
, _a_show(animation(this, &DialogsWidget::step_show))
|
||||
, _searchInPeer(0)
|
||||
, _searchInMigrated(0)
|
||||
, _searchFull(false)
|
||||
, _searchFullMigrated(false)
|
||||
, _peopleFull(false)
|
||||
{
|
||||
, _a_show(animation(this, &DialogsWidget::step_show)) {
|
||||
_scroll.setWidget(&_inner);
|
||||
_scroll.setFocusPolicy(Qt::NoFocus);
|
||||
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(&_scroll, SIGNAL(geometryChanged()), &_inner, SLOT(onParentGeometryChanged()));
|
||||
connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll()));
|
||||
connect(&_filter, SIGNAL(cancelled()), this, SLOT(onCancel()));
|
||||
connect(&_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate()));
|
||||
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(_filter, SIGNAL(cancelled()), this, SLOT(onCancel()));
|
||||
connect(_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate()));
|
||||
connect(_filter, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(onFilterCursorMoved(int,int)));
|
||||
connect(_cancelSearch, SIGNAL(clicked()), this, SLOT(onCancelSearch()));
|
||||
|
||||
_mainMenuToggle->setClickedCallback([this] { showMainMenu(); });
|
||||
|
||||
_chooseByDragTimer.setSingleShot(true);
|
||||
connect(&_chooseByDragTimer, SIGNAL(timeout()), this, SLOT(onChooseByDrag()));
|
||||
|
||||
|
@ -1819,21 +1805,13 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : TWidget(parent)
|
|||
_searchTimer.setSingleShot(true);
|
||||
connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchMessages()));
|
||||
|
||||
_scroll.show();
|
||||
_filter.show();
|
||||
_filter.move(st::dialogsPadding.x(), st::dialogsFilterPadding);
|
||||
_filter.setFocusPolicy(Qt::StrongFocus);
|
||||
_filter.customUpDown(true);
|
||||
_addContact->hide();
|
||||
_newGroup->show();
|
||||
_filter->setFocusPolicy(Qt::StrongFocus);
|
||||
_filter->customUpDown(true);
|
||||
_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() {
|
||||
_filter.setFocus();
|
||||
_filter->setFocus();
|
||||
_inner.activate();
|
||||
}
|
||||
|
||||
|
@ -1858,7 +1836,7 @@ void DialogsWidget::dlgUpdated(History *row, MsgId msgId) {
|
|||
}
|
||||
|
||||
void DialogsWidget::dialogsToUp() {
|
||||
if (_filter.getLastText().trimmed().isEmpty()) {
|
||||
if (_filter->getLastText().trimmed().isEmpty()) {
|
||||
_scroll.scrollToY(0);
|
||||
}
|
||||
}
|
||||
|
@ -1873,9 +1851,8 @@ void DialogsWidget::showAnimated(Window::SlideDirection direction, const Window:
|
|||
_a_show.stop();
|
||||
|
||||
_scroll.hide();
|
||||
_filter.hide();
|
||||
_filter->hide();
|
||||
_cancelSearch->hide();
|
||||
_newGroup->hide();
|
||||
|
||||
int delta = st::slideShift;
|
||||
if (direction == Window::SlideDirection::FromLeft) {
|
||||
|
@ -1903,7 +1880,7 @@ void DialogsWidget::step_show(float64 ms, bool timer) {
|
|||
_cacheUnder = _cacheOver = QPixmap();
|
||||
|
||||
_scroll.show();
|
||||
_filter.show();
|
||||
_filter->show();
|
||||
_a_show.stop();
|
||||
|
||||
onFilterUpdate();
|
||||
|
@ -1930,8 +1907,8 @@ void DialogsWidget::updateNotifySettings(PeerData *peer) {
|
|||
|
||||
void DialogsWidget::notify_userIsContactChanged(UserData *user, bool fromThisApp) {
|
||||
if (fromThisApp) {
|
||||
_filter.setText(QString());
|
||||
_filter.updatePlaceholder();
|
||||
_filter->setText(QString());
|
||||
_filter->updatePlaceholder();
|
||||
onFilterUpdate();
|
||||
}
|
||||
_inner.notify_userIsContactChanged(user, fromThisApp);
|
||||
|
@ -2031,7 +2008,7 @@ bool DialogsWidget::dialogsFailed(const RPCError &error, mtpRequestId req) {
|
|||
}
|
||||
|
||||
bool DialogsWidget::onSearchMessages(bool searchCache) {
|
||||
QString q = _filter.getLastText().trimmed();
|
||||
QString q = _filter->getLastText().trimmed();
|
||||
if (q.isEmpty()) {
|
||||
if (_searchRequest) {
|
||||
MTP::cancel(_searchRequest);
|
||||
|
@ -2098,16 +2075,39 @@ void DialogsWidget::onChooseByDrag() {
|
|||
_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) {
|
||||
if ((_filter.getLastText() != query) || (inPeer && inPeer != _searchInPeer && inPeer->migrateTo() != _searchInPeer)) {
|
||||
if ((_filter->getLastText() != query) || (inPeer && inPeer != _searchInPeer && inPeer->migrateTo() != _searchInPeer)) {
|
||||
if (inPeer) {
|
||||
onCancelSearch();
|
||||
_searchInPeer = inPeer->migrateTo() ? inPeer->migrateTo() : inPeer;
|
||||
_searchInMigrated = _searchInPeer ? _searchInPeer->migrateFrom() : 0;
|
||||
_inner.searchInPeer(_searchInPeer);
|
||||
}
|
||||
_filter.setText(query);
|
||||
_filter.updatePlaceholder();
|
||||
_filter->setText(query);
|
||||
_filter->updatePlaceholder();
|
||||
onFilterUpdate(true);
|
||||
_searchTimer.stop();
|
||||
onSearchMessages();
|
||||
|
@ -2371,17 +2371,15 @@ void DialogsWidget::onListScroll() {
|
|||
void DialogsWidget::onFilterUpdate(bool force) {
|
||||
if (_a_show.animating() && !force) return;
|
||||
|
||||
QString filterText = _filter.getLastText();
|
||||
QString filterText = _filter->getLastText();
|
||||
_inner.onFilterUpdate(filterText, force);
|
||||
if (filterText.isEmpty()) {
|
||||
_searchCache.clear();
|
||||
_searchQueries.clear();
|
||||
_searchQuery = QString();
|
||||
_cancelSearch->hide();
|
||||
_newGroup->show();
|
||||
} else if (_cancelSearch->isHidden()) {
|
||||
_cancelSearch->show();
|
||||
_newGroup->hide();
|
||||
}
|
||||
if (filterText.size() < MinUsernameLength) {
|
||||
_peopleCache.clear();
|
||||
|
@ -2399,8 +2397,8 @@ void DialogsWidget::searchInPeer(PeerData *peer) {
|
|||
}
|
||||
|
||||
void DialogsWidget::onFilterCursorMoved(int from, int to) {
|
||||
if (to < 0) to = _filter.cursorPosition();
|
||||
QString t = _filter.getLastText();
|
||||
if (to < 0) to = _filter->cursorPosition();
|
||||
QString t = _filter->getLastText();
|
||||
QStringRef r;
|
||||
for (int start = to; start > 0;) {
|
||||
--start;
|
||||
|
@ -2415,8 +2413,8 @@ void DialogsWidget::onFilterCursorMoved(int from, int to) {
|
|||
}
|
||||
|
||||
void DialogsWidget::onCompleteHashtag(QString tag) {
|
||||
QString t = _filter.getLastText(), r;
|
||||
int cur = _filter.cursorPosition();
|
||||
QString t = _filter->getLastText(), r;
|
||||
int cur = _filter->cursorPosition();
|
||||
for (int start = cur; start > 0;) {
|
||||
--start;
|
||||
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;
|
||||
r = t.mid(0, start + 1) + tag + ' ' + t.mid(cur);
|
||||
_filter.setText(r);
|
||||
_filter.setCursorPosition(start + 1 + tag.size() + 1);
|
||||
_filter->setText(r);
|
||||
_filter->setCursorPosition(start + 1 + tag.size() + 1);
|
||||
onFilterUpdate(true);
|
||||
return;
|
||||
}
|
||||
|
@ -2436,22 +2434,23 @@ void DialogsWidget::onCompleteHashtag(QString tag) {
|
|||
}
|
||||
if (!t.at(start).isLetterOrNumber() && t.at(start) != '_') break;
|
||||
}
|
||||
_filter.setText(t.mid(0, cur) + '#' + tag + ' ' + t.mid(cur));
|
||||
_filter.setCursorPosition(cur + 1 + tag.size() + 1);
|
||||
_filter->setText(t.mid(0, cur) + '#' + tag + ' ' + t.mid(cur));
|
||||
_filter->setCursorPosition(cur + 1 + tag.size() + 1);
|
||||
onFilterUpdate(true);
|
||||
}
|
||||
|
||||
void DialogsWidget::resizeEvent(QResizeEvent *e) {
|
||||
int32 w = width();
|
||||
_filter.setGeometry(st::dialogsPadding.x(), st::dialogsFilterPadding, w - 2 * st::dialogsPadding.x(), _filter.height());
|
||||
_newGroup->move(w - _newGroup->width() - st::dialogsPadding.x(), _filter.y());
|
||||
_addContact->move(w - _addContact->width() - st::dialogsPadding.x(), _filter.y());
|
||||
_cancelSearch->move(w - _cancelSearch->width() - st::dialogsPadding.x(), _filter.y());
|
||||
_scroll.move(0, _filter.height() + 2 * st::dialogsFilterPadding);
|
||||
_filter->setGeometryToLeft(st::dialogsFilterPadding.x() * 2 + _mainMenuToggle->width(), st::dialogsFilterPadding.y(), w - 3 * st::dialogsFilterPadding.x() - _mainMenuToggle->width(), _filter->height());
|
||||
_mainMenuToggle->moveToLeft(st::dialogsFilterPadding.x(), _filter->y());
|
||||
_cancelSearch->moveToRight(st::dialogsFilterPadding.x(), _filter->y());
|
||||
_scroll.move(0, _filter->height() + 2 * st::dialogsFilterPadding.y());
|
||||
|
||||
updateMainMenuGeometry();
|
||||
|
||||
int32 addToY = App::main() ? App::main()->contentScrollAddToY() : 0;
|
||||
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) {
|
||||
_scroll.scrollToY(newScrollY);
|
||||
} 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) {
|
||||
if (e->key() == Qt::Key_Escape) {
|
||||
e->ignore();
|
||||
|
@ -2548,16 +2553,8 @@ Dialogs::IndexedList *DialogsWidget::dialogsList() {
|
|||
return _inner.dialogsList();
|
||||
}
|
||||
|
||||
void DialogsWidget::onAddContact() {
|
||||
Ui::showLayer(new AddContactBox(), KeepOtherLayers);
|
||||
}
|
||||
|
||||
void DialogsWidget::onNewGroup() {
|
||||
Ui::showLayer(new NewGroupBox());
|
||||
}
|
||||
|
||||
bool DialogsWidget::onCancelSearch() {
|
||||
bool clearing = !_filter.getLastText().isEmpty();
|
||||
bool clearing = !_filter->getLastText().isEmpty();
|
||||
if (_searchRequest) {
|
||||
MTP::cancel(_searchRequest);
|
||||
_searchRequest = 0;
|
||||
|
@ -2571,8 +2568,8 @@ bool DialogsWidget::onCancelSearch() {
|
|||
clearing = true;
|
||||
}
|
||||
_inner.clearFilter();
|
||||
_filter.clear();
|
||||
_filter.updatePlaceholder();
|
||||
_filter->clear();
|
||||
_filter->updatePlaceholder();
|
||||
onFilterUpdate();
|
||||
return clearing;
|
||||
}
|
||||
|
@ -2590,8 +2587,8 @@ void DialogsWidget::onCancelSearchInPeer() {
|
|||
_inner.searchInPeer(0);
|
||||
}
|
||||
_inner.clearFilter();
|
||||
_filter.clear();
|
||||
_filter.updatePlaceholder();
|
||||
_filter->clear();
|
||||
_filter->updatePlaceholder();
|
||||
onFilterUpdate();
|
||||
if (!Adaptive::OneColumn() && !App::main()->selectingPeer()) {
|
||||
emit cancelled();
|
||||
|
|
|
@ -31,10 +31,9 @@ class IndexedList;
|
|||
namespace Ui {
|
||||
class IconButton;
|
||||
class PopupMenu;
|
||||
class DropdownMenu;
|
||||
} // namespace Ui
|
||||
|
||||
class MainWidget;
|
||||
|
||||
enum DialogsSearchRequestType {
|
||||
DialogsSearchFromStart,
|
||||
DialogsSearchFromOffset,
|
||||
|
@ -48,7 +47,7 @@ class DialogsInner : public SplittedWidget, public RPCSender, private base::Subs
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DialogsInner(QWidget *parent, MainWidget *main);
|
||||
DialogsInner(QWidget *parent, QWidget *main);
|
||||
|
||||
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
||||
void addSavedPeersAfter(const QDateTime &date);
|
||||
|
@ -238,7 +237,7 @@ class DialogsWidget : public TWidget, public RPCSender {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DialogsWidget(MainWidget *parent);
|
||||
DialogsWidget(QWidget *parent);
|
||||
|
||||
void dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpRequestId req);
|
||||
void contactsReceived(const MTPcontacts_Contacts &contacts);
|
||||
|
@ -295,17 +294,13 @@ public:
|
|||
void notify_historyMuteUpdated(History *history);
|
||||
|
||||
signals:
|
||||
|
||||
void cancelled();
|
||||
|
||||
public slots:
|
||||
|
||||
void onCancel();
|
||||
void onListScroll();
|
||||
void activate();
|
||||
void onFilterUpdate(bool force = false);
|
||||
void onAddContact();
|
||||
void onNewGroup();
|
||||
bool onCancelSearch();
|
||||
void onCancelSearchInPeer();
|
||||
|
||||
|
@ -319,8 +314,11 @@ public slots:
|
|||
void onChooseByDrag();
|
||||
|
||||
private:
|
||||
void showMainMenu();
|
||||
void updateMainMenuGeometry();
|
||||
|
||||
bool _dragInScroll, _dragForward;
|
||||
bool _dragInScroll = false;
|
||||
bool _dragForward = false;
|
||||
QTimer _chooseByDragTimer;
|
||||
|
||||
void unreadCountsReceived(const QVector<MTPDialog> &dialogs);
|
||||
|
@ -329,15 +327,16 @@ private:
|
|||
bool searchFailed(DialogsSearchRequestType type, const RPCError &error, mtpRequestId req);
|
||||
bool peopleFailed(const RPCError &error, mtpRequestId req);
|
||||
|
||||
bool _dialogsFull;
|
||||
int32 _dialogsOffsetDate;
|
||||
MsgId _dialogsOffsetId;
|
||||
PeerData *_dialogsOffsetPeer;
|
||||
mtpRequestId _dialogsRequest, _contactsRequest;
|
||||
bool _dialogsFull = false;
|
||||
int32 _dialogsOffsetDate = 0;
|
||||
MsgId _dialogsOffsetId = 0;
|
||||
PeerData *_dialogsOffsetPeer = nullptr;
|
||||
mtpRequestId _dialogsRequest = 0;
|
||||
mtpRequestId _contactsRequest = 0;
|
||||
|
||||
FlatInput _filter;
|
||||
ChildWidget<Ui::IconButton> _newGroup;
|
||||
ChildWidget<Ui::IconButton> _addContact;
|
||||
ChildWidget<Ui::IconButton> _mainMenuToggle;
|
||||
ChildWidget<Ui::DropdownMenu> _mainMenu = { nullptr };
|
||||
ChildWidget<FlatInput> _filter;
|
||||
ChildWidget<Ui::IconButton> _cancelSearch;
|
||||
ScrollArea _scroll;
|
||||
DialogsInner _inner;
|
||||
|
@ -347,11 +346,14 @@ private:
|
|||
anim::ivalue a_coordUnder, a_coordOver;
|
||||
anim::fvalue a_progress;
|
||||
|
||||
PeerData *_searchInPeer, *_searchInMigrated;
|
||||
PeerData *_searchInPeer = nullptr;
|
||||
PeerData *_searchInMigrated = nullptr;
|
||||
|
||||
QTimer _searchTimer;
|
||||
QString _searchQuery, _peopleQuery;
|
||||
bool _searchFull, _searchFullMigrated, _peopleFull;
|
||||
bool _searchFull = false;
|
||||
bool _searchFullMigrated = false;
|
||||
bool _peopleFull = false;
|
||||
mtpRequestId _searchRequest, _peopleRequest;
|
||||
|
||||
typedef QMap<QString, MTPmessages_Messages> SearchCache;
|
||||
|
|
|
@ -151,11 +151,11 @@ introBackButton: IconButton {
|
|||
|
||||
icon: icon {
|
||||
{ size(40px, 40px), #f2f2f2 },
|
||||
{ "title_previous", #adadad, point(12px, 12px) },
|
||||
{ "title_back", #adadad, point(12px, 12px) },
|
||||
};
|
||||
iconOver: icon {
|
||||
{ size(40px, 40px), #eeeeee },
|
||||
{ "title_previous", #969696, point(12px, 12px) },
|
||||
{ "title_back", #969696, point(12px, 12px) },
|
||||
};
|
||||
|
||||
iconPosition: point(0px, 0px);
|
||||
|
|
|
@ -83,6 +83,7 @@ MainWidget::MainWidget(QWidget *parent) : TWidget(parent)
|
|||
updateScrollColors();
|
||||
|
||||
connect(_dialogs, SIGNAL(cancelled()), this, SLOT(dialogsCancelled()));
|
||||
connect(this, SIGNAL(dialogsUpdated()), this, SLOT(onListScroll()));
|
||||
connect(_history, SIGNAL(cancelled()), _dialogs, SLOT(activate()));
|
||||
connect(this, SIGNAL(peerPhotoChanged(PeerData*)), this, SIGNAL(dialogsUpdated()));
|
||||
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) {
|
||||
OverviewsPreload::iterator it;
|
||||
MediaOverviewType type = OverviewCount;
|
||||
|
|
|
@ -312,8 +312,6 @@ public:
|
|||
void loadMediaBack(PeerData *peer, MediaOverviewType type, bool many = false);
|
||||
|
||||
void checkLastUpdate(bool afterSleep);
|
||||
void showAddContact();
|
||||
void showNewGroup();
|
||||
|
||||
void serviceNotification(const QString &msg, const MTPMessageMedia &media);
|
||||
void serviceHistoryDone(const MTPmessages_Messages &msgs);
|
||||
|
|
|
@ -44,7 +44,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "apiwrap.h"
|
||||
#include "settings/settings_widget.h"
|
||||
#include "platform/platform_notifications_manager.h"
|
||||
#include "platform/platform_window_title.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "window/window_theme.h"
|
||||
#include "window/window_theme_warning.h"
|
||||
|
@ -86,7 +85,7 @@ void ConnectingWidget::onReconnect() {
|
|||
MTP::restart();
|
||||
}
|
||||
|
||||
MainWindow::MainWindow() : Platform::MainWindow(), _body(this) {
|
||||
MainWindow::MainWindow() {
|
||||
icon16 = icon256.scaledToWidth(16, Qt::SmoothTransformation);
|
||||
icon32 = icon256.scaledToWidth(32, Qt::SmoothTransformation);
|
||||
icon64 = icon256.scaledToWidth(64, Qt::SmoothTransformation);
|
||||
|
@ -105,15 +104,9 @@ MainWindow::MainWindow() : Platform::MainWindow(), _body(this) {
|
|||
}
|
||||
});
|
||||
|
||||
if (objectName().isEmpty()) {
|
||||
setObjectName(qsl("MainWindow"));
|
||||
}
|
||||
resize(st::windowDefWidth, st::windowDefHeight);
|
||||
resize(st::windowDefaultWidth, st::windowDefaultHeight);
|
||||
|
||||
setLocale(QLocale(QLocale::English, QLocale::UnitedStates));
|
||||
setCentralWidget(_body);
|
||||
|
||||
QMetaObject::connectSlotsByName(this);
|
||||
|
||||
_inactiveTimer.setSingleShot(true);
|
||||
connect(&_inactiveTimer, SIGNAL(timeout()), this, SLOT(onInactiveTimer()));
|
||||
|
@ -162,26 +155,17 @@ void MainWindow::onStateChanged(Qt::WindowState state) {
|
|||
if (state == Qt::WindowMinimized && cWorkMode() == dbiwmTrayOnly) {
|
||||
App::wnd()->minimizeToTray();
|
||||
}
|
||||
psSavePosition(state);
|
||||
savePosition(state);
|
||||
}
|
||||
|
||||
void MainWindow::init() {
|
||||
psInitFrameless();
|
||||
setWindowIcon(wndIcon);
|
||||
Platform::MainWindow::init();
|
||||
|
||||
_title = Platform::CreateTitleWidget(this);
|
||||
setWindowIcon(wndIcon);
|
||||
|
||||
Application::instance()->installEventFilter(this);
|
||||
connect(windowHandle(), SIGNAL(windowStateChanged(Qt::WindowState)), this, SLOT(onStateChanged(Qt::WindowState)));
|
||||
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() {
|
||||
|
@ -241,9 +225,7 @@ void MainWindow::clearWidgets() {
|
|||
|
||||
QPixmap MainWindow::grabInner() {
|
||||
QPixmap result;
|
||||
if (_settings) {
|
||||
result = myGrab(_settings);
|
||||
} else if (_intro) {
|
||||
if (_intro) {
|
||||
result = myGrab(_intro);
|
||||
} else if (_main) {
|
||||
result = myGrab(_main);
|
||||
|
@ -274,13 +256,13 @@ void MainWindow::clearPasscode() {
|
|||
}
|
||||
|
||||
void MainWindow::setupPasscode(bool anim) {
|
||||
QPixmap bg = grabInner();
|
||||
auto bg = grabInner();
|
||||
|
||||
if (_passcode) {
|
||||
_passcode->stop_show();
|
||||
_passcode.destroyDelayed();
|
||||
}
|
||||
_passcode.create(_body);
|
||||
_passcode.create(bodyWidget());
|
||||
updateControlsGeometry();
|
||||
|
||||
if (_main) _main->hide();
|
||||
|
@ -332,7 +314,7 @@ void MainWindow::setupIntro(bool anim) {
|
|||
QPixmap bg = anim ? grabInner() : QPixmap();
|
||||
|
||||
clearWidgets();
|
||||
_intro.create(_body);
|
||||
_intro.create(bodyWidget());
|
||||
updateControlsGeometry();
|
||||
|
||||
if (anim) {
|
||||
|
@ -382,7 +364,7 @@ void MainWindow::sendServiceHistoryRequest() {
|
|||
void MainWindow::setupMain(bool anim, const MTPUser *self) {
|
||||
QPixmap bg = anim ? grabInner() : QPixmap();
|
||||
clearWidgets();
|
||||
_main.create(_body);
|
||||
_main.create(bodyWidget());
|
||||
updateControlsGeometry();
|
||||
|
||||
if (anim) {
|
||||
|
@ -418,7 +400,7 @@ void MainWindow::showSettings() {
|
|||
}
|
||||
|
||||
if (!_layerBg) {
|
||||
_layerBg.create(_body);
|
||||
_layerBg.create(bodyWidget());
|
||||
}
|
||||
_settings.create(this);
|
||||
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) {
|
||||
if (box) {
|
||||
if (!_layerBg) {
|
||||
_layerBg.create(_body);
|
||||
_layerBg.create(bodyWidget());
|
||||
}
|
||||
if (options.testFlag(KeepOtherLayers)) {
|
||||
if (options.testFlag(ShowAfterOtherLayers)) {
|
||||
|
@ -532,7 +514,7 @@ bool MainWindow::ui_isMediaViewShown() {
|
|||
void MainWindow::ui_showMediaPreview(DocumentData *document) {
|
||||
if (!document || ((!document->isAnimation() || !document->loaded()) && !document->sticker())) return;
|
||||
if (!_mediaPreview) {
|
||||
_mediaPreview.create(_body);
|
||||
_mediaPreview.create(bodyWidget());
|
||||
updateControlsGeometry();
|
||||
}
|
||||
if (_mediaPreview->isHidden()) {
|
||||
|
@ -544,7 +526,7 @@ void MainWindow::ui_showMediaPreview(DocumentData *document) {
|
|||
void MainWindow::ui_showMediaPreview(PhotoData *photo) {
|
||||
if (!photo) return;
|
||||
if (!_mediaPreview) {
|
||||
_mediaPreview.create(_body);
|
||||
_mediaPreview.create(bodyWidget());
|
||||
updateControlsGeometry();
|
||||
}
|
||||
if (_mediaPreview->isHidden()) {
|
||||
|
@ -571,7 +553,7 @@ void MainWindow::showConnecting(const QString &text, const QString &reconnect) {
|
|||
if (_connecting) {
|
||||
_connecting->set(text, reconnect);
|
||||
} else {
|
||||
_connecting.create(_body, text, reconnect);
|
||||
_connecting.create(bodyWidget(), text, reconnect);
|
||||
updateControlsGeometry();
|
||||
fixOrder();
|
||||
}
|
||||
|
@ -586,15 +568,13 @@ void MainWindow::hideConnecting() {
|
|||
void MainWindow::themeUpdated(const Window::Theme::BackgroundUpdate &data) {
|
||||
using Type = Window::Theme::BackgroundUpdate::Type;
|
||||
if (data.type == Type::TestingTheme) {
|
||||
if (_title) _title->update();
|
||||
if (!_testingThemeWarning) {
|
||||
_testingThemeWarning.create(_body);
|
||||
_testingThemeWarning.create(bodyWidget());
|
||||
_testingThemeWarning->setGeometry(rect());
|
||||
_testingThemeWarning->setHiddenCallback([this] { _testingThemeWarning.destroyDelayed(); });
|
||||
}
|
||||
_testingThemeWarning->showAnimated();
|
||||
} else if (data.type == Type::RevertingTheme || data.type == Type::ApplyingTheme) {
|
||||
if (_title) _title->update();
|
||||
_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) {
|
||||
switch (e->type()) {
|
||||
case QEvent::MouseButtonPress:
|
||||
|
@ -757,7 +699,7 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *e) {
|
|||
case QEvent::Move:
|
||||
case QEvent::Resize:
|
||||
if (obj == this) {
|
||||
psUpdatedPosition();
|
||||
positionUpdated();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -821,13 +763,17 @@ void MainWindow::updateTrayMenu(bool force) {
|
|||
void MainWindow::onShowAddContact() {
|
||||
if (isHidden()) showFromTray();
|
||||
|
||||
if (_main) _main->showAddContact();
|
||||
if (App::self()) {
|
||||
Ui::showLayer(new AddContactBox(), KeepOtherLayers);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onShowNewGroup() {
|
||||
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() {
|
||||
|
@ -906,7 +852,6 @@ void MainWindow::layerFinishedHide(LayerStackWidget *was) {
|
|||
}
|
||||
|
||||
void MainWindow::fixOrder() {
|
||||
if (_title) _title->raise();
|
||||
if (_layerBg) _layerBg->raise();
|
||||
if (_mediaPreview) _mediaPreview->raise();
|
||||
if (_connecting) _connecting->raise();
|
||||
|
@ -980,7 +925,7 @@ void MainWindow::closeEvent(QCloseEvent *e) {
|
|||
}
|
||||
|
||||
void MainWindow::resizeEvent(QResizeEvent *e) {
|
||||
if (!_title) return;
|
||||
Platform::MainWindow::resizeEvent(e);
|
||||
|
||||
Adaptive::Layout layout = Adaptive::OneColumnLayout;
|
||||
if (width() > st::adaptiveWideWidth) {
|
||||
|
@ -993,17 +938,11 @@ void MainWindow::resizeEvent(QResizeEvent *e) {
|
|||
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();
|
||||
}
|
||||
|
||||
void MainWindow::updateControlsGeometry() {
|
||||
auto body = _body->rect();
|
||||
auto body = bodyWidget()->rect();
|
||||
if (_passcode) _passcode->setGeometry(body);
|
||||
if (_main) _main->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 "ui/effects/rect_shadow.h"
|
||||
#include "platform/platform_main_window.h"
|
||||
#include "window/window_title.h"
|
||||
#include "core/single_timer.h"
|
||||
|
||||
class MediaView;
|
||||
|
@ -71,7 +70,7 @@ private:
|
|||
|
||||
class MediaPreviewWidget;
|
||||
|
||||
class MainWindow : public Platform::MainWindow, private base::Subscriber {
|
||||
class MainWindow : public Platform::MainWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -97,9 +96,6 @@ public:
|
|||
|
||||
void mtpStateChanged(int32 dc, int32 state);
|
||||
|
||||
Window::HitTestResult hitTest(const QPoint &p) const;
|
||||
QRect iconRect() const;
|
||||
|
||||
IntroWidget *introWidget();
|
||||
MainWidget *mainWidget();
|
||||
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);
|
||||
QImage icon16, icon32, icon64, iconbig16, iconbig32, iconbig64;
|
||||
|
||||
QWidget *centralwidget;
|
||||
|
||||
typedef QPair<QString, MTPMessageMedia> DelayedServiceMsg;
|
||||
QVector<DelayedServiceMsg> _delayedServiceMsgs;
|
||||
mtpRequestId _serviceHistoryRequest = 0;
|
||||
|
||||
Window::TitleWidget *_title = nullptr;
|
||||
ChildWidget<TWidget> _body;
|
||||
ChildWidget<PasscodeWidget> _passcode = { nullptr };
|
||||
ChildWidget<IntroWidget> _intro = { nullptr };
|
||||
ChildWidget<MainWidget> _main = { nullptr };
|
||||
|
|
|
@ -125,11 +125,11 @@ mediaPlayerNextDisabledIcon: icon {
|
|||
};
|
||||
mediaPlayerPreviousButton: IconButton(mediaPlayerNextButton) {
|
||||
icon: icon {
|
||||
{ "player_previous", mediaPlayerActiveFg, mediaPlayerSkipIconPosition },
|
||||
{ "player_next-flip_horizontal", mediaPlayerActiveFg, mediaPlayerSkipIconPosition },
|
||||
};
|
||||
}
|
||||
mediaPlayerPreviousDisabledIcon: icon {
|
||||
{ "player_previous", mediaPlayerInactiveFg, mediaPlayerSkipIconPosition },
|
||||
{ "player_next-flip_horizontal", mediaPlayerInactiveFg, mediaPlayerSkipIconPosition },
|
||||
};
|
||||
mediaPlayerClose: IconButton(mediaPlayerRepeatButton) {
|
||||
width: 37px;
|
||||
|
@ -178,10 +178,10 @@ mediaPlayerPanelNextDisabledIcon: icon {
|
|||
{ "player_panel_next", mediaPlayerInactiveFg, point(10px, 10px) },
|
||||
};
|
||||
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 {
|
||||
{ "player_panel_previous", mediaPlayerInactiveFg, point(10px, 10px) },
|
||||
{ "player_panel_next-flip_horizontal", mediaPlayerInactiveFg, point(10px, 10px) },
|
||||
};
|
||||
|
||||
mediaPlayerPanelPadding: 16px;
|
||||
|
|
|
@ -81,7 +81,7 @@ mediaviewVolumeOnIconOver: icon {{ "media_volume", mediaviewPlaybackActiveOver,
|
|||
mediaviewVolumeIconTop: 8px;
|
||||
mediaviewControllerRadius: 25px;
|
||||
|
||||
mediaviewLeft: icon {{ "mediaview_previous", #ffffff }};
|
||||
mediaviewLeft: icon {{ "mediaview_next-flip_horizontal", #ffffff }};
|
||||
mediaviewRight: icon {{ "mediaview_next", #ffffff }};
|
||||
mediaviewClose: icon {{ "mediaview_close", #ffffff }};
|
||||
mediaviewSave: icon {{ "mediaview_download", #ffffff }};
|
||||
|
|
|
@ -54,7 +54,7 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, PeerD
|
|||
, _history(App::history(_peer->id))
|
||||
, _channel(peerToChannel(_peer->id))
|
||||
, _rowWidth(st::msgMinWidth)
|
||||
, _search(this, st::dlgFilter, lang(lng_dlg_filter))
|
||||
, _search(this, st::dialogsFilter, lang(lng_dlg_filter))
|
||||
, _cancelSearch(this, st::dialogsCancelSearch)
|
||||
, _itemsToBeLoaded(LinksOverviewPerPage * 2)
|
||||
, _width(st::windowMinWidth) {
|
||||
|
|
|
@ -431,89 +431,6 @@ void MainWindow::LibsLoaded() {
|
|||
#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() {
|
||||
if (!noQtTrayIcon) {
|
||||
cSetSupportTray(QSystemTrayIcon::isSystemTrayAvailable());
|
||||
|
@ -641,7 +558,7 @@ void MainWindow::psFirstShow() {
|
|||
show();
|
||||
}
|
||||
|
||||
posInited = true;
|
||||
setPositionInited();
|
||||
}
|
||||
|
||||
void MainWindow::psInitSysMenu() {
|
||||
|
|
|
@ -30,18 +30,10 @@ class MainWindow : public Window::MainWindow {
|
|||
public:
|
||||
MainWindow();
|
||||
|
||||
int32 psResizeRowWidth() const {
|
||||
return 0;//st::wndResizeAreaWidth;
|
||||
}
|
||||
|
||||
void psInitFrameless();
|
||||
void psInitSize();
|
||||
|
||||
void psFirstShow();
|
||||
void psInitSysMenu();
|
||||
void psUpdateSysMenu(Qt::WindowState state);
|
||||
void psUpdateMargins();
|
||||
void psUpdatedPosition();
|
||||
|
||||
void psFlash();
|
||||
void psNotifySettingGot();
|
||||
|
@ -51,10 +43,6 @@ public:
|
|||
void psRefreshTaskbarIcon() {
|
||||
}
|
||||
|
||||
bool psPosInited() const {
|
||||
return posInited;
|
||||
}
|
||||
|
||||
void psUpdateCounter();
|
||||
|
||||
bool psHasNativeNotifications();
|
||||
|
@ -66,7 +54,6 @@ public:
|
|||
~MainWindow();
|
||||
|
||||
public slots:
|
||||
void psSavePosition(Qt::WindowState state = Qt::WindowActive);
|
||||
void psShowTrayMenu();
|
||||
|
||||
void psStatusIconCheck();
|
||||
|
@ -76,7 +63,6 @@ protected:
|
|||
|
||||
bool psHasTrayIcon() const;
|
||||
|
||||
bool posInited = false;
|
||||
QSystemTrayIcon *trayIcon = nullptr;
|
||||
QMenu *trayIconMenu = nullptr;
|
||||
QImage icon256, iconbig256;
|
||||
|
|
|
@ -38,18 +38,10 @@ class MainWindow : public Window::MainWindow {
|
|||
public:
|
||||
MainWindow();
|
||||
|
||||
int32 psResizeRowWidth() const {
|
||||
return 0;//st::wndResizeAreaWidth;
|
||||
}
|
||||
|
||||
void psInitFrameless();
|
||||
void psInitSize();
|
||||
|
||||
void psFirstShow();
|
||||
void psInitSysMenu();
|
||||
void psUpdateSysMenu(Qt::WindowState state);
|
||||
void psUpdateMargins();
|
||||
void psUpdatedPosition();
|
||||
|
||||
void psFlash();
|
||||
|
||||
|
@ -58,10 +50,6 @@ public:
|
|||
void psRefreshTaskbarIcon() {
|
||||
}
|
||||
|
||||
bool psPosInited() const {
|
||||
return posInited;
|
||||
}
|
||||
|
||||
bool psFilterNativeEvent(void *event);
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *evt) override;
|
||||
|
@ -79,7 +67,6 @@ public:
|
|||
~MainWindow();
|
||||
|
||||
public slots:
|
||||
void psSavePosition(Qt::WindowState state = Qt::WindowActive);
|
||||
void psShowTrayMenu();
|
||||
|
||||
void psMacUndo();
|
||||
|
@ -103,7 +90,6 @@ protected:
|
|||
|
||||
void psMacUpdateMenu();
|
||||
|
||||
bool posInited;
|
||||
QSystemTrayIcon *trayIcon = nullptr;
|
||||
QMenu *trayIconMenu = nullptr;
|
||||
QImage icon256, iconbig256;
|
||||
|
@ -118,6 +104,8 @@ protected:
|
|||
QTimer psUpdatedPositionTimer;
|
||||
|
||||
private:
|
||||
void createGlobalMenu();
|
||||
|
||||
MacPrivate _private;
|
||||
|
||||
mutable bool psIdle;
|
||||
|
|
|
@ -52,8 +52,7 @@ void MacPrivate::darkModeChanged() {
|
|||
}
|
||||
|
||||
MainWindow::MainWindow()
|
||||
: posInited(false)
|
||||
, icon256(qsl(":/gui/art/icon256.png"))
|
||||
: icon256(qsl(":/gui/art/icon256.png"))
|
||||
, iconbig256(qsl(":/gui/art/iconbig256.png"))
|
||||
, wndIcon(QPixmap::fromImage(iconbig256, Qt::ColorOnly)) {
|
||||
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() {
|
||||
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::psFirstShow() {
|
||||
psUpdateMargins();
|
||||
|
||||
|
@ -296,9 +217,14 @@ void MainWindow::psFirstShow() {
|
|||
show();
|
||||
}
|
||||
|
||||
posInited = true;
|
||||
setPositionInited();
|
||||
|
||||
// init global menu
|
||||
createGlobalMenu();
|
||||
|
||||
psMacUpdateMenu();
|
||||
}
|
||||
|
||||
void MainWindow::createGlobalMenu() {
|
||||
auto main = psMainMenu.addMenu(qsl("Telegram"));
|
||||
auto about = main->addAction(lng_mac_menu_about_telegram(lt_telegram, qsl("Telegram")));
|
||||
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()));
|
||||
window->addSeparator();
|
||||
psShowTelegram = window->addAction(lang(lng_mac_menu_show), App::wnd(), SLOT(showFromTray()));
|
||||
|
||||
psMacUpdateMenu();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -398,23 +322,23 @@ void MainWindow::psUpdateMargins() {
|
|||
}
|
||||
|
||||
void MainWindow::psMacUpdateMenu() {
|
||||
if (!posInited) return;
|
||||
if (!positionInited()) return;
|
||||
|
||||
QWidget *focused = QApplication::focusWidget();
|
||||
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();
|
||||
canSelectAll = !edit->text().isEmpty();
|
||||
canUndo = edit->isUndoAvailable();
|
||||
canRedo = edit->isRedoAvailable();
|
||||
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();
|
||||
canSelectAll = !edit->isEmpty();
|
||||
canUndo = edit->isUndoAvailable();
|
||||
canRedo = edit->isRedoAvailable();
|
||||
canPaste = !Application::clipboard()->text().isEmpty();
|
||||
} else if (HistoryInner *list = qobject_cast<HistoryInner*>(focused)) {
|
||||
} else if (auto list = qobject_cast<HistoryInner*>(focused)) {
|
||||
canCopy = list->canCopySelected();
|
||||
canDelete = list->canDeleteSelected();
|
||||
}
|
||||
|
|
|
@ -194,7 +194,7 @@ public:
|
|||
max_w = avail.width();
|
||||
accumulate_max(max_w, st::windowMinWidth);
|
||||
max_h = avail.height();
|
||||
accumulate_max(max_h, st::windowMinHeight);
|
||||
accumulate_max(max_h, st::titleHeight + st::windowMinHeight);
|
||||
|
||||
HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0);
|
||||
HWND hwnd = App::wnd() ? App::wnd()->psHwnd() : 0;
|
||||
|
@ -350,7 +350,7 @@ public:
|
|||
}
|
||||
return;
|
||||
}
|
||||
if (!App::wnd()->psPosInited()) return;
|
||||
if (!App::wnd()->positionInited()) return;
|
||||
|
||||
int x = _x, y = _y, w = _w, h = _h;
|
||||
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());
|
||||
}
|
||||
|
||||
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() {
|
||||
QWidget *w = new QWidget(this);
|
||||
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);
|
||||
}
|
||||
|
||||
namespace {
|
||||
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()));
|
||||
|
||||
void MainWindow::initHook() {
|
||||
auto platformInterface = QGuiApplication::platformNativeInterface();
|
||||
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);
|
||||
}
|
||||
|
||||
// RegisterApplicationRestart(NULL, 0);
|
||||
|
||||
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() {
|
||||
return Notifications::supported();
|
||||
}
|
||||
|
@ -894,7 +810,7 @@ void MainWindow::psFirstShow() {
|
|||
show();
|
||||
}
|
||||
|
||||
posInited = true;
|
||||
setPositionInited();
|
||||
if (showShadows) {
|
||||
shadowsUpdate(ShadowsChange::Moved | ShadowsChange::Resized | ShadowsChange::Shown);
|
||||
}
|
||||
|
|
|
@ -35,12 +35,6 @@ class MainWindow : public Window::MainWindow {
|
|||
public:
|
||||
MainWindow();
|
||||
|
||||
int32 psResizeRowWidth() const {
|
||||
return 0;//st::wndResizeAreaWidth;
|
||||
}
|
||||
|
||||
void psInitFrameless();
|
||||
void psInitSize();
|
||||
HWND psHwnd() const;
|
||||
HMENU psMenu() const;
|
||||
|
||||
|
@ -48,7 +42,6 @@ public:
|
|||
void psInitSysMenu();
|
||||
void psUpdateSysMenu(Qt::WindowState state);
|
||||
void psUpdateMargins();
|
||||
void psUpdatedPosition();
|
||||
|
||||
void psFlash();
|
||||
void psNotifySettingGot();
|
||||
|
@ -57,10 +50,6 @@ public:
|
|||
|
||||
void psRefreshTaskbarIcon();
|
||||
|
||||
bool psPosInited() const {
|
||||
return posInited;
|
||||
}
|
||||
|
||||
void psUpdateCounter();
|
||||
|
||||
bool psHasNativeNotifications();
|
||||
|
@ -99,15 +88,16 @@ public:
|
|||
~MainWindow();
|
||||
|
||||
public slots:
|
||||
void psSavePosition(Qt::WindowState state = Qt::WindowActive);
|
||||
void psShowTrayMenu();
|
||||
|
||||
protected:
|
||||
void initHook() override;
|
||||
int32 screenNameChecksum(const QString &name) const override;
|
||||
|
||||
bool psHasTrayIcon() const {
|
||||
return trayIcon;
|
||||
}
|
||||
|
||||
bool posInited = false;
|
||||
QSystemTrayIcon *trayIcon = nullptr;
|
||||
Ui::PopupMenu *trayIconMenu = nullptr;
|
||||
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 "ui/buttons/icon_button.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
namespace Platform {
|
||||
|
@ -30,7 +31,8 @@ TitleWidget::TitleWidget(QWidget *parent) : Window::TitleWidget(parent)
|
|||
, _minimize(this, st::titleButtonMinimize)
|
||||
, _maximizeRestore(this, st::titleButtonMaximize)
|
||||
, _close(this, st::titleButtonClose)
|
||||
, _maximized(parent->window()->windowState() & Qt::WindowMaximized) {
|
||||
, _maximized(parent->window()->windowState() & Qt::WindowMaximized)
|
||||
, _shadow(this, st::titleShadow) {
|
||||
_minimize->setClickedCallback([this]() {
|
||||
window()->setWindowState(Qt::WindowMinimized);
|
||||
_minimize->clearState();
|
||||
|
@ -65,6 +67,7 @@ void TitleWidget::updateControlsPosition() {
|
|||
|
||||
void TitleWidget::resizeEvent(QResizeEvent *e) {
|
||||
updateControlsPosition();
|
||||
_shadow->setGeometry(0, height() - st::lineWidth, width(), st::lineWidth);
|
||||
}
|
||||
|
||||
void TitleWidget::updateControlsVisibility() {
|
||||
|
|
|
@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
|
||||
namespace Ui {
|
||||
class IconButton;
|
||||
class PlainShadow;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Platform {
|
||||
|
@ -51,6 +52,7 @@ private:
|
|||
ChildWidget<Ui::IconButton> _minimize;
|
||||
ChildWidget<Ui::IconButton> _maximizeRestore;
|
||||
ChildWidget<Ui::IconButton> _close;
|
||||
ChildWidget<Ui::PlainShadow> _shadow;
|
||||
|
||||
bool _maximized = false;
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
|
|||
}
|
||||
emit App::wnd()->windowHandle()->windowStateChanged(state);
|
||||
} else {
|
||||
App::wnd()->psUpdatedPosition();
|
||||
App::wnd()->positionUpdated();
|
||||
}
|
||||
App::wnd()->psUpdateMargins();
|
||||
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: {
|
||||
App::wnd()->shadowsUpdate(ShadowsChange::Moved);
|
||||
App::wnd()->psUpdatedPosition();
|
||||
App::wnd()->positionUpdated();
|
||||
} return false;
|
||||
|
||||
case WM_NCHITTEST: {
|
||||
|
@ -185,7 +185,6 @@ bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
|
|||
switch (res) {
|
||||
case Window::HitTestResult::Client:
|
||||
case Window::HitTestResult::SysButton: *result = HTCLIENT; break;
|
||||
case Window::HitTestResult::Icon: *result = HTCAPTION; break;
|
||||
case Window::HitTestResult::Caption: *result = HTCAPTION; break;
|
||||
case Window::HitTestResult::Top: *result = HTTOP; 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);
|
||||
} 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: {
|
||||
if (wParam == SC_MOUSEMENU) {
|
||||
POINTS p = MAKEPOINTS(lParam);
|
||||
|
|
|
@ -924,7 +924,7 @@ void psUpdateOverlayed(TWidget *widget) {
|
|||
if (!wv) widget->setAttribute(Qt::WA_WState_Visible, true);
|
||||
widget->update();
|
||||
QEvent e(QEvent::UpdateRequest);
|
||||
widget->event(&e);
|
||||
QGuiApplication::sendEvent(widget, &e);
|
||||
if (!wm) widget->setAttribute(Qt::WA_Mapped, false);
|
||||
if (!wv) widget->setAttribute(Qt::WA_WState_Visible, false);
|
||||
}
|
||||
|
|
|
@ -74,10 +74,11 @@ settingsButtonTop: 75px;
|
|||
settingsButtonSkip: 10px;
|
||||
settingsPrimaryButton: defaultActiveButton;
|
||||
settingsSecondaryButton: defaultLightButton;
|
||||
settingsEditButton: IconButton(dialogsNewChatButton) {
|
||||
settingsEditButton: IconButton {
|
||||
width: 24px;
|
||||
height: 34px;
|
||||
|
||||
icon: icon {{ "settings_edit_name", #b7b7b7 }};
|
||||
iconPosition: point(3px, 9px);
|
||||
iconPositionDown: point(3px, 10px);
|
||||
}
|
||||
|
|
|
@ -136,8 +136,8 @@ emojiColorsSepColor: #d5d5d5;
|
|||
emojiSwitchSkip: 27px;
|
||||
emojiSwitchImgSkip: 21px;
|
||||
emojiSwitchColor: #42a8db;
|
||||
emojiSwitchStickers: icon {{ "emoji_switch_right", emojiSwitchColor }};
|
||||
emojiSwitchEmoji: icon {{ "emoji_switch_left", emojiSwitchColor }};
|
||||
emojiSwitchStickers: icon {{ "emoji_switch", emojiSwitchColor }};
|
||||
emojiSwitchEmoji: icon {{ "emoji_switch-flip_horizontal", emojiSwitchColor }};
|
||||
|
||||
stickerPanSize: size(64px, 64px);
|
||||
stickerPanPadding: 11px;
|
||||
|
|
|
@ -138,9 +138,6 @@ class TWidget : public QWidget {
|
|||
public:
|
||||
TWidget(QWidget *parent = nullptr) : QWidget(parent) {
|
||||
}
|
||||
bool event(QEvent *e) override {
|
||||
return QWidget::event(e);
|
||||
}
|
||||
virtual void grabStart() {
|
||||
}
|
||||
virtual void grabFinish() {
|
||||
|
@ -238,39 +235,39 @@ private:
|
|||
|
||||
// A simple wrap around T* to explicitly state ownership
|
||||
template <typename T>
|
||||
class ChildWidget {
|
||||
class ChildObject {
|
||||
public:
|
||||
ChildWidget(std_::nullptr_t) : _widget(nullptr) {
|
||||
ChildObject(std_::nullptr_t) : _object(nullptr) {
|
||||
}
|
||||
|
||||
// No default constructor, but constructors with at least
|
||||
// one argument are simply make functions.
|
||||
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;
|
||||
ChildWidget<T> &operator=(const ChildWidget<T> &other) = delete;
|
||||
ChildObject(const ChildObject<T> &other) = delete;
|
||||
ChildObject<T> &operator=(const ChildObject<T> &other) = delete;
|
||||
|
||||
ChildWidget<T> &operator=(std_::nullptr_t) {
|
||||
_widget = nullptr;
|
||||
ChildObject<T> &operator=(std_::nullptr_t) {
|
||||
_object = nullptr;
|
||||
return *this;
|
||||
}
|
||||
ChildWidget<T> &operator=(T *widget) {
|
||||
_widget = widget;
|
||||
ChildObject<T> &operator=(T *object) {
|
||||
_object = object;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T *operator->() const {
|
||||
return _widget;
|
||||
return _object;
|
||||
}
|
||||
T &operator*() const {
|
||||
return *_widget;
|
||||
return *_object;
|
||||
}
|
||||
|
||||
// So we can pass this pointer to methods like connect().
|
||||
T *ptr() const {
|
||||
return _widget;
|
||||
return _object;
|
||||
}
|
||||
operator T*() const {
|
||||
return ptr();
|
||||
|
@ -279,28 +276,30 @@ public:
|
|||
// Use that instead "= new T(parent, ...)"
|
||||
template <typename Parent, typename... Args>
|
||||
void create(Parent &&parent, Args&&... args) {
|
||||
delete _widget;
|
||||
_widget = new T(std_::forward<Parent>(parent), std_::forward<Args>(args)...);
|
||||
delete _object;
|
||||
_object = new T(std_::forward<Parent>(parent), std_::forward<Args>(args)...);
|
||||
}
|
||||
void destroy() {
|
||||
if (_widget) {
|
||||
delete _widget;
|
||||
_widget = nullptr;
|
||||
}
|
||||
delete base::take(_object);
|
||||
}
|
||||
void destroyDelayed() {
|
||||
if (_widget) {
|
||||
_widget->hide();
|
||||
_widget->deleteLater();
|
||||
_widget = nullptr;
|
||||
if (_object) {
|
||||
if (auto widget = base::up_cast<QWidget*>(_object)) {
|
||||
widget->hide();
|
||||
}
|
||||
_object->deleteLater();
|
||||
_object = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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() {
|
||||
return _menu->addSeparator();
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ public:
|
|||
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, base::lambda_unique<void()> callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
||||
QAction *addSeparator();
|
||||
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) {
|
||||
auto action = new QAction(text, this);
|
||||
auto action = addAction(new QAction(text, this), icon, iconOver);
|
||||
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) {
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
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, base::lambda_unique<void()> callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
||||
QAction *addSeparator();
|
||||
void clearActions();
|
||||
|
||||
|
|
|
@ -84,6 +84,10 @@ QAction *PopupMenu::addAction(const QString &text, const QObject *receiver, cons
|
|||
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() {
|
||||
return _menu->addSeparator();
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
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, base::lambda_unique<void()> callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
||||
QAction *addSeparator();
|
||||
void clearActions();
|
||||
|
||||
|
|
|
@ -190,6 +190,9 @@ defaultMaskButton: MaskButton {
|
|||
widgetSlideDuration: 200;
|
||||
widgetFadeDuration: 200;
|
||||
|
||||
fieldSearchIcon: icon {{ "box_search", #aaaaaa, point(9px, 8px) }};
|
||||
boxFieldSearchIcon: icon {{ "box_search", #aaaaaa, point(10px, 9px) }};
|
||||
|
||||
discreteSliderHeight: 39px;
|
||||
discreteSliderTop: 5px;
|
||||
discreteSliderSkip: 3px;
|
||||
|
|
|
@ -21,9 +21,147 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "stdafx.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 {
|
||||
|
||||
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() {
|
||||
|
|
|
@ -20,20 +20,63 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "window/window_title.h"
|
||||
|
||||
namespace Window {
|
||||
|
||||
class MainWindow : public QMainWindow {
|
||||
class TitleWidget;
|
||||
|
||||
class MainWindow : public QMainWindow, protected base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow();
|
||||
|
||||
void init();
|
||||
HitTestResult hitTest(const QPoint &p) const;
|
||||
|
||||
bool positionInited() const {
|
||||
return _positionInited;
|
||||
}
|
||||
void positionUpdated();
|
||||
|
||||
virtual void closeWithoutDestroy();
|
||||
|
||||
virtual ~MainWindow();
|
||||
|
||||
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) {
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
|
@ -446,6 +446,7 @@ void Widget::addToHeight(int add) {
|
|||
auto newHeight = height() + add;
|
||||
auto newPosition = computePosition(newHeight);
|
||||
updateGeometry(newPosition.x(), newPosition.y(), width(), newHeight);
|
||||
psUpdateOverlayed(this);
|
||||
}
|
||||
|
||||
void Widget::updateGeometry(int x, int y, int width, int height) {
|
||||
|
|
|
@ -24,8 +24,8 @@ using "ui/widgets/widgets.style";
|
|||
|
||||
windowMinWidth: 380px;
|
||||
windowMinHeight: 480px;
|
||||
windowDefWidth: 800px;
|
||||
windowDefHeight: 600px;
|
||||
windowDefaultWidth: 800px;
|
||||
windowDefaultHeight: 600px;
|
||||
windowShadow: icon {{ "window_shadow", windowShadowFg }};
|
||||
windowShadowShift: 1px;
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ enum class HitTestResult {
|
|||
None = 0,
|
||||
Client,
|
||||
SysButton,
|
||||
Icon,
|
||||
Caption,
|
||||
Top,
|
||||
TopRight,
|
||||
|
|