mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-16 04:07:02 +00:00
Added ability to change zoom in IV.
This commit is contained in:
parent
d351a7d697
commit
7e14277ead
@ -12,6 +12,7 @@ body {
|
||||
margin: 0;
|
||||
background-color: var(--td-window-bg);
|
||||
color: var(--td-window-fg);
|
||||
zoom: var(--td-zoom-percentage);
|
||||
}
|
||||
|
||||
html.custom_scroll ::-webkit-scrollbar {
|
||||
|
@ -222,7 +222,7 @@ QByteArray Settings::serialize() const {
|
||||
+ Serialize::stringSize(_customFontFamily)
|
||||
+ sizeof(qint32) * 3
|
||||
+ Serialize::bytearraySize(_tonsiteStorageToken)
|
||||
+ sizeof(qint32);
|
||||
+ sizeof(qint32) * 2;
|
||||
|
||||
auto result = QByteArray();
|
||||
result.reserve(size);
|
||||
@ -377,7 +377,8 @@ QByteArray Settings::serialize() const {
|
||||
<< qint32(_systemUnlockEnabled ? 1 : 0)
|
||||
<< qint32(!_weatherInCelsius ? 0 : *_weatherInCelsius ? 1 : 2)
|
||||
<< _tonsiteStorageToken
|
||||
<< qint32(_includeMutedCounterFolders ? 1 : 0);
|
||||
<< qint32(_includeMutedCounterFolders ? 1 : 0)
|
||||
<< qint32(_ivZoom.current());
|
||||
}
|
||||
|
||||
Ensures(result.size() == size);
|
||||
@ -501,6 +502,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||
qint32 systemUnlockEnabled = _systemUnlockEnabled ? 1 : 0;
|
||||
qint32 weatherInCelsius = !_weatherInCelsius ? 0 : *_weatherInCelsius ? 1 : 2;
|
||||
QByteArray tonsiteStorageToken = _tonsiteStorageToken;
|
||||
qint32 ivZoom = _ivZoom.current();
|
||||
|
||||
stream >> themesAccentColors;
|
||||
if (!stream.atEnd()) {
|
||||
@ -810,6 +812,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||
if (!stream.atEnd()) {
|
||||
stream >> includeMutedCounterFolders;
|
||||
}
|
||||
if (!stream.atEnd()) {
|
||||
stream >> ivZoom;
|
||||
}
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("App Error: "
|
||||
"Bad data for Core::Settings::constructFromSerialized()"));
|
||||
@ -1021,6 +1026,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||
? std::optional<bool>()
|
||||
: (weatherInCelsius == 1);
|
||||
_tonsiteStorageToken = tonsiteStorageToken;
|
||||
_ivZoom = ivZoom;
|
||||
}
|
||||
|
||||
QString Settings::getSoundPath(const QString &key) const {
|
||||
@ -1408,6 +1414,7 @@ void Settings::resetOnLastLogout() {
|
||||
_hiddenGroupCallTooltips = 0;
|
||||
_storiesClickTooltipHidden = false;
|
||||
_ttlVoiceClickTooltipHidden = false;
|
||||
_ivZoom = 100;
|
||||
|
||||
_recentEmojiPreload.clear();
|
||||
_recentEmoji.clear();
|
||||
@ -1547,4 +1554,16 @@ bool Settings::rememberedDeleteMessageOnlyForYou() const {
|
||||
return _rememberedDeleteMessageOnlyForYou;
|
||||
}
|
||||
|
||||
int Settings::ivZoom() const {
|
||||
return _ivZoom.current();
|
||||
}
|
||||
rpl::producer<int> Settings::ivZoomValue() const {
|
||||
return _ivZoom.value();
|
||||
}
|
||||
void Settings::setIvZoom(int value) {
|
||||
constexpr auto kMin = 30;
|
||||
constexpr auto kMax = 200;
|
||||
_ivZoom = std::clamp(value, kMin, kMax);
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
|
@ -915,6 +915,10 @@ public:
|
||||
_tonsiteStorageToken = value;
|
||||
}
|
||||
|
||||
[[nodiscard]] int ivZoom() const;
|
||||
[[nodiscard]] rpl::producer<int> ivZoomValue() const;
|
||||
void setIvZoom(int value);
|
||||
|
||||
[[nodiscard]] static bool ThirdColumnByDefault();
|
||||
[[nodiscard]] static float64 DefaultDialogsWidthRatio();
|
||||
|
||||
@ -1050,6 +1054,7 @@ private:
|
||||
bool _systemUnlockEnabled = false;
|
||||
std::optional<bool> _weatherInCelsius;
|
||||
QByteArray _tonsiteStorageToken;
|
||||
rpl::variable<int> _ivZoom = 100;
|
||||
|
||||
bool _tabbedReplacedWithInfo = false; // per-window
|
||||
rpl::event_stream<bool> _tabbedReplacedWithInfoValue; // per-window
|
||||
|
@ -29,6 +29,38 @@ ivBack: IconButton(ivMenuToggle) {
|
||||
iconOver: ivBackIcon;
|
||||
rippleAreaPosition: point(12px, 6px);
|
||||
}
|
||||
ivZoomButtonsSize: 26px;
|
||||
ivPlusMinusZoom: IconButton(ivMenuToggle) {
|
||||
width: ivZoomButtonsSize;
|
||||
height: ivZoomButtonsSize;
|
||||
|
||||
rippleAreaPosition: point(0px, 0px);
|
||||
rippleAreaSize: ivZoomButtonsSize;
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: windowBgOver;
|
||||
}
|
||||
}
|
||||
ivResetZoomStyle: TextStyle(defaultTextStyle) {
|
||||
font: font(12px);
|
||||
}
|
||||
ivResetZoom: RoundButton(defaultActiveButton) {
|
||||
textFg: windowFg;
|
||||
textFgOver: windowFgOver;
|
||||
textBg: windowBg;
|
||||
textBgOver: windowBgOver;
|
||||
|
||||
height: ivZoomButtonsSize;
|
||||
padding: margins(0px, 0px, 0px, 0px);
|
||||
|
||||
style: ivResetZoomStyle;
|
||||
|
||||
ripple: defaultRippleAnimation;
|
||||
}
|
||||
ivResetZoomLabel: FlatLabel(defaultFlatLabel) {
|
||||
textFg: windowFg;
|
||||
style: ivResetZoomStyle;
|
||||
}
|
||||
ivResetZoomInnerPadding: 20px;
|
||||
ivBackIconDisabled: icon {{ "box_button_back", menuIconFg }};
|
||||
ivForwardIcon: icon {{ "box_button_back-flip_horizontal", menuIconColor }};
|
||||
ivForward: IconButton(ivBack) {
|
||||
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/platform/ui_platform_window_title.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/menu/menu_action.h"
|
||||
#include "ui/widgets/rp_window.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
@ -50,7 +51,145 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
namespace Iv {
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] QByteArray ComputeStyles() {
|
||||
constexpr auto kZoomStep = int(10);
|
||||
constexpr auto kDefaultZoom = int(100);
|
||||
|
||||
class ItemZoom final : public Ui::Menu::Action {
|
||||
public:
|
||||
ItemZoom(
|
||||
not_null<RpWidget*> parent,
|
||||
const not_null<Delegate*> delegate,
|
||||
const style::Menu &st)
|
||||
: Ui::Menu::Action(
|
||||
parent,
|
||||
st,
|
||||
Ui::CreateChild<QAction>(parent),
|
||||
nullptr,
|
||||
nullptr)
|
||||
, _delegate(delegate)
|
||||
, _st(st) {
|
||||
init();
|
||||
}
|
||||
|
||||
void init() {
|
||||
enableMouseSelecting();
|
||||
|
||||
AbstractButton::setDisabled(true);
|
||||
|
||||
class SmallButton final : public Ui::IconButton {
|
||||
public:
|
||||
SmallButton(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
QChar c,
|
||||
float64 skip,
|
||||
const style::color &color)
|
||||
: Ui::IconButton(parent, st::ivPlusMinusZoom)
|
||||
, _color(color)
|
||||
, _skip(style::ConvertFloatScale(skip))
|
||||
, _c(c) {
|
||||
}
|
||||
|
||||
void paintEvent(QPaintEvent *event) override {
|
||||
auto p = Painter(this);
|
||||
Ui::RippleButton::paintRipple(
|
||||
p,
|
||||
st::ivPlusMinusZoom.rippleAreaPosition);
|
||||
p.setPen(_color);
|
||||
p.setFont(st::normalFont);
|
||||
p.drawText(
|
||||
QRectF(rect()).translated(0, _skip),
|
||||
_c,
|
||||
style::al_center);
|
||||
}
|
||||
|
||||
private:
|
||||
const style::color _color;
|
||||
const float64 _skip;
|
||||
const QChar _c;
|
||||
|
||||
};
|
||||
|
||||
const auto reset = Ui::CreateChild<Ui::RoundButton>(
|
||||
this,
|
||||
rpl::single<QString>(QString()),
|
||||
st::ivResetZoom);
|
||||
const auto resetLabel = Ui::CreateChild<Ui::FlatLabel>(
|
||||
reset,
|
||||
tr::lng_background_reset_default(),
|
||||
st::ivResetZoomLabel);
|
||||
resetLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
reset->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
||||
reset->setClickedCallback([this] {
|
||||
_delegate->ivSetZoom(kDefaultZoom);
|
||||
});
|
||||
reset->show();
|
||||
const auto plus = Ui::CreateChild<SmallButton>(
|
||||
this,
|
||||
'+',
|
||||
0,
|
||||
_st.itemFg);
|
||||
plus->setClickedCallback([this] {
|
||||
_delegate->ivSetZoom(_delegate->ivZoom() + kZoomStep);
|
||||
});
|
||||
plus->show();
|
||||
const auto minus = Ui::CreateChild<SmallButton>(
|
||||
this,
|
||||
QChar(0x2013),
|
||||
-1,
|
||||
_st.itemFg);
|
||||
minus->setClickedCallback([this] {
|
||||
_delegate->ivSetZoom(_delegate->ivZoom() - kZoomStep);
|
||||
});
|
||||
minus->show();
|
||||
|
||||
_delegate->ivZoomValue(
|
||||
) | rpl::start_with_next([this](int value) {
|
||||
_text.setText(_st.itemStyle, QString::number(value) + '%');
|
||||
update();
|
||||
}, lifetime());
|
||||
|
||||
rpl::combine(
|
||||
sizeValue(),
|
||||
reset->sizeValue()
|
||||
) | rpl::start_with_next([=, this](const QSize &size, const QSize &) {
|
||||
reset->setFullWidth(0
|
||||
+ resetLabel->width()
|
||||
+ st::ivResetZoomInnerPadding);
|
||||
resetLabel->moveToLeft(
|
||||
(reset->width() - resetLabel->width()) / 2,
|
||||
(reset->height() - resetLabel->height()) / 2);
|
||||
reset->moveToRight(
|
||||
_st.itemPadding.right(),
|
||||
(size.height() - reset->height()) / 2);
|
||||
plus->moveToRight(
|
||||
_st.itemPadding.right() + reset->width(),
|
||||
(size.height() - plus->height()) / 2);
|
||||
minus->moveToRight(
|
||||
_st.itemPadding.right() + plus->width() + reset->width(),
|
||||
(size.height() - minus->height()) / 2);
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void paintEvent(QPaintEvent *event) override {
|
||||
auto p = QPainter(this);
|
||||
p.setPen(_st.itemFg);
|
||||
_text.draw(p, {
|
||||
.position = QPoint(
|
||||
_st.itemIconPosition.x(),
|
||||
(height() - _text.minHeight()) / 2),
|
||||
.outerWidth = width(),
|
||||
.availableWidth = width(),
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
const not_null<Delegate*> _delegate;
|
||||
const style::Menu &_st;
|
||||
Ui::Text::String _text;
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]] QByteArray ComputeStyles(int zoom) {
|
||||
static const auto map = base::flat_map<QByteArray, const style::color*>{
|
||||
{ "shadow-fg", &st::shadowFg },
|
||||
{ "scroll-bg", &st::scrollBg },
|
||||
@ -85,7 +224,7 @@ namespace {
|
||||
static const auto phrases = base::flat_map<QByteArray, tr::phrase<>>{
|
||||
{ "iv-join-channel", tr::lng_iv_join_channel },
|
||||
};
|
||||
return Ui::ComputeStyles(map, phrases)
|
||||
return Ui::ComputeStyles(map, phrases, zoom)
|
||||
+ ';'
|
||||
+ Ui::ComputeSemiTransparentOverStyle(
|
||||
"light-button-bg-over",
|
||||
@ -93,7 +232,7 @@ namespace {
|
||||
st::windowBg);
|
||||
}
|
||||
|
||||
[[nodiscard]] QByteArray WrapPage(const Prepared &page) {
|
||||
[[nodiscard]] QByteArray WrapPage(const Prepared &page, int zoom) {
|
||||
#ifdef Q_OS_MAC
|
||||
const auto classAttribute = ""_q;
|
||||
#else // Q_OS_MAC
|
||||
@ -110,7 +249,7 @@ namespace {
|
||||
<html)"_q
|
||||
+ classAttribute
|
||||
+ R"( style=")"
|
||||
+ Ui::EscapeForAttribute(ComputeStyles())
|
||||
+ Ui::EscapeForAttribute(ComputeStyles(zoom))
|
||||
+ R"(">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
@ -206,7 +345,8 @@ Controller::Controller(
|
||||
Fn<ShareBoxResult(ShareBoxDescriptor)> showShareBox)
|
||||
: _delegate(delegate)
|
||||
, _updateStyles([=] {
|
||||
const auto str = Ui::EscapeForScriptString(ComputeStyles());
|
||||
const auto zoom = _delegate->ivZoom();
|
||||
const auto str = Ui::EscapeForScriptString(ComputeStyles(zoom));
|
||||
if (_webview) {
|
||||
_webview->eval("IV.updateStyles('" + str + "');");
|
||||
}
|
||||
@ -484,6 +624,16 @@ void Controller::createWebview(const Webview::StorageId &storageId) {
|
||||
if (event->key() == Qt::Key_Escape) {
|
||||
escape();
|
||||
}
|
||||
if (event->modifiers() & Qt::ControlModifier) {
|
||||
if (event->key() == Qt::Key_Plus
|
||||
|| event->key() == Qt::Key_Equal) {
|
||||
_delegate->ivSetZoom(_delegate->ivZoom() + kZoomStep);
|
||||
} else if (event->key() == Qt::Key_Minus) {
|
||||
_delegate->ivSetZoom(_delegate->ivZoom() - kZoomStep);
|
||||
} else if (event->key() == Qt::Key_0) {
|
||||
_delegate->ivSetZoom(kDefaultZoom);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, window->lifetime());
|
||||
|
||||
@ -595,7 +745,8 @@ void Controller::createWebview(const Webview::StorageId &storageId) {
|
||||
|
||||
rpl::merge(
|
||||
Lang::Updated(),
|
||||
style::PaletteChanged()
|
||||
style::PaletteChanged(),
|
||||
_delegate->ivZoomValue() | rpl::to_empty
|
||||
) | rpl::start_with_next([=] {
|
||||
_updateStyles.call();
|
||||
}, _webview->lifetime());
|
||||
@ -611,7 +762,8 @@ void Controller::createWebview(const Webview::StorageId &storageId) {
|
||||
return Webview::DataResult::Failed;
|
||||
}
|
||||
return finishWith(
|
||||
WrapPage(_pages[index]), "text/html; charset=utf-8");
|
||||
WrapPage(_pages[index], _delegate->ivZoom()),
|
||||
"text/html; charset=utf-8");
|
||||
} else if (id.starts_with("page") && id.ends_with(".json")) {
|
||||
auto index = 0;
|
||||
const auto result = std::from_chars(
|
||||
@ -897,6 +1049,10 @@ void Controller::showMenu() {
|
||||
showShareMenu();
|
||||
}, &st::menuIconShare);
|
||||
|
||||
_menu->addSeparator();
|
||||
_menu->addAction(
|
||||
base::make_unique_q<ItemZoom>(_menu, _delegate, _menu->menu()->st()));
|
||||
|
||||
_menu->setForcedOrigin(Ui::PanelAnimation::Origin::TopRight);
|
||||
_menu->popup(_window->body()->mapToGlobal(
|
||||
QPoint(_window->body()->width(), 0) + st::ivMenuPosition));
|
||||
|
@ -18,6 +18,10 @@ public:
|
||||
virtual void ivSetLastSourceWindow(not_null<QWidget*> window) = 0;
|
||||
[[nodiscard]] virtual QRect ivGeometry() const = 0;
|
||||
virtual void ivSaveGeometry(not_null<Ui::RpWindow*> window) = 0;
|
||||
|
||||
[[nodiscard]] virtual int ivZoom() const = 0;
|
||||
[[nodiscard]] virtual rpl::producer<int> ivZoomValue() const = 0;
|
||||
virtual void ivSetZoom(int value) = 0;
|
||||
};
|
||||
|
||||
} // namespace Iv
|
||||
|
@ -117,4 +117,15 @@ void DelegateImpl::ivSaveGeometry(not_null<Ui::RpWindow*> window) {
|
||||
}
|
||||
}
|
||||
|
||||
int DelegateImpl::ivZoom() const {
|
||||
return Core::App().settings().ivZoom();
|
||||
}
|
||||
rpl::producer<int> DelegateImpl::ivZoomValue() const {
|
||||
return Core::App().settings().ivZoomValue();
|
||||
}
|
||||
void DelegateImpl::ivSetZoom(int value) {
|
||||
Core::App().settings().setIvZoom(value);
|
||||
Core::App().saveSettingsDelayed();
|
||||
}
|
||||
|
||||
} // namespace Iv
|
||||
|
@ -19,6 +19,10 @@ public:
|
||||
[[nodiscard]] QRect ivGeometry() const override;
|
||||
void ivSaveGeometry(not_null<Ui::RpWindow*> window) override;
|
||||
|
||||
[[nodiscard]] int ivZoom() const;
|
||||
[[nodiscard]] rpl::producer<int> ivZoomValue() const;
|
||||
void ivSetZoom(int value);
|
||||
|
||||
private:
|
||||
QPointer<QWidget> _lastSourceWindow;
|
||||
|
||||
|
@ -379,7 +379,7 @@ void VenuesController::rowPaintIcon(
|
||||
static const auto phrases = base::flat_map<QByteArray, tr::phrase<>>{
|
||||
{ "maps-places-in-area", tr::lng_maps_places_in_area },
|
||||
};
|
||||
return Ui::ComputeStyles(map, phrases, Window::Theme::IsNightMode());
|
||||
return Ui::ComputeStyles(map, phrases, 100, Window::Theme::IsNightMode());
|
||||
}
|
||||
|
||||
[[nodiscard]] QByteArray ReadResource(const QString &name) {
|
||||
|
@ -31,6 +31,7 @@ namespace {
|
||||
QByteArray ComputeStyles(
|
||||
const base::flat_map<QByteArray, const style::color*> &colors,
|
||||
const base::flat_map<QByteArray, tr::phrase<>> &phrases,
|
||||
int zoom,
|
||||
bool nightTheme) {
|
||||
static const auto serialize = [](const style::color *color) {
|
||||
return Serialize((*color)->c);
|
||||
@ -66,6 +67,9 @@ QByteArray ComputeStyles(
|
||||
result += "--td-"_q + name + ':' + serialize(color) + ';';
|
||||
}
|
||||
result += "--td-night:"_q + (nightTheme ? "1" : "0") + ';';
|
||||
result += "--td-zoom-percentage:"_q
|
||||
+ (QString::number(zoom).toUtf8() + '%')
|
||||
+ ';';
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ namespace Ui {
|
||||
[[nodiscard]] QByteArray ComputeStyles(
|
||||
const base::flat_map<QByteArray, const style::color*> &colors,
|
||||
const base::flat_map<QByteArray, tr::phrase<>> &phrases,
|
||||
int zoom,
|
||||
bool nightTheme = false);
|
||||
[[nodiscard]] QByteArray ComputeSemiTransparentOverStyle(
|
||||
const QByteArray &name,
|
||||
|
Loading…
Reference in New Issue
Block a user