Handle emoji myself in custom macOS title.
This commit is contained in:
parent
37531086ec
commit
bfdd116000
12 changed files with 74 additions and 28 deletions
|
|
@ -28,6 +28,8 @@ public:
|
|||
void setGeometry(QRect rect) override;
|
||||
void close() override;
|
||||
|
||||
const style::TextStyle &titleTextStyle() const override;
|
||||
|
||||
private:
|
||||
class Private;
|
||||
friend class Private;
|
||||
|
|
|
|||
|
|
@ -422,6 +422,10 @@ void WindowHelper::close() {
|
|||
_private->close();
|
||||
}
|
||||
|
||||
const style::TextStyle &WindowHelper::titleTextStyle() const {
|
||||
return _title->textStyle();
|
||||
}
|
||||
|
||||
void WindowHelper::init() {
|
||||
updateCustomTitleVisibility(true);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
#pragma once
|
||||
|
||||
#include "ui/text/text.h"
|
||||
#include "ui/rp_widget.h"
|
||||
#include "base/object_ptr.h"
|
||||
|
||||
|
|
@ -14,6 +15,7 @@
|
|||
|
||||
namespace style {
|
||||
struct WindowTitle;
|
||||
struct TextStyle;
|
||||
} // namespace style
|
||||
|
||||
namespace Ui {
|
||||
|
|
@ -25,12 +27,14 @@ namespace Platform {
|
|||
class TitleWidget : public RpWidget {
|
||||
public:
|
||||
TitleWidget(not_null<RpWidget*> parent, int height);
|
||||
~TitleWidget();
|
||||
|
||||
void setText(const QString &text);
|
||||
void setStyle(const style::WindowTitle &st);
|
||||
void setControlsRect(const QRect &rect);
|
||||
[[nodiscard]] QString text() const;
|
||||
[[nodiscard]] bool shouldBeHidden() const;
|
||||
[[nodiscard]] const style::TextStyle &textStyle() const;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
|
@ -43,11 +47,11 @@ private:
|
|||
void init(int height);
|
||||
|
||||
not_null<const style::WindowTitle*> _st;
|
||||
std::unique_ptr<style::TextStyle> _textStyle;
|
||||
object_ptr<Ui::PlainShadow> _shadow;
|
||||
QString _text;
|
||||
int _textWidth = 0;
|
||||
Ui::Text::String _string;
|
||||
int _controlsRight = 0;
|
||||
QFont _font;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "base/debug_log.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
|
@ -27,10 +28,12 @@ TitleWidget::TitleWidget(not_null<RpWidget*> parent, int height)
|
|||
init(height);
|
||||
}
|
||||
|
||||
TitleWidget::~TitleWidget() = default;
|
||||
|
||||
void TitleWidget::setText(const QString &text) {
|
||||
if (_text != text) {
|
||||
_text = text;
|
||||
_textWidth = QFontMetrics(_font).horizontalAdvance(_text);
|
||||
_string.setText(textStyle(), text);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
|
@ -48,6 +51,10 @@ bool TitleWidget::shouldBeHidden() const {
|
|||
return !_st->height;
|
||||
}
|
||||
|
||||
const style::TextStyle &TitleWidget::textStyle() const {
|
||||
return *_textStyle;
|
||||
}
|
||||
|
||||
QString TitleWidget::text() const {
|
||||
return _text;
|
||||
}
|
||||
|
|
@ -64,51 +71,55 @@ void TitleWidget::init(int height) {
|
|||
setGeometry(0, 0, width, height);
|
||||
}, lifetime());
|
||||
|
||||
const auto setFromFont = [&](const style::font &font) {
|
||||
_textStyle = std::make_unique<style::TextStyle>(style::TextStyle{
|
||||
.font = font,
|
||||
.linkFont = font,
|
||||
.linkFontOver = font,
|
||||
});
|
||||
};
|
||||
|
||||
const auto families = QStringList{
|
||||
u".AppleSystemUIFont"_q,
|
||||
u".SF NS Text"_q,
|
||||
u"Helvetica Neue"_q,
|
||||
};
|
||||
for (auto family : families) {
|
||||
_font.setFamily(family);
|
||||
if (QFontInfo(_font).family() == _font.family()) {
|
||||
auto font = QFont();
|
||||
font.setFamily(family);
|
||||
if (QFontInfo(font).family() == font.family()) {
|
||||
static const auto logged = [&] {
|
||||
LOG(("Title Font: %1").arg(family));
|
||||
return true;
|
||||
}();
|
||||
const auto apple = (family == u".AppleSystemUIFont"_q);
|
||||
setFromFont(style::font(
|
||||
apple ? 13 : (height * 15) / 24,
|
||||
apple ? style::internal::FontBold : 0,
|
||||
family));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (QFontInfo(_font).family() != _font.family()) {
|
||||
_font = st::semiboldFont;
|
||||
_font.setPixelSize(13);
|
||||
} else if (_font.family() == u".AppleSystemUIFont"_q) {
|
||||
_font.setBold(true);
|
||||
_font.setPixelSize(13);
|
||||
} else {
|
||||
_font.setPixelSize((height * 15) / 24);
|
||||
if (!_textStyle) {
|
||||
setFromFont(style::font(13, style::internal::FontSemibold, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void TitleWidget::paintEvent(QPaintEvent *e) {
|
||||
QPainter p(this);
|
||||
Painter p(this);
|
||||
|
||||
const auto active = isActiveWindow();
|
||||
p.fillRect(rect(), active ? _st->bgActive : _st->bg);
|
||||
|
||||
p.setFont(_font);
|
||||
p.setPen(active ? _st->fgActive : _st->fg);
|
||||
|
||||
if ((width() - _controlsRight * 2) < _textWidth) {
|
||||
const auto elided = QFontMetrics(_font).elidedText(
|
||||
_text,
|
||||
Qt::ElideRight,
|
||||
width() - _controlsRight);
|
||||
const auto padding = QMargins(_controlsRight, 0, 0, 0);
|
||||
p.drawText(rect() - padding, elided, style::al_left);
|
||||
const auto top = (height() - _textStyle->font->height) / 2;
|
||||
if ((width() - _controlsRight * 2) < _string.maxWidth()) {
|
||||
const auto left = _controlsRight;
|
||||
_string.drawElided(p, left, top, width() - left);
|
||||
} else {
|
||||
p.drawText(rect(), _text, style::al_center);
|
||||
const auto left = (width() - _string.maxWidth()) / 2;
|
||||
_string.draw(p, left, top, width() - left);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -205,6 +205,10 @@ void BasicWindowHelper::setBodyTitleArea(
|
|||
_bodyTitleAreaTestMethod = std::move(testMethod);
|
||||
}
|
||||
|
||||
const style::TextStyle &BasicWindowHelper::titleTextStyle() const {
|
||||
return st::defaultWindowTitle.style;
|
||||
}
|
||||
|
||||
QMargins BasicWindowHelper::nativeFrameMargins() const {
|
||||
const auto inner = window()->geometry();
|
||||
const auto outer = window()->frameGeometry();
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
namespace style {
|
||||
struct WindowTitle;
|
||||
struct TextStyle;
|
||||
} // namespace style
|
||||
|
||||
namespace Ui {
|
||||
|
|
@ -62,6 +63,8 @@ public:
|
|||
virtual int manualRoundingRadius() const;
|
||||
void setBodyTitleArea(Fn<WindowTitleHitTestFlags(QPoint)> testMethod);
|
||||
|
||||
[[nodiscard]] virtual const style::TextStyle &titleTextStyle() const;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] WindowTitleHitTestFlags bodyTitleAreaHit(
|
||||
QPoint point) const {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ void SetCustomFonts(const CustomFont ®ular, const CustomFont &bold) {
|
|||
BoldFont = bold;
|
||||
}
|
||||
|
||||
QFont ResolveFont(uint32 flags, int size) {
|
||||
QFont ResolveFont(const QString &familyOverride, uint32 flags, int size) {
|
||||
static auto Database = QFontDatabase();
|
||||
|
||||
const auto bold = ((flags & FontBold) || (flags & FontSemibold));
|
||||
|
|
@ -35,7 +35,12 @@ QFont ResolveFont(uint32 flags, int size) {
|
|||
const auto useCustom = !custom.family.isEmpty();
|
||||
|
||||
auto result = QFont(QGuiApplication::font().family());
|
||||
if (flags & FontMonospace) {
|
||||
if (!familyOverride.isEmpty()) {
|
||||
result.setFamily(familyOverride);
|
||||
if (bold) {
|
||||
result.setBold(true);
|
||||
}
|
||||
} else if (flags & FontMonospace) {
|
||||
result.setFamily(MonospaceFont());
|
||||
} else if (useCustom) {
|
||||
const auto sizes = Database.smoothSizes(custom.family, custom.style);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,6 @@ inline bool operator>=(const CustomFont &a, const CustomFont &b) {
|
|||
|
||||
void SetCustomFonts(const CustomFont ®ular, const CustomFont &bold);
|
||||
|
||||
[[nodiscard]] QFont ResolveFont(uint32 flags, int size);
|
||||
[[nodiscard]] QFont ResolveFont(const QString &familyOverride, uint32 flags, int size);
|
||||
|
||||
} // namespace style
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ int CeilTextWidth(const QFont &font, const QString &text) {
|
|||
}
|
||||
|
||||
FontData::FontData(int size, uint32 flags, int family, Font *other)
|
||||
: f(ResolveFont(flags, size))
|
||||
: f(ResolveFont(family ? fontFamilies[family] : QString(), flags, size))
|
||||
, _m(f)
|
||||
, _size(size)
|
||||
, _flags(flags)
|
||||
|
|
|
|||
|
|
@ -103,4 +103,8 @@ int RpWindow::manualRoundingRadius() const {
|
|||
return _helper->manualRoundingRadius();
|
||||
}
|
||||
|
||||
const style::TextStyle &RpWindow::titleTextStyle() const {
|
||||
return _helper->titleTextStyle();
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace style {
|
||||
struct WindowTitle;
|
||||
struct TextStyle;
|
||||
} // namespace style
|
||||
|
||||
namespace Ui {
|
||||
|
|
@ -68,6 +69,8 @@ public:
|
|||
[[nodiscard]] int manualRoundingRadius() const;
|
||||
void setBodyTitleArea(Fn<WindowTitleHitTestFlags(QPoint)> testMethod);
|
||||
|
||||
[[nodiscard]] const style::TextStyle &titleTextStyle() const;
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Platform::BasicWindowHelper> _helper;
|
||||
|
||||
|
|
|
|||
|
|
@ -555,6 +555,7 @@ WindowTitle {
|
|||
bgActive: color;
|
||||
fg: color;
|
||||
fgActive: color;
|
||||
style: TextStyle;
|
||||
minimize: IconButton;
|
||||
minimizeIconActive: icon;
|
||||
minimizeIconActiveOver: icon;
|
||||
|
|
@ -1420,6 +1421,11 @@ defaultWindowTitle: WindowTitle {
|
|||
bgActive: titleBgActive;
|
||||
fg: titleFg;
|
||||
fgActive: titleFgActive;
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(semibold 12px);
|
||||
linkFont: font(semibold 12px);
|
||||
linkFontOver: font(semibold 12px underline);
|
||||
}
|
||||
minimize: IconButton(windowTitleButton) {
|
||||
icon: icon {
|
||||
{ windowTitleButtonSize, titleButtonBg },
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue