Shutdown on Linux fix attempt. Draft remove in empty conversation fix.

Larger badge of unread messages in history-to-down button.
Submit bot-start by Enter. Fix icons show in chat without input field.
This commit is contained in:
John Preston 2016-06-21 18:58:07 +03:00
parent c73b5a6da4
commit af4b3ba023
12 changed files with 137 additions and 47 deletions

View File

@ -2288,7 +2288,9 @@ namespace {
setLaunchState(QuitRequested);
if (auto window = wnd()) {
window->hide();
if (!Sandbox::isSavingSession()) {
window->hide();
}
}
if (auto mainwidget = main()) {
mainwidget->saveDraftToCloud();

View File

@ -42,7 +42,6 @@ void applyPeerCloudDraft(PeerId peerId, const MTPDdraftMessage &draft) {
history->setCloudDraft(std_::move(cloudDraft));
history->createLocalDraftFromCloud();
history->updateChatListSortPosition();
history->updateChatListEntry();
if (auto main = App::main()) {
main->applyCloudDraft(history);
@ -56,7 +55,6 @@ void clearPeerCloudDraft(PeerId peerId) {
history->clearLocalDraft();
history->updateChatListSortPosition();
history->updateChatListEntry();
if (auto main = App::main()) {
main->applyCloudDraft(history);

View File

@ -140,59 +140,78 @@ void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draf
history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
}
class UnreadBadgeStyleData : public Data::AbstractStructure {
public:
struct UnreadBadgeSizeData {
QImage circle;
QPixmap left[4], right[4];
};
class UnreadBadgeStyleData : public Data::AbstractStructure {
public:
UnreadBadgeSizeData sizes[UnreadBadgeSizesCount];
style::color bg[4] = { st::dialogsUnreadBg, st::dialogsUnreadBgActive, st::dialogsUnreadBgMuted, st::dialogsUnreadBgMutedActive };
};
Data::GlobalStructurePointer<UnreadBadgeStyleData> unreadBadgeStyle;
void createCircleMask(int size) {
if (!unreadBadgeStyle->circle.isNull()) return;
void createCircleMask(UnreadBadgeSizeData *data, int size) {
if (!data->circle.isNull()) return;
unreadBadgeStyle->circle = style::createCircleMask(size);
data->circle = style::createCircleMask(size);
}
QImage colorizeCircleHalf(int size, int half, int xoffset, style::color color) {
auto result = style::colorizeImage(unreadBadgeStyle->circle, color, QRect(xoffset, 0, half, size));
QImage colorizeCircleHalf(UnreadBadgeSizeData *data, int size, int half, int xoffset, style::color color) {
auto result = style::colorizeImage(data->circle, color, QRect(xoffset, 0, half, size));
result.setDevicePixelRatio(cRetinaFactor());
return result;
}
} // namepsace
void paintUnreadBadge(Painter &p, const QRect &rect, bool active, bool muted) {
int index = (active ? 0x01 : 0x00) | (muted ? 0x02 : 0x00);
int size = rect.height(), sizehalf = size / 2;
void paintUnreadBadge(Painter &p, const QRect &rect, const UnreadBadgeStyle &st) {
t_assert(rect.height() == st.size);
int index = (st.active ? 0x01 : 0x00) | (st.muted ? 0x02 : 0x00);
int size = st.size, sizehalf = size / 2;
unreadBadgeStyle.createIfNull();
auto badgeData = unreadBadgeStyle->sizes;
if (st.sizeId > 0) {
t_assert(st.sizeId < UnreadBadgeSizesCount);
badgeData = &unreadBadgeStyle->sizes[st.sizeId];
}
style::color bg = unreadBadgeStyle->bg[index];
if (unreadBadgeStyle->left[index].isNull()) {
if (badgeData->left[index].isNull()) {
int imgsize = size * cIntRetinaFactor(), imgsizehalf = sizehalf * cIntRetinaFactor();
createCircleMask(size);
unreadBadgeStyle->left[index] = App::pixmapFromImageInPlace(colorizeCircleHalf(imgsize, imgsizehalf, 0, bg));
unreadBadgeStyle->right[index] = App::pixmapFromImageInPlace(colorizeCircleHalf(imgsize, imgsizehalf, imgsize - imgsizehalf, bg));
createCircleMask(badgeData, size);
badgeData->left[index] = App::pixmapFromImageInPlace(colorizeCircleHalf(badgeData, imgsize, imgsizehalf, 0, bg));
badgeData->right[index] = App::pixmapFromImageInPlace(colorizeCircleHalf(badgeData, imgsize, imgsizehalf, imgsize - imgsizehalf, bg));
}
int bar = rect.width() - 2 * sizehalf;
p.drawPixmap(rect.x(), rect.y(), unreadBadgeStyle->left[index]);
p.drawPixmap(rect.x(), rect.y(), badgeData->left[index]);
if (bar) {
p.fillRect(rect.x() + sizehalf, rect.y(), bar, rect.height(), bg);
}
p.drawPixmap(rect.x() + sizehalf + bar, rect.y(), unreadBadgeStyle->right[index]);
p.drawPixmap(rect.x() + sizehalf + bar, rect.y(), badgeData->right[index]);
}
void paintUnreadCount(Painter &p, const QString &text, int x, int y, style::align align, bool active, bool muted, int *outUnreadWidth) {
int unreadWidth = st::dialogsUnreadFont->width(text);
UnreadBadgeStyle::UnreadBadgeStyle()
: align(style::al_right)
, active(false)
, muted(false)
, size(st::dialogsUnreadHeight)
, sizeId(UnreadBadgeInDialogs)
, font(st::dialogsUnreadFont) {
}
void paintUnreadCount(Painter &p, const QString &text, int x, int y, const UnreadBadgeStyle &st, int *outUnreadWidth) {
int unreadWidth = st.font->width(text);
int unreadRectWidth = unreadWidth + 2 * st::dialogsUnreadPadding;
int unreadRectHeight = st::dialogsUnreadHeight;
int unreadRectHeight = st.size;
accumulate_max(unreadRectWidth, unreadRectHeight);
int unreadRectLeft = x;
if ((align & Qt::AlignHorizontal_Mask) & style::al_center) {
if ((st.align & Qt::AlignHorizontal_Mask) & style::al_center) {
unreadRectLeft = (x - unreadRectWidth) / 2;
} else if ((align & Qt::AlignHorizontal_Mask) & style::al_right) {
} else if ((st.align & Qt::AlignHorizontal_Mask) & style::al_right) {
unreadRectLeft = x - unreadRectWidth;
}
int unreadRectTop = y;
@ -200,11 +219,11 @@ void paintUnreadCount(Painter &p, const QString &text, int x, int y, style::alig
*outUnreadWidth = unreadRectWidth;
}
paintUnreadBadge(p, QRect(unreadRectLeft, unreadRectTop, unreadRectWidth, unreadRectHeight), active, muted);
paintUnreadBadge(p, QRect(unreadRectLeft, unreadRectTop, unreadRectWidth, unreadRectHeight), st);
p.setFont(st::dialogsUnreadFont);
p.setPen(active ? st::dialogsUnreadFgActive : st::dialogsUnreadFg);
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + st::dialogsUnreadTop + st::dialogsUnreadFont->ascent, text);
p.setFont(st.font);
p.setPen(st.active ? st::dialogsUnreadFgActive : st::dialogsUnreadFg);
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + st::dialogsUnreadTop + st.font->ascent, text);
}
void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool selected, bool onlyBackground) {
@ -242,7 +261,11 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele
int unreadRight = w - st::dialogsPadding.x();
int unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - st::dialogsUnreadTop;
int unreadWidth = 0;
paintUnreadCount(p, counter, unreadRight, unreadTop, style::al_right, active, mutedCounter, &unreadWidth);
UnreadBadgeStyle st;
st.active = active;
st.muted = history->mute();
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
availableWidth -= unreadWidth + st::dialogsUnreadPadding;
}
if (history->typing.isEmpty() && history->sendActions.isEmpty()) {
@ -281,7 +304,9 @@ void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool o
if (mutedHidden) {
if (int32 unread = App::histories().unreadMutedCount()) {
int unreadRight = w - st::dialogsPadding.x();
paintUnreadCount(p, QString::number(unread), unreadRight, unreadTop, style::al_right, false, true, nullptr);
UnreadBadgeStyle st;
st.muted = true;
paintUnreadCount(p, QString::number(unread), unreadRight, unreadTop, st, nullptr);
}
}
}

View File

@ -35,8 +35,23 @@ public:
void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool onlyBackground);
void paintUnreadCount(Painter &p, const QString &text, int x, int y, style::align align, bool active, bool muted, int *outUnreadWidth);
void paintUnreadBadge(Painter &p, const QRect &rect, bool active, bool muted);
enum UnreadBadgeSize {
UnreadBadgeInDialogs = 0,
UnreadBadgeInHistoryToDown,
UnreadBadgeSizesCount
};
struct UnreadBadgeStyle {
UnreadBadgeStyle();
style::align align;
bool active;
bool muted;
int size;
UnreadBadgeSize sizeId;
style::font font;
};
void paintUnreadCount(Painter &p, const QString &text, int x, int y, const UnreadBadgeStyle &st, int *outUnreadWidth = nullptr);
} // namespace Layout
} // namespace Dialogs

View File

@ -230,7 +230,6 @@ Data::Draft *History::createCloudDraft(Data::Draft *fromDraft) {
cloudDraftTextCache.clear();
updateChatListSortPosition();
updateChatListEntry();
return cloudDraft();
}
@ -248,7 +247,6 @@ void History::clearCloudDraft() {
_cloudDraft = nullptr;
cloudDraftTextCache.clear();
updateChatListSortPosition();
updateChatListEntry();
}
}
@ -1759,6 +1757,7 @@ namespace {
}
inline uint64 dialogPosFromDate(const QDateTime &date) {
if (date.isNull()) return 0;
return (uint64(date.toTime_t()) << 32) | (++_dialogsPosToTopShift);
}
@ -1769,8 +1768,8 @@ void History::setLastMessage(HistoryItem *msg) {
setChatsListDate(msg->date);
} else {
lastMsg = 0;
updateChatListEntry();
}
updateChatListEntry();
}
bool History::needUpdateInChatList() const {
@ -1796,7 +1795,7 @@ void History::setChatsListDate(const QDateTime &date) {
void History::updateChatListSortPosition() {
auto chatListDate = [this]() {
if (auto draft = cloudDraft()) {
if (draft->date > lastMsgDate) {
if (!Data::draftIsNull(draft) && draft->date > lastMsgDate) {
return draft->date;
}
}
@ -1804,8 +1803,15 @@ void History::updateChatListSortPosition() {
};
_sortKeyInChatList = dialogPosFromDate(chatListDate());
if (App::main() && needUpdateInChatList()) {
App::main()->createDialog(this);
if (auto m = App::main()) {
if (needUpdateInChatList()) {
if (_sortKeyInChatList) {
m->createDialog(this);
updateChatListEntry();
} else {
m->deleteConversation(peer, false);
}
}
}
}

View File

@ -42,3 +42,5 @@ membersInnerDropdown: InnerDropdown(defaultInnerDropdown) {
scrollMargin: margins(0px, 5px, 0px, 5px);
scrollPadding: margins(0px, 3px, 8px, 3px);
}
historyToDownBadgeFont: semiboldFont;
historyToDownBadgeSize: 22px;

View File

@ -1477,6 +1477,10 @@ void HistoryInner::keyPressEvent(QKeyEvent *e) {
if (!_selected.isEmpty() && selectedForDelete == selectedForForward) {
_widget->onDeleteSelected();
}
} else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
if (_selected.isEmpty()) {
_widget->onListEnterPressed();
}
} else {
e->ignore();
}
@ -5863,10 +5867,13 @@ void HistoryWidget::onFilesDrop(const QMimeData *data) {
}
void HistoryWidget::onKbToggle(bool manual) {
auto fieldEnabled = canWriteMessage();
if (_kbShown || _kbReplyTo) {
_kbHide.hide();
if (_kbShown) {
_kbShow.show();
if (fieldEnabled) {
_kbShow.show();
}
if (manual && _history) {
_history->lastKeyboardHiddenId = _keyboard.forMsgId().msg;
}
@ -5890,14 +5897,16 @@ void HistoryWidget::onKbToggle(bool manual) {
} else if (!_keyboard.hasMarkup() && _keyboard.forceReply()) {
_kbHide.hide();
_kbShow.hide();
_cmdStart.show();
if (fieldEnabled) {
_cmdStart.show();
}
_kbScroll.hide();
_kbShown = false;
_field.setMaxHeight(st::maxFieldHeight);
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard.forceReply()) ? App::histItemById(_keyboard.forMsgId()) : 0;
if (_kbReplyTo && !_editMsgId && !_replyToId) {
if (_kbReplyTo && !_editMsgId && !_replyToId && fieldEnabled) {
updateReplyToName();
_replyEditMsgText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
_fieldBarCancel.show();
@ -5906,7 +5915,7 @@ void HistoryWidget::onKbToggle(bool manual) {
if (manual && _history) {
_history->lastKeyboardHiddenId = 0;
}
} else {
} else if (fieldEnabled) {
_kbHide.show();
_kbShow.hide();
_kbScroll.show();
@ -5927,7 +5936,7 @@ void HistoryWidget::onKbToggle(bool manual) {
}
}
resizeEvent(0);
if (_kbHide.isHidden()) {
if (_kbHide.isHidden() && canWriteMessage()) {
_attachEmoji.show();
} else {
_attachEmoji.hide();
@ -8072,6 +8081,12 @@ void HistoryWidget::onListEscapePressed() {
}
}
void HistoryWidget::onListEnterPressed() {
if (!_botStart.isHidden()) {
onBotStart();
}
}
void HistoryWidget::onClearSelected() {
if (_list) _list->clearSelectedItems();
}

View File

@ -651,6 +651,7 @@ public:
void stopRecording(bool send);
void onListEscapePressed();
void onListEnterPressed();
void sendBotCommand(PeerData *peer, UserData *bot, const QString &cmd, MsgId replyTo);
bool insertBotCommand(const QString &cmd, bool specialGif);

View File

@ -1285,9 +1285,14 @@ void MainWindow::toggleDisplayNotifyFromTray() {
}
void MainWindow::closeEvent(QCloseEvent *e) {
e->ignore();
if (!MTP::authedId() || Sandbox::isSavingSession() || !Ui::hideWindowNoQuit()) {
if (Sandbox::isSavingSession()) {
e->accept();
App::quit();
} else {
e->ignore();
if (!MTP::authedId() || !Ui::hideWindowNoQuit()) {
App::quit();
}
}
}

View File

@ -68,12 +68,17 @@ void HistoryDownButton::paintEvent(QPaintEvent *e) {
st::historyToDownArrow.paint(p, QPoint(0, st::historyToDownPaddingTop), width());
if (_unreadCount > 0) {
p.setOpacity(opacity);
bool active = false, muted = false;
auto unreadString = QString::number(_unreadCount);
if (unreadString.size() > 4) {
unreadString = qsl("..") + unreadString.mid(unreadString.size() - 4);
}
Dialogs::Layout::paintUnreadCount(p, unreadString, width(), 0, style::al_center, active, muted, nullptr);
Dialogs::Layout::UnreadBadgeStyle st;
st.align = style::al_center;
st.font = st::historyToDownBadgeFont;
st.size = st::historyToDownBadgeSize;
st.sizeId = Dialogs::Layout::UnreadBadgeInHistoryToDown;
Dialogs::Layout::paintUnreadCount(p, unreadString, width(), 0, st, nullptr);
}
}

View File

@ -1268,6 +1268,11 @@
<ClCompile Include="SourceFiles\overviewwidget.cpp" />
<ClCompile Include="SourceFiles\overview\overview_layout.cpp" />
<ClCompile Include="SourceFiles\passcodewidget.cpp" />
<ClCompile Include="SourceFiles\platform\linux\linux_libs.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="SourceFiles\platform\linux\main_window_linux.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
@ -1726,6 +1731,11 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/platform/linux/main_window_linux.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include"</Command>
</CustomBuild>
<ClInclude Include="SourceFiles\platform\linux\linux_libs.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="SourceFiles\platform\platform_main_window.h" />
<CustomBuild Include="SourceFiles\platform\win\main_window_win.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>

View File

@ -1341,6 +1341,9 @@
<ClCompile Include="GeneratedFiles\Release\moc_inner_dropdown.cpp">
<Filter>GeneratedFiles\Release</Filter>
</ClCompile>
<ClCompile Include="SourceFiles\platform\linux\linux_libs.cpp">
<Filter>SourceFiles\platform\linux</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="SourceFiles\stdafx.h">
@ -1589,6 +1592,9 @@
<ClInclude Include="SourceFiles\platform\winrt\main_window_winrt.h">
<Filter>SourceFiles\platform\winrt</Filter>
</ClInclude>
<ClInclude Include="SourceFiles\platform\linux\linux_libs.h">
<Filter>SourceFiles\platform\linux</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="SourceFiles\application.h">