Allow different styles for box layers.
This commit is contained in:
parent
41bae1eba6
commit
7287e235e0
13 changed files with 205 additions and 31 deletions
|
|
@ -555,6 +555,7 @@ callHangupRipple: #c04646; // phone call popup hangup button ripple effect
|
|||
callMuteRipple: #ffffff12; // phone call popup mute mic and camera ripple effect
|
||||
|
||||
groupCallBg: #131417; // group call popup background
|
||||
groupCallActiveFg: #4db8ff; // group call active controls text
|
||||
groupCallMembersBg: #1a1c1f; // group call members list background
|
||||
groupCallMembersFg: #ffffff; // group call member name text
|
||||
groupCallMembersRipple: #22252a; // group call member row ripple effect
|
||||
|
|
@ -569,6 +570,8 @@ groupCallLive1: #0dcc39; // group call live button color1
|
|||
groupCallLive2: #0bb6bd; // group call live button color2
|
||||
groupCallMuted1: #0992ef; // group call muted button color1
|
||||
groupCallMuted2: #16ccfb; // group call muted button color2
|
||||
groupCallBoxButtonBgOver: #1d2a39; // group call button in box with mouse over
|
||||
groupCallBoxButtonBgRipple: #223143; // group call button in box ripple effect
|
||||
|
||||
callBarBg: dialogsBgActive; // active phone call bar background
|
||||
callBarMuteRipple: dialogsRippleBgActive; // active phone call bar mute and hangup button ripple effect
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ QPointer<RoundButton> BoxContent::addButton(
|
|||
return addButton(
|
||||
std::move(text),
|
||||
std::move(clickCallback),
|
||||
st::defaultBoxButton);
|
||||
getDelegate()->style().button);
|
||||
}
|
||||
|
||||
QPointer<RoundButton> BoxContent::addLeftButton(
|
||||
|
|
@ -38,7 +38,7 @@ QPointer<RoundButton> BoxContent::addLeftButton(
|
|||
return getDelegate()->addLeftButton(
|
||||
std::move(text),
|
||||
std::move(clickCallback),
|
||||
st::defaultBoxButton);
|
||||
getDelegate()->style().button);
|
||||
}
|
||||
|
||||
void BoxContent::setInner(object_ptr<TWidget> inner) {
|
||||
|
|
@ -245,8 +245,9 @@ void BoxContent::paintEvent(QPaintEvent *e) {
|
|||
Painter p(this);
|
||||
|
||||
if (testAttribute(Qt::WA_OpaquePaintEvent)) {
|
||||
const auto &color = getDelegate()->style().bg;
|
||||
for (const auto rect : e->region()) {
|
||||
p.fillRect(rect, st::boxBg);
|
||||
p.fillRect(rect, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ class BoxContentDelegate {
|
|||
public:
|
||||
virtual void setLayerType(bool layerType) = 0;
|
||||
virtual void setStyle(const style::Box &st) = 0;
|
||||
virtual const style::Box &style() = 0;
|
||||
virtual void setTitle(rpl::producer<TextWithEntities> title) = 0;
|
||||
virtual void setAdditionalTitle(rpl::producer<QString> additional) = 0;
|
||||
virtual void setCloseByOutsideClick(bool close) = 0;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ BoxLayerWidget::BoxLayerWidget(
|
|||
: LayerWidget(layer)
|
||||
, _layer(layer)
|
||||
, _content(std::move(content))
|
||||
, _roundRect(ImageRoundRadius::Small, st::boxBg) {
|
||||
, _roundRect(ImageRoundRadius::Small, st().bg) {
|
||||
_content->setParent(this);
|
||||
_content->setDelegate(this);
|
||||
|
||||
|
|
@ -74,12 +74,21 @@ const style::Box &BoxLayerWidget::st() const {
|
|||
return _st
|
||||
? *_st
|
||||
: _layerType
|
||||
? st::layerBox
|
||||
: st::defaultBox;
|
||||
? (_layer->boxStyleOverrideLayer()
|
||||
? *_layer->boxStyleOverrideLayer()
|
||||
: st::layerBox)
|
||||
: (_layer->boxStyleOverride()
|
||||
? *_layer->boxStyleOverride()
|
||||
: st::defaultBox);
|
||||
}
|
||||
|
||||
void BoxLayerWidget::setStyle(const style::Box &st) {
|
||||
_st = &st;
|
||||
_roundRect.setColor(st.bg);
|
||||
}
|
||||
|
||||
const style::Box &BoxLayerWidget::style() {
|
||||
return st();
|
||||
}
|
||||
|
||||
int BoxLayerWidget::buttonsHeight() const {
|
||||
|
|
@ -118,7 +127,7 @@ void BoxLayerWidget::paintEvent(QPaintEvent *e) {
|
|||
auto other = e->region().intersected(QRect(0, st::boxRadius, width(), height() - 2 * st::boxRadius));
|
||||
if (!other.isEmpty()) {
|
||||
for (const auto rect : other) {
|
||||
p.fillRect(rect, st::boxBg);
|
||||
p.fillRect(rect, st().bg);
|
||||
}
|
||||
}
|
||||
if (!_additionalTitle.current().isEmpty()
|
||||
|
|
@ -137,21 +146,29 @@ void BoxLayerWidget::paintEvent(QPaintEvent *e) {
|
|||
|
||||
void BoxLayerWidget::paintAdditionalTitle(Painter &p) {
|
||||
p.setFont(st::boxTitleAdditionalFont);
|
||||
p.setPen(st::boxTitleAdditionalFg);
|
||||
p.drawTextLeft(_titleLeft + (_title ? _title->width() : 0) + st::boxTitleAdditionalSkip, _titleTop + st::boxTitleFont->ascent - st::boxTitleAdditionalFont->ascent, width(), _additionalTitle.current());
|
||||
p.setPen(st().titleAdditionalFg);
|
||||
p.drawTextLeft(
|
||||
_titleLeft + (_title ? _title->width() : 0) + st::boxTitleAdditionalSkip,
|
||||
_titleTop + st::boxTitleFont->ascent - st::boxTitleAdditionalFont->ascent,
|
||||
width(),
|
||||
_additionalTitle.current());
|
||||
}
|
||||
|
||||
void BoxLayerWidget::parentResized() {
|
||||
auto newHeight = countRealHeight();
|
||||
auto parentSize = parentWidget()->size();
|
||||
setGeometry((parentSize.width() - width()) / 2, (parentSize.height() - newHeight) / 2, width(), newHeight);
|
||||
setGeometry(
|
||||
(parentSize.width() - width()) / 2,
|
||||
(parentSize.height() - newHeight) / 2,
|
||||
width(),
|
||||
newHeight);
|
||||
update();
|
||||
}
|
||||
|
||||
void BoxLayerWidget::setTitle(rpl::producer<TextWithEntities> title) {
|
||||
const auto wasTitle = hasTitle();
|
||||
if (title) {
|
||||
_title.create(this, rpl::duplicate(title), st::boxTitle);
|
||||
_title.create(this, rpl::duplicate(title), st().title);
|
||||
_title->show();
|
||||
std::move(
|
||||
title
|
||||
|
|
@ -323,9 +340,10 @@ void BoxLayerWidget::setDimensions(int newWidth, int maxHeight, bool forceCenter
|
|||
resize(newWidth, countRealHeight());
|
||||
auto newGeometry = geometry();
|
||||
auto parentHeight = parentWidget()->height();
|
||||
if (newGeometry.top() + newGeometry.height() + st::boxVerticalMargin > parentHeight
|
||||
const auto bottomMargin = st().margin.bottom();
|
||||
if (newGeometry.top() + newGeometry.height() + bottomMargin > parentHeight
|
||||
|| forceCenterPosition) {
|
||||
const auto top1 = parentHeight - int(st::boxVerticalMargin) - newGeometry.height();
|
||||
const auto top1 = parentHeight - bottomMargin - newGeometry.height();
|
||||
const auto top2 = (parentHeight - newGeometry.height()) / 2;
|
||||
const auto newTop = forceCenterPosition
|
||||
? std::min(top1, top2)
|
||||
|
|
@ -343,7 +361,10 @@ void BoxLayerWidget::setDimensions(int newWidth, int maxHeight, bool forceCenter
|
|||
}
|
||||
|
||||
int BoxLayerWidget::countRealHeight() const {
|
||||
return qMin(_fullHeight, parentWidget()->height() - 2 * st::boxVerticalMargin);
|
||||
const auto &margin = st().margin;
|
||||
return std::min(
|
||||
_fullHeight,
|
||||
parentWidget()->height() - margin.top() - margin.bottom());
|
||||
}
|
||||
|
||||
int BoxLayerWidget::countFullHeight() const {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ public:
|
|||
|
||||
void setLayerType(bool layerType) override;
|
||||
void setStyle(const style::Box &st) override;
|
||||
const style::Box &style() override;
|
||||
void setTitle(rpl::producer<TextWithEntities> title) override;
|
||||
void setAdditionalTitle(rpl::producer<QString> additional) override;
|
||||
void showBox(
|
||||
|
|
|
|||
|
|
@ -11,6 +11,16 @@ namespace Ui {
|
|||
LayerManager::LayerManager(not_null<RpWidget*> widget) : _widget(widget) {
|
||||
}
|
||||
|
||||
void LayerManager::setStyleOverrides(
|
||||
const style::Box *boxSt,
|
||||
const style::Box *layerSt) {
|
||||
_boxSt = boxSt;
|
||||
_layerSt = layerSt;
|
||||
if (_layer) {
|
||||
_layer->setStyleOverrides(_boxSt, _layerSt);
|
||||
}
|
||||
}
|
||||
|
||||
void LayerManager::setHideByBackgroundClick(bool hide) {
|
||||
_hideByBackgroundClick = hide;
|
||||
if (_layer) {
|
||||
|
|
@ -55,6 +65,7 @@ void LayerManager::ensureLayerCreated() {
|
|||
}
|
||||
_layer.emplace(_widget);
|
||||
_layer->setHideByBackgroundClick(_hideByBackgroundClick);
|
||||
_layer->setStyleOverrides(_boxSt, _layerSt);
|
||||
|
||||
_layer->hideFinishEvents(
|
||||
) | rpl::filter([=] {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@
|
|||
|
||||
#include <QtCore/QMargins>
|
||||
|
||||
namespace style {
|
||||
struct Box;
|
||||
} // namespace style
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class BoxContent;
|
||||
|
|
@ -19,6 +23,10 @@ class LayerManager final {
|
|||
public:
|
||||
explicit LayerManager(not_null<RpWidget*> widget);
|
||||
|
||||
void setStyleOverrides(
|
||||
const style::Box *boxSt,
|
||||
const style::Box *layerSt);
|
||||
|
||||
void setHideByBackgroundClick(bool hide);
|
||||
void showBox(
|
||||
object_ptr<BoxContent> box,
|
||||
|
|
@ -34,6 +42,9 @@ private:
|
|||
|
||||
const not_null<RpWidget*> _widget;
|
||||
base::unique_qptr<LayerStackWidget> _layer;
|
||||
|
||||
const style::Box *_boxSt = nullptr;
|
||||
const style::Box *_layerSt = nullptr;
|
||||
bool _hideByBackgroundClick = false;
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -458,6 +458,13 @@ bool LayerStackWidget::layerShown() const {
|
|||
return _specialLayer || currentLayer() || _mainMenu;
|
||||
}
|
||||
|
||||
void LayerStackWidget::setStyleOverrides(
|
||||
const style::Box *boxSt,
|
||||
const style::Box *layerSt) {
|
||||
_boxSt = boxSt;
|
||||
_layerSt = layerSt;
|
||||
}
|
||||
|
||||
void LayerStackWidget::setCacheImages() {
|
||||
auto bodyCache = QPixmap(), mainMenuCache = QPixmap();
|
||||
auto specialLayerCache = QPixmap();
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ class SectionMemento;
|
|||
struct SectionShow;
|
||||
} // namespace Window
|
||||
|
||||
namespace style {
|
||||
struct Box;
|
||||
} // namespace style
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class BoxContent;
|
||||
|
|
@ -93,6 +97,16 @@ public:
|
|||
void finishAnimating();
|
||||
rpl::producer<> hideFinishEvents() const;
|
||||
|
||||
void setStyleOverrides(
|
||||
const style::Box *boxSt,
|
||||
const style::Box *layerSt);
|
||||
[[nodiscard]] const style::Box *boxStyleOverrideLayer() const {
|
||||
return _layerSt;
|
||||
}
|
||||
[[nodiscard]] const style::Box *boxStyleOverride() const {
|
||||
return _boxSt;
|
||||
}
|
||||
|
||||
void showBox(
|
||||
object_ptr<BoxContent> box,
|
||||
LayerOptions options,
|
||||
|
|
@ -201,6 +215,9 @@ private:
|
|||
|
||||
class BackgroundWidget;
|
||||
object_ptr<BackgroundWidget> _background;
|
||||
|
||||
const style::Box *_boxSt = nullptr;
|
||||
const style::Box *_layerSt = nullptr;
|
||||
bool _hideByBackgroundClick = true;
|
||||
|
||||
rpl::event_stream<> _hideFinishStream;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@ ServiceCheck {
|
|||
Box {
|
||||
buttonPadding: margins;
|
||||
buttonHeight: pixels;
|
||||
button: RoundButton;
|
||||
margin: margins;
|
||||
title: FlatLabel;
|
||||
bg: color;
|
||||
titleAdditionalFg: color;
|
||||
}
|
||||
|
||||
boxDuration: 200;
|
||||
|
|
@ -36,12 +41,6 @@ defaultBoxButton: RoundButton(defaultLightButton) {
|
|||
font: boxButtonFont;
|
||||
}
|
||||
|
||||
boxTextStyle: TextStyle(defaultTextStyle) {
|
||||
font: font(boxFontSize);
|
||||
linkFont: font(boxFontSize);
|
||||
linkFontOver: font(boxFontSize underline);
|
||||
}
|
||||
|
||||
boxLabelStyle: TextStyle(boxTextStyle) {
|
||||
lineHeight: 22px;
|
||||
}
|
||||
|
|
@ -118,7 +117,6 @@ boxOptionListPadding: margins(0px, 0px, 0px, 0px);
|
|||
boxOptionListSkip: 20px;
|
||||
boxOptionInputSkip: 6px;
|
||||
|
||||
boxVerticalMargin: 10px;
|
||||
boxWidth: 320px;
|
||||
boxWideWidth: 364px;
|
||||
boxPadding: margins(22px, 30px, 22px, 8px);
|
||||
|
|
@ -129,6 +127,11 @@ boxMediumSkip: 20px;
|
|||
defaultBox: Box {
|
||||
buttonPadding: margins(8px, 12px, 13px, 12px);
|
||||
buttonHeight: 36px;
|
||||
button: defaultBoxButton;
|
||||
margin: margins(0px, 10px, 0px, 10px);
|
||||
bg: boxBg;
|
||||
title: boxTitle;
|
||||
titleAdditionalFg: boxTitleAdditionalFg;
|
||||
}
|
||||
layerBox: Box(defaultBox) {
|
||||
buttonPadding: margins(8px, 8px, 8px, 8px);
|
||||
|
|
|
|||
|
|
@ -67,22 +67,25 @@ RoundRect::RoundRect(
|
|||
ImageRoundRadius radius,
|
||||
const style::color &color)
|
||||
: _color(color)
|
||||
, _corners(Images::PrepareCorners(radius, color)) {
|
||||
, _refresh([=] { _corners = Images::PrepareCorners(radius, _color); }) {
|
||||
_refresh();
|
||||
style::PaletteChanged(
|
||||
) | rpl::start_with_next([=] {
|
||||
_corners = Images::PrepareCorners(radius, _color);
|
||||
}, _lifetime);
|
||||
) | rpl::start_with_next(_refresh, _lifetime);
|
||||
}
|
||||
|
||||
RoundRect::RoundRect(
|
||||
int radius,
|
||||
const style::color &color)
|
||||
: _color(color)
|
||||
, _corners(Images::PrepareCorners(radius, color)) {
|
||||
, _refresh([=] { _corners = Images::PrepareCorners(radius, _color); }) {
|
||||
_refresh();
|
||||
style::PaletteChanged(
|
||||
) | rpl::start_with_next([=] {
|
||||
_corners = Images::PrepareCorners(radius, _color);
|
||||
}, _lifetime);
|
||||
) | rpl::start_with_next(_refresh, _lifetime);
|
||||
}
|
||||
|
||||
void RoundRect::setColor(const style::color &color) {
|
||||
_color = color;
|
||||
_refresh();
|
||||
}
|
||||
|
||||
const style::color &RoundRect::color() const {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ public:
|
|||
RoundRect(int radius, const style::color &color);
|
||||
|
||||
[[nodiscard]] const style::color &color() const;
|
||||
void setColor(const style::color &color);
|
||||
void paint(
|
||||
QPainter &p,
|
||||
const QRect &rect,
|
||||
|
|
@ -39,6 +40,7 @@ public:
|
|||
private:
|
||||
style::color _color;
|
||||
std::array<QImage, 4> _corners;
|
||||
Fn<void()> _refresh;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
|
|
|
|||
|
|
@ -495,6 +495,7 @@ SettingsButton {
|
|||
textBgOver: color;
|
||||
|
||||
font: font;
|
||||
rightLabel: FlatLabel;
|
||||
|
||||
height: pixels;
|
||||
padding: margins;
|
||||
|
|
@ -780,6 +781,7 @@ defaultToggle: Toggle {
|
|||
}
|
||||
defaultCheckbox: Checkbox {
|
||||
textFg: windowFg;
|
||||
textFgActive: windowFg;
|
||||
|
||||
width: -44px;
|
||||
margin: margins(8px, 8px, 8px, 8px);
|
||||
|
|
@ -821,12 +823,76 @@ defaultMultiSelectItem: MultiSelectItem {
|
|||
minScale: 0.3;
|
||||
}
|
||||
|
||||
widgetSlideDuration: 200;
|
||||
widgetFadeDuration: 200;
|
||||
defaultMultiSelectSearchField: InputField(defaultInputField) {
|
||||
textBg: transparent;
|
||||
textMargins: margins(2px, 7px, 2px, 0px);
|
||||
|
||||
placeholderFg: placeholderFg;
|
||||
placeholderFgActive: placeholderFgActive;
|
||||
placeholderFgError: placeholderFgActive;
|
||||
placeholderMargins: margins(2px, 0px, 2px, 0px);
|
||||
placeholderScale: 0.;
|
||||
placeholderFont: normalFont;
|
||||
|
||||
border: 0px;
|
||||
borderActive: 0px;
|
||||
|
||||
heightMin: 32px;
|
||||
|
||||
font: normalFont;
|
||||
}
|
||||
|
||||
fieldSearchIcon: icon {{ "box_search", menuIconFg, point(9px, 8px) }};
|
||||
boxFieldSearchIcon: icon {{ "box_search", menuIconFg, point(10px, 9px) }};
|
||||
|
||||
defaultMultiSelectSearchCancel: CrossButton {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
|
||||
cross: CrossAnimation {
|
||||
size: 36px;
|
||||
skip: 12px;
|
||||
stroke: 2px;
|
||||
minScale: 0.3;
|
||||
}
|
||||
crossFg: boxTitleCloseFg;
|
||||
crossFgOver: boxTitleCloseFgOver;
|
||||
crossPosition: point(4px, 4px);
|
||||
|
||||
duration: 150;
|
||||
loadingPeriod: 1000;
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: windowBgOver;
|
||||
}
|
||||
}
|
||||
defaultMultiSelect: MultiSelect {
|
||||
bg: boxSearchBg;
|
||||
padding: margins(8px, 6px, 8px, 6px);
|
||||
maxHeight: 104px;
|
||||
scroll: ScrollArea(defaultSolidScroll) {
|
||||
deltat: 3px;
|
||||
deltab: 3px;
|
||||
round: 1px;
|
||||
width: 8px;
|
||||
deltax: 3px;
|
||||
hiding: 1000;
|
||||
}
|
||||
|
||||
item: defaultMultiSelectItem;
|
||||
itemSkip: 8px;
|
||||
|
||||
field: defaultMultiSelectSearchField;
|
||||
fieldMinWidth: 42px;
|
||||
fieldIcon: boxFieldSearchIcon;
|
||||
fieldIconSkip: 36px;
|
||||
|
||||
fieldCancel: defaultMultiSelectSearchCancel;
|
||||
fieldCancelSkip: 40px;
|
||||
}
|
||||
|
||||
widgetSlideDuration: 200;
|
||||
widgetFadeDuration: 200;
|
||||
|
||||
SettingsSlider {
|
||||
height: pixels;
|
||||
barTop: pixels;
|
||||
|
|
@ -1125,6 +1191,7 @@ PeerListItem {
|
|||
|
||||
button: OutlineButton;
|
||||
checkbox: RoundImageCheckbox;
|
||||
disabledCheckFg: color;
|
||||
statusFg: color;
|
||||
statusFgOver: color;
|
||||
statusFgActive: color;
|
||||
|
|
@ -1132,6 +1199,8 @@ PeerListItem {
|
|||
|
||||
PeerList {
|
||||
padding: margins;
|
||||
bg: color;
|
||||
about: FlatLabel;
|
||||
item: PeerListItem;
|
||||
}
|
||||
|
||||
|
|
@ -1163,13 +1232,31 @@ defaultPeerListItem: PeerListItem {
|
|||
photoSize: 46px;
|
||||
button: defaultPeerListButton;
|
||||
checkbox: defaultPeerListCheckbox;
|
||||
disabledCheckFg: menuIconFg;
|
||||
statusFg: windowSubTextFg;
|
||||
statusFgOver: windowSubTextFgOver;
|
||||
statusFgActive: windowActiveTextFg;
|
||||
}
|
||||
|
||||
boxTextStyle: TextStyle(defaultTextStyle) {
|
||||
font: font(boxFontSize);
|
||||
linkFont: font(boxFontSize);
|
||||
linkFontOver: font(boxFontSize underline);
|
||||
}
|
||||
|
||||
defaultPeerListAbout: FlatLabel(defaultFlatLabel) {
|
||||
minWidth: 240px;
|
||||
textFg: membersAboutLimitFg;
|
||||
align: align(top);
|
||||
style: TextStyle(boxTextStyle) {
|
||||
lineHeight: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
defaultPeerList: PeerList {
|
||||
padding: margins(0px, 0px, 0px, 0px);
|
||||
bg: contactsBg;
|
||||
about: defaultPeerListAbout;
|
||||
item: defaultPeerListItem;
|
||||
}
|
||||
|
||||
|
|
@ -1256,6 +1343,11 @@ defaultSettingsToggle: Toggle(defaultToggle) {
|
|||
defaultSettingsToggleOver: Toggle(defaultSettingsToggle) {
|
||||
untoggledFg: menuIconFgOver;
|
||||
}
|
||||
defaultSettingsRightLabel: FlatLabel(defaultFlatLabel) {
|
||||
textFg: windowActiveTextFg;
|
||||
style: boxTextStyle;
|
||||
maxHeight: 20px;
|
||||
}
|
||||
defaultSettingsButton: SettingsButton {
|
||||
textFg: windowBoldFg;
|
||||
textFgOver: windowBoldFgOver;
|
||||
|
|
@ -1263,6 +1355,7 @@ defaultSettingsButton: SettingsButton {
|
|||
textBgOver: windowBgOver;
|
||||
|
||||
font: boxTextFont;
|
||||
rightLabel: defaultSettingsRightLabel;
|
||||
|
||||
height: 20px;
|
||||
padding: margins(22px, 10px, 22px, 8px);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue