mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Improve ChooseFontBox navigation.
This commit is contained in:
parent
97ecc57be8
commit
d82e48f8e4
7 changed files with 141 additions and 37 deletions
BIN
Telegram/Resources/icons/menu/fonts.png
Normal file
BIN
Telegram/Resources/icons/menu/fonts.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 563 B |
BIN
Telegram/Resources/icons/menu/fonts@2x.png
Normal file
BIN
Telegram/Resources/icons/menu/fonts@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/menu/fonts@3x.png
Normal file
BIN
Telegram/Resources/icons/menu/fonts@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -1619,7 +1619,7 @@ void SetupThemeSettings(
|
||||||
tr::lng_settings_font_family(),
|
tr::lng_settings_font_family(),
|
||||||
std::move(label),
|
std::move(label),
|
||||||
st::settingsButton,
|
st::settingsButton,
|
||||||
{ &st::menuIconTranslate }
|
{ &st::menuIconFont }
|
||||||
)->setClickedCallback([=] {
|
)->setClickedCallback([=] {
|
||||||
const auto save = [=](QString chosen) {
|
const auto save = [=](QString chosen) {
|
||||||
*family = chosen;
|
*family = chosen;
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "ui/boxes/choose_font_box.h"
|
#include "ui/boxes/choose_font_box.h"
|
||||||
|
|
||||||
|
#include "base/event_filter.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
#include "ui/chat/chat_style.h"
|
#include "ui/chat/chat_style.h"
|
||||||
|
@ -18,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "ui/cached_round_corners.h"
|
#include "ui/cached_round_corners.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
|
#include "styles/style_boxes.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
|
@ -98,16 +100,11 @@ public:
|
||||||
rpl::producer<QString> filter,
|
rpl::producer<QString> filter,
|
||||||
rpl::producer<> submits,
|
rpl::producer<> submits,
|
||||||
Fn<void(QString)> chosen,
|
Fn<void(QString)> chosen,
|
||||||
Fn<void(Ui::ScrollToRequest)> scrollTo);
|
Fn<void(Ui::ScrollToRequest, anim::type)> scrollTo);
|
||||||
|
|
||||||
void initScroll();
|
void initScroll(anim::type animated);
|
||||||
void setMinHeight(int height);
|
void setMinHeight(int height);
|
||||||
void selectSkip(Qt::Key direction, int pageSize);
|
void selectSkip(Qt::Key direction);
|
||||||
|
|
||||||
[[nodiscard]] auto scrollToRequests() const
|
|
||||||
-> rpl::producer<Ui::ScrollToRequest> {
|
|
||||||
return _scrollToRequests.events();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Entry {
|
struct Entry {
|
||||||
|
@ -124,6 +121,7 @@ private:
|
||||||
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
int resizeGetHeight(int newWidth) override;
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
void leaveEventHook(QEvent *e) override;
|
||||||
void mouseMoveEvent(QMouseEvent *e) override;
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
void mousePressEvent(QMouseEvent *e) override;
|
void mousePressEvent(QMouseEvent *e) override;
|
||||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||||
|
@ -149,8 +147,11 @@ private:
|
||||||
int _selected = -1;
|
int _selected = -1;
|
||||||
int _pressed = -1;
|
int _pressed = -1;
|
||||||
|
|
||||||
|
std::optional<QPoint> _lastGlobalPoint;
|
||||||
|
bool _selectedByKeyboard = false;
|
||||||
|
|
||||||
Fn<void(QString)> _callback;
|
Fn<void(QString)> _callback;
|
||||||
rpl::event_stream<Ui::ScrollToRequest> _scrollToRequests;
|
Fn<void(Ui::ScrollToRequest, anim::type)> _scrollTo;
|
||||||
|
|
||||||
int _rowsSkip = 0;
|
int _rowsSkip = 0;
|
||||||
int _rowHeight = 0;
|
int _rowHeight = 0;
|
||||||
|
@ -169,12 +170,13 @@ Selector::Selector(
|
||||||
rpl::producer<QString> filter,
|
rpl::producer<QString> filter,
|
||||||
rpl::producer<> submits,
|
rpl::producer<> submits,
|
||||||
Fn<void(QString)> chosen,
|
Fn<void(QString)> chosen,
|
||||||
Fn<void(Ui::ScrollToRequest)> scrollTo)
|
Fn<void(Ui::ScrollToRequest, anim::type)> scrollTo)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _st(st::settingsButton)
|
, _st(st::settingsButton)
|
||||||
, _rows(FullList(now))
|
, _rows(FullList(now))
|
||||||
, _chosen(now)
|
, _chosen(now)
|
||||||
, _callback(std::move(chosen))
|
, _callback(std::move(chosen))
|
||||||
|
, _scrollTo(std::move(scrollTo))
|
||||||
, _rowsSkip(st::settingsInfoPhotoSkip)
|
, _rowsSkip(st::settingsInfoPhotoSkip)
|
||||||
, _rowHeight(_st.height + _st.padding.top() + _st.padding.bottom()) {
|
, _rowHeight(_st.height + _st.padding.top() + _st.padding.bottom()) {
|
||||||
Expects(_chosen >= 0 && _chosen < _rows.size());
|
Expects(_chosen >= 0 && _chosen < _rows.size());
|
||||||
|
@ -185,15 +187,14 @@ Selector::Selector(
|
||||||
applyFilter(query);
|
applyFilter(query);
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
|
|
||||||
std::move(submits) | rpl::filter([=] {
|
std::move(
|
||||||
return searching() && !_filtered.empty();
|
submits
|
||||||
}) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
choose(*_filtered.front());
|
if (_selected >= 0) {
|
||||||
}, _lifetime);
|
choose(shownRowAt(_selected));
|
||||||
|
} else if (searching() && !_filtered.empty()) {
|
||||||
_scrollToRequests.events(
|
choose(*_filtered.front());
|
||||||
) | rpl::start_with_next([=](Ui::ScrollToRequest request) {
|
}
|
||||||
scrollTo(request);
|
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,6 +259,17 @@ void Selector::updateSelected(int selected) {
|
||||||
if (was != now) {
|
if (was != now) {
|
||||||
setCursor(now ? style::cur_pointer : style::cur_default);
|
setCursor(now ? style::cur_pointer : style::cur_default);
|
||||||
}
|
}
|
||||||
|
if (_selectedByKeyboard) {
|
||||||
|
const auto top = (_selected > 0)
|
||||||
|
? (_rowsSkip + _selected * _rowHeight)
|
||||||
|
: 0;
|
||||||
|
const auto bottom = (_selected > 0)
|
||||||
|
? (top + _rowHeight)
|
||||||
|
: _selected
|
||||||
|
? 0
|
||||||
|
: _rowHeight;
|
||||||
|
_scrollTo({ top, bottom }, anim::type::instant);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selector::updatePressed(int pressed) {
|
void Selector::updatePressed(int pressed) {
|
||||||
|
@ -313,9 +325,10 @@ void Selector::validateCache(Entry &row) {
|
||||||
|
|
||||||
const auto textw = width() - _st.padding.left() - _st.padding.right();
|
const auto textw = width() - _st.padding.left() - _st.padding.right();
|
||||||
const auto metrics = QFontMetrics(font);
|
const auto metrics = QFontMetrics(font);
|
||||||
|
const auto textt = (_rowHeight - metrics.height()) / 2.;
|
||||||
p.drawText(
|
p.drawText(
|
||||||
_st.padding.left(),
|
_st.padding.left(),
|
||||||
_st.padding.top() + metrics.ascent(),
|
int(base::SafeRound(textt)) + metrics.ascent(),
|
||||||
metrics.elidedText(row.text, Qt::ElideRight, textw));
|
metrics.elidedText(row.text, Qt::ElideRight, textw));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +355,37 @@ void Selector::setMinHeight(int height) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selector::initScroll() {
|
void Selector::selectSkip(Qt::Key key) {
|
||||||
|
const auto count = shownRowsCount();
|
||||||
|
if (key == Qt::Key_Down) {
|
||||||
|
if (_selected + 1 < count) {
|
||||||
|
_selectedByKeyboard = true;
|
||||||
|
updateSelected(_selected + 1);
|
||||||
|
}
|
||||||
|
} else if (key == Qt::Key_Up) {
|
||||||
|
if (_selected >= 0) {
|
||||||
|
_selectedByKeyboard = true;
|
||||||
|
updateSelected(_selected - 1);
|
||||||
|
}
|
||||||
|
} else if (key == Qt::Key_PageDown) {
|
||||||
|
const auto change = _minHeight / _rowHeight;
|
||||||
|
if (_selected + 1 < count) {
|
||||||
|
_selectedByKeyboard = true;
|
||||||
|
updateSelected(std::min(_selected + change, count - 1));
|
||||||
|
}
|
||||||
|
} else if (key == Qt::Key_PageUp) {
|
||||||
|
const auto change = _minHeight / _rowHeight;
|
||||||
|
if (_selected > 0) {
|
||||||
|
_selectedByKeyboard = true;
|
||||||
|
updateSelected(std::max(_selected - change, 0));
|
||||||
|
} else if (!_selected) {
|
||||||
|
_selectedByKeyboard = true;
|
||||||
|
updateSelected(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Selector::initScroll(anim::type animated) {
|
||||||
const auto index = [&] {
|
const auto index = [&] {
|
||||||
if (searching()) {
|
if (searching()) {
|
||||||
const auto i = ranges::find(_filtered, _chosen, &Entry::id);
|
const auto i = ranges::find(_filtered, _chosen, &Entry::id);
|
||||||
|
@ -358,7 +401,7 @@ void Selector::initScroll() {
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
const auto top = _rowsSkip + index * _rowHeight;
|
const auto top = _rowsSkip + index * _rowHeight;
|
||||||
const auto use = std::max(top - (_minHeight - _rowHeight) / 2, 0);
|
const auto use = std::max(top - (_minHeight - _rowHeight) / 2, 0);
|
||||||
_scrollToRequests.fire({ use, use + _minHeight });
|
_scrollTo({ use, use + _minHeight }, animated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,6 +414,15 @@ void Selector::paintEvent(QPaintEvent *e) {
|
||||||
auto p = QPainter(this);
|
auto p = QPainter(this);
|
||||||
|
|
||||||
const auto rows = shownRowsCount();
|
const auto rows = shownRowsCount();
|
||||||
|
if (!rows) {
|
||||||
|
p.setFont(st::normalFont);
|
||||||
|
p.setPen(st::windowSubTextFg);
|
||||||
|
p.drawText(
|
||||||
|
QRect(0, 0, width(), height() * 2 / 3),
|
||||||
|
tr::lng_font_not_found(tr::now),
|
||||||
|
style::al_center);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto clip = e->rect();
|
const auto clip = e->rect();
|
||||||
const auto clipped = std::max(clip.y() - _rowsSkip, 0);
|
const auto clipped = std::max(clip.y() - _rowsSkip, 0);
|
||||||
const auto from = std::min(clipped / _rowHeight, rows);
|
const auto from = std::min(clipped / _rowHeight, rows);
|
||||||
|
@ -397,19 +449,37 @@ void Selector::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
if (!row.check) {
|
if (!row.check) {
|
||||||
row.check = std::make_unique<Ui::RadioView>(
|
row.check = std::make_unique<Ui::RadioView>(
|
||||||
st::defaultRadio,
|
st::langsRadio,
|
||||||
(row.id == _chosen),
|
(row.id == _chosen),
|
||||||
[=, row = &row] { updateRow(row, i); });
|
[=, row = &row] { updateRow(row, i); });
|
||||||
}
|
}
|
||||||
row.check->paint(
|
row.check->paint(
|
||||||
p,
|
p,
|
||||||
_st.iconLeft,
|
_st.iconLeft,
|
||||||
y + (_rowHeight - st::defaultRadio.diameter) / 2,
|
y + (_rowHeight - st::langsRadio.diameter) / 2,
|
||||||
width());
|
width());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Selector::leaveEventHook(QEvent *e) {
|
||||||
|
_lastGlobalPoint = std::nullopt;
|
||||||
|
if (!_selectedByKeyboard) {
|
||||||
|
updateSelected(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Selector::mouseMoveEvent(QMouseEvent *e) {
|
void Selector::mouseMoveEvent(QMouseEvent *e) {
|
||||||
|
if (!_lastGlobalPoint) {
|
||||||
|
_lastGlobalPoint = e->globalPos();
|
||||||
|
if (_selectedByKeyboard) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (*_lastGlobalPoint == e->globalPos() && _selectedByKeyboard) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
_lastGlobalPoint = e->globalPos();
|
||||||
|
}
|
||||||
|
_selectedByKeyboard = false;
|
||||||
const auto y = e->y() - _rowsSkip;
|
const auto y = e->y() - _rowsSkip;
|
||||||
const auto index = (y >= 0) ? (y / _rowHeight) : -1;
|
const auto index = (y >= 0) ? (y / _rowHeight) : -1;
|
||||||
updateSelected((index >= 0 && index < shownRowsCount()) ? index : -1);
|
updateSelected((index >= 0 && index < shownRowsCount()) ? index : -1);
|
||||||
|
@ -443,8 +513,11 @@ void Selector::choose(Entry &row) {
|
||||||
row.check->setChecked(true, anim::type::normal);
|
row.check->setChecked(true, anim::type::normal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const auto animated = searching()
|
||||||
|
? anim::type::instant
|
||||||
|
: anim::type::normal;
|
||||||
_callback(id);
|
_callback(id);
|
||||||
initScroll();
|
initScroll(animated);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selector::addRipple(int index, QPoint position) {
|
void Selector::addRipple(int index, QPoint position) {
|
||||||
|
@ -839,8 +912,10 @@ void ChooseFontBox(
|
||||||
state->family = value;
|
state->family = value;
|
||||||
filter->clearQuery();
|
filter->clearQuery();
|
||||||
};
|
};
|
||||||
const auto scrollTo = [=](Ui::ScrollToRequest request) {
|
const auto scrollTo = [=](
|
||||||
box->scrollToY(request.ymin, request.ymax);
|
Ui::ScrollToRequest request,
|
||||||
|
anim::type animated) {
|
||||||
|
box->scrollTo(request, animated);
|
||||||
};
|
};
|
||||||
const auto selector = box->addRow(
|
const auto selector = box->addRow(
|
||||||
object_ptr<Selector>(
|
object_ptr<Selector>(
|
||||||
|
@ -854,6 +929,20 @@ void ChooseFontBox(
|
||||||
box->setMinHeight(st::boxMaxListHeight);
|
box->setMinHeight(st::boxMaxListHeight);
|
||||||
box->setMaxHeight(st::boxMaxListHeight);
|
box->setMaxHeight(st::boxMaxListHeight);
|
||||||
|
|
||||||
|
base::install_event_filter(filter, [=](not_null<QEvent*> e) {
|
||||||
|
if (e->type() == QEvent::KeyPress) {
|
||||||
|
const auto key = static_cast<QKeyEvent*>(e.get())->key();
|
||||||
|
if (key == Qt::Key_Up
|
||||||
|
|| key == Qt::Key_Down
|
||||||
|
|| key == Qt::Key_PageUp
|
||||||
|
|| key == Qt::Key_PageDown) {
|
||||||
|
selector->selectSkip(Qt::Key(key));
|
||||||
|
return base::EventFilterResult::Cancel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return base::EventFilterResult::Continue;
|
||||||
|
});
|
||||||
|
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
box->heightValue(),
|
box->heightValue(),
|
||||||
top->heightValue()
|
top->heightValue()
|
||||||
|
@ -861,27 +950,41 @@ void ChooseFontBox(
|
||||||
selector->setMinHeight(box - top);
|
selector->setMinHeight(box - top);
|
||||||
}, selector->lifetime());
|
}, selector->lifetime());
|
||||||
|
|
||||||
box->addButton(tr::lng_settings_save(), [=] {
|
const auto apply = [=](QString chosen) {
|
||||||
if (state->family.current() == family) {
|
if (chosen == family) {
|
||||||
box->closeBox();
|
box->closeBox();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
box->getDelegate()->show(Ui::MakeConfirmBox({
|
box->getDelegate()->show(Ui::MakeConfirmBox({
|
||||||
.text = tr::lng_settings_need_restart(),
|
.text = tr::lng_settings_need_restart(),
|
||||||
.confirmed = [=] { save(state->family.current()); },
|
.confirmed = [=] { save(chosen); },
|
||||||
.confirmText = tr::lng_settings_restart_now(),
|
.confirmText = tr::lng_settings_restart_now(),
|
||||||
}));
|
}));
|
||||||
});
|
};
|
||||||
box->addButton(tr::lng_cancel(), [=] {
|
const auto refreshButtons = [=](QString chosen) {
|
||||||
box->closeBox();
|
box->clearButtons();
|
||||||
});
|
// Doesn't fit in most languages.
|
||||||
|
//if (!chosen.isEmpty()) {
|
||||||
|
// box->addLeftButton(tr::lng_background_reset_default(), [=] {
|
||||||
|
// apply(QString());
|
||||||
|
// });
|
||||||
|
//}
|
||||||
|
box->addButton(tr::lng_settings_save(), [=] {
|
||||||
|
apply(chosen);
|
||||||
|
});
|
||||||
|
box->addButton(tr::lng_cancel(), [=] {
|
||||||
|
box->closeBox();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
state->family.value(
|
||||||
|
) | rpl::start_with_next(refreshButtons, box->lifetime());
|
||||||
|
|
||||||
box->setFocusCallback([=] {
|
box->setFocusCallback([=] {
|
||||||
filter->setInnerFocus();
|
filter->setInnerFocus();
|
||||||
});
|
});
|
||||||
box->setInitScrollCallback([=] {
|
box->setInitScrollCallback([=] {
|
||||||
SendPendingMoveResizeEvents(box);
|
SendPendingMoveResizeEvents(box);
|
||||||
selector->initScroll();
|
selector->initScroll(anim::type::instant);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,7 @@ menuIconAsMessages: icon {{ "menu/mode_messages", menuIconColor }};
|
||||||
menuIconTagFilter: icon{{ "menu/tag_filter", menuIconColor }};
|
menuIconTagFilter: icon{{ "menu/tag_filter", menuIconColor }};
|
||||||
menuIconTagRename: icon{{ "menu/tag_rename", menuIconColor }};
|
menuIconTagRename: icon{{ "menu/tag_rename", menuIconColor }};
|
||||||
menuIconGroupsHide: icon {{ "menu/hide_members", menuIconColor }};
|
menuIconGroupsHide: icon {{ "menu/hide_members", menuIconColor }};
|
||||||
|
menuIconFont: icon {{ "menu/fonts", menuIconColor }};
|
||||||
|
|
||||||
menuIconTTLAny: icon {{ "menu/auto_delete_plain", menuIconColor }};
|
menuIconTTLAny: icon {{ "menu/auto_delete_plain", menuIconColor }};
|
||||||
menuIconTTLAnyTextPosition: point(11px, 22px);
|
menuIconTTLAnyTextPosition: point(11px, 22px);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit ae5a61f7aeaa18eb4016d290c45be990c614a9a1
|
Subproject commit 27b75347341838cffd1d5a84c66db7241d27d030
|
Loading…
Add table
Reference in a new issue