mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
New cancel search icon animation.
This commit is contained in:
parent
9fa284a6d1
commit
9155591e8a
21 changed files with 301 additions and 79 deletions
|
@ -27,7 +27,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "window/window_theme.h"
|
||||
#include "styles/style_overview.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "ui/effects/round_image_checkbox.h"
|
||||
#include "ui/effects/round_checkbox.h"
|
||||
|
||||
BackgroundBox::BackgroundBox() : ItemListBox(st::backgroundScroll)
|
||||
, _inner(this) {
|
||||
|
|
|
@ -268,8 +268,12 @@ contactsMultiSelect: MultiSelect {
|
|||
textActiveBg: activeButtonBg;
|
||||
textActiveFg: activeButtonFg;
|
||||
deleteFg: activeButtonFg;
|
||||
deleteLeft: 10px;
|
||||
deleteStroke: 2px;
|
||||
deleteCross: CrossAnimation {
|
||||
size: 32px;
|
||||
skip: 10px;
|
||||
stroke: 2px;
|
||||
minScale: 0.3;
|
||||
}
|
||||
duration: 150;
|
||||
minScale: 0.3;
|
||||
}
|
||||
|
@ -295,7 +299,25 @@ contactsMultiSelect: MultiSelect {
|
|||
fieldIcon: boxFieldSearchIcon;
|
||||
fieldIconSkip: 36px;
|
||||
|
||||
fieldCancel: boxBlockTitleClose;
|
||||
fieldCancel: CrossButton {
|
||||
width: boxBlockTitleHeight;
|
||||
height: boxBlockTitleHeight;
|
||||
|
||||
cross: CrossAnimation {
|
||||
size: 40px;
|
||||
skip: 14px;
|
||||
stroke: 2px;
|
||||
minScale: 0.3;
|
||||
}
|
||||
crossFg: boxBlockTitleCloseFg;
|
||||
crossFgOver: boxBlockTitleCloseFgOver;
|
||||
crossPosition: point(4px, 4px);
|
||||
|
||||
duration: 150;
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: windowBgOver;
|
||||
}
|
||||
}
|
||||
fieldCancelSkip: 40px;
|
||||
}
|
||||
contactsPhotoCheckbox: RoundImageCheckbox {
|
||||
|
|
|
@ -22,7 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "boxes/abstractbox.h"
|
||||
#include "core/single_timer.h"
|
||||
#include "ui/effects/round_image_checkbox.h"
|
||||
#include "ui/effects/round_checkbox.h"
|
||||
#include "boxes/members_box.h"
|
||||
|
||||
namespace Dialogs {
|
||||
|
|
|
@ -22,7 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "boxes/abstractbox.h"
|
||||
#include "core/single_timer.h"
|
||||
#include "ui/effects/round_image_checkbox.h"
|
||||
#include "ui/effects/round_checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
|
||||
class ContactsBox;
|
||||
|
|
|
@ -23,7 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "boxes/abstractbox.h"
|
||||
#include "core/observer.h"
|
||||
#include "core/vector_of_moveable.h"
|
||||
#include "ui/effects/round_image_checkbox.h"
|
||||
#include "ui/effects/round_checkbox.h"
|
||||
|
||||
namespace Dialogs {
|
||||
class Row;
|
||||
|
|
|
@ -113,11 +113,21 @@ dialogsCancelSearchInPeer: IconButton(dialogsMenuToggle) {
|
|||
iconOver: icon {{ "dialogs_cancel_search", dialogsMenuIconFgOver }};
|
||||
iconPosition: point(11px, 11px);
|
||||
}
|
||||
dialogsCancelSearch: IconButton(dialogsCancelSearchInPeer) {
|
||||
dialogsCancelSearch: CrossButton {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
iconPosition: point(7px, 7px);
|
||||
|
||||
cross: CrossAnimation {
|
||||
size: 32px;
|
||||
skip: 10px;
|
||||
stroke: 2px;
|
||||
minScale: 0.3;
|
||||
}
|
||||
crossFg: dialogsMenuIconFg;
|
||||
crossFgOver: dialogsMenuIconFgOver;
|
||||
crossPosition: point(0px, 0px);
|
||||
|
||||
duration: 150;
|
||||
ripple: emptyRippleAnimation;
|
||||
}
|
||||
|
||||
|
|
|
@ -1719,7 +1719,6 @@ DialogsWidget::DialogsWidget(QWidget *parent) : TWidget(parent)
|
|||
|
||||
_filter->setFocusPolicy(Qt::StrongFocus);
|
||||
_filter->customUpDown(true);
|
||||
_cancelSearch->hide();
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
@ -1790,7 +1789,7 @@ void DialogsWidget::showAnimated(Window::SlideDirection direction, const Window:
|
|||
_mainMenuToggle->hide();
|
||||
if (_forwardCancel) _forwardCancel->hide();
|
||||
_filter->hide();
|
||||
_cancelSearch->hide();
|
||||
_cancelSearch->hideFast();
|
||||
_lockUnlock->hide();
|
||||
|
||||
int delta = st::slideShift;
|
||||
|
@ -2294,9 +2293,9 @@ void DialogsWidget::onFilterUpdate(bool force) {
|
|||
_searchCache.clear();
|
||||
_searchQueries.clear();
|
||||
_searchQuery = QString();
|
||||
_cancelSearch->hide();
|
||||
} else if (_cancelSearch->isHidden()) {
|
||||
_cancelSearch->show();
|
||||
_cancelSearch->hideAnimated();
|
||||
} else {
|
||||
_cancelSearch->showAnimated();
|
||||
}
|
||||
if (filterText.size() < MinUsernameLength) {
|
||||
_peopleCache.clear();
|
||||
|
|
|
@ -36,6 +36,7 @@ class DropdownMenu;
|
|||
class FlatButton;
|
||||
class LinkButton;
|
||||
class FlatInput;
|
||||
class CrossButton;
|
||||
} // namespace Ui
|
||||
|
||||
enum DialogsSearchRequestType {
|
||||
|
@ -334,7 +335,7 @@ private:
|
|||
ChildWidget<Ui::IconButton> _forwardCancel = { nullptr };
|
||||
ChildWidget<Ui::IconButton> _mainMenuToggle;
|
||||
ChildWidget<Ui::FlatInput> _filter;
|
||||
ChildWidget<Ui::IconButton> _cancelSearch;
|
||||
ChildWidget<Ui::CrossButton> _cancelSearch;
|
||||
ChildWidget<Ui::IconButton> _lockUnlock;
|
||||
ChildWidget<Ui::ScrollArea> _scroll;
|
||||
ChildWidget<DialogsInner> _inner;
|
||||
|
|
|
@ -35,7 +35,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "media/player/media_player_instance.h"
|
||||
#include "localstorage.h"
|
||||
#include "history/history_media_types.h"
|
||||
#include "ui/effects/round_image_checkbox.h"
|
||||
#include "ui/effects/round_checkbox.h"
|
||||
|
||||
namespace Overview {
|
||||
namespace Layout {
|
||||
|
|
|
@ -85,7 +85,6 @@ OverviewInner::OverviewInner(OverviewWidget *overview, Ui::ScrollArea *scroll, P
|
|||
_searchTimer.setSingleShot(true);
|
||||
connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchMessages()));
|
||||
|
||||
_cancelSearch->hide();
|
||||
if (_type == OverviewLinks || _type == OverviewFiles) {
|
||||
_search->show();
|
||||
} else {
|
||||
|
@ -1346,7 +1345,7 @@ void OverviewInner::switchType(MediaOverviewType type) {
|
|||
_search->updatePlaceholder();
|
||||
onSearchUpdate();
|
||||
}
|
||||
_cancelSearch->hide();
|
||||
_cancelSearch->hideFast();
|
||||
|
||||
resizeToWidth(_width, 0, _minHeight, true);
|
||||
}
|
||||
|
@ -1475,9 +1474,9 @@ void OverviewInner::onSearchUpdate() {
|
|||
_searchQueries.clear();
|
||||
_searchQuery = QString();
|
||||
_searchResults.clear();
|
||||
_cancelSearch->hide();
|
||||
} else if (_cancelSearch->isHidden()) {
|
||||
_cancelSearch->show();
|
||||
_cancelSearch->hideAnimated();
|
||||
} else {
|
||||
_cancelSearch->showAnimated();
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
|
@ -1499,7 +1498,7 @@ void OverviewInner::onCancel() {
|
|||
bool OverviewInner::onCancelSearch() {
|
||||
if (_search->isHidden()) return false;
|
||||
bool clearing = !_search->text().isEmpty();
|
||||
_cancelSearch->hide();
|
||||
_cancelSearch->hideAnimated();
|
||||
_search->clear();
|
||||
_search->updatePlaceholder();
|
||||
onSearchUpdate();
|
||||
|
|
|
@ -37,6 +37,7 @@ class PlainShadow;
|
|||
class PopupMenu;
|
||||
class IconButton;
|
||||
class FlatInput;
|
||||
class CrossButton;
|
||||
} // namespace Ui
|
||||
|
||||
class OverviewWidget;
|
||||
|
@ -182,7 +183,7 @@ private:
|
|||
int32 setLayoutItem(int32 index, Overview::Layout::AbstractItem *item, int32 top);
|
||||
|
||||
ChildWidget<Ui::FlatInput> _search;
|
||||
ChildWidget<Ui::IconButton> _cancelSearch;
|
||||
ChildWidget<Ui::CrossButton> _cancelSearch;
|
||||
QVector<MsgId> _results;
|
||||
int32 _itemsToBeLoaded;
|
||||
|
||||
|
|
74
Telegram/SourceFiles/ui/effects/cross_animation.cpp
Normal file
74
Telegram/SourceFiles/ui/effects/cross_animation.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "ui/effects/cross_animation.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
void CrossAnimation::paint(QPainter &p, const style::CrossAnimation &st, const style::color &color, int x, int y, int outerWidth, float64 shown) {
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
|
||||
auto deleteScale = shown + st.minScale * (1. - shown);
|
||||
auto deleteSkip = deleteScale * st.skip + (1. - deleteScale) * (st.size / 2);
|
||||
auto sqrt2 = sqrt(2.);
|
||||
auto deleteLeft = rtlpoint(x + deleteSkip, 0, outerWidth).x() + 0.;
|
||||
auto deleteTop = y + deleteSkip + 0.;
|
||||
auto deleteWidth = st.size - 2 * deleteSkip;
|
||||
auto deleteHeight = st.size - 2 * deleteSkip;
|
||||
auto deleteStroke = st.stroke / sqrt2;
|
||||
QPointF pathDelete[] = {
|
||||
{ deleteLeft, deleteTop + deleteStroke },
|
||||
{ deleteLeft + deleteStroke, deleteTop },
|
||||
{ deleteLeft + (deleteWidth / 2.), deleteTop + (deleteHeight / 2.) - deleteStroke },
|
||||
{ deleteLeft + deleteWidth - deleteStroke, deleteTop },
|
||||
{ deleteLeft + deleteWidth, deleteTop + deleteStroke },
|
||||
{ deleteLeft + (deleteWidth / 2.) + deleteStroke, deleteTop + (deleteHeight / 2.) },
|
||||
{ deleteLeft + deleteWidth, deleteTop + deleteHeight - deleteStroke },
|
||||
{ deleteLeft + deleteWidth - deleteStroke, deleteTop + deleteHeight },
|
||||
{ deleteLeft + (deleteWidth / 2.), deleteTop + (deleteHeight / 2.) + deleteStroke },
|
||||
{ deleteLeft + deleteStroke, deleteTop + deleteHeight },
|
||||
{ deleteLeft, deleteTop + deleteHeight - deleteStroke },
|
||||
{ deleteLeft + (deleteWidth / 2.) - deleteStroke, deleteTop + (deleteHeight / 2.) },
|
||||
};
|
||||
if (shown < 1.) {
|
||||
auto alpha = -(shown - 1.) * M_PI_2;
|
||||
auto cosalpha = cos(alpha);
|
||||
auto sinalpha = sin(alpha);
|
||||
auto shiftx = deleteLeft + (deleteWidth / 2.);
|
||||
auto shifty = deleteTop + (deleteHeight / 2.);
|
||||
for (auto &point : pathDelete) {
|
||||
auto x = point.x() - shiftx;
|
||||
auto y = point.y() - shifty;
|
||||
point.setX(shiftx + x * cosalpha - y * sinalpha);
|
||||
point.setY(shifty + y * cosalpha + x * sinalpha);
|
||||
}
|
||||
}
|
||||
QPainterPath path;
|
||||
path.moveTo(pathDelete[0]);
|
||||
for (int i = 1; i != base::array_size(pathDelete); ++i) {
|
||||
path.lineTo(pathDelete[i]);
|
||||
}
|
||||
p.fillPath(path, color);
|
||||
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||
}
|
||||
|
||||
} // namespace Ui
|
33
Telegram/SourceFiles/ui/effects/cross_animation.h
Normal file
33
Telegram/SourceFiles/ui/effects/cross_animation.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class CrossAnimation {
|
||||
public:
|
||||
static void paint(QPainter &p, const style::CrossAnimation &st, const style::color &color, int x, int y, int outerWidth, float64 shown);
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
|
@ -19,7 +19,7 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
|||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "ui/effects/round_image_checkbox.h"
|
||||
#include "ui/effects/round_checkbox.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "ui/widgets/buttons.h"
|
||||
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/effects/cross_animation.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
|
@ -449,4 +450,68 @@ void LeftOutlineButton::paintEvent(QPaintEvent *e) {
|
|||
p.drawTextLeft(_st.padding.left(), _st.padding.top(), width(), _text, _textWidth);
|
||||
}
|
||||
|
||||
CrossButton::CrossButton(QWidget *parent, const style::CrossButton &st) : RippleButton(parent, st.ripple)
|
||||
, _st(st) {
|
||||
resize(_st.width, _st.height);
|
||||
setCursor(style::cur_pointer);
|
||||
hide();
|
||||
}
|
||||
|
||||
void CrossButton::hideAnimated() {
|
||||
startAnimation(false);
|
||||
}
|
||||
|
||||
void CrossButton::showAnimated() {
|
||||
startAnimation(true);
|
||||
}
|
||||
|
||||
void CrossButton::hideFast() {
|
||||
hideAnimated();
|
||||
_a_show.finish();
|
||||
}
|
||||
|
||||
void CrossButton::startAnimation(bool shown) {
|
||||
if (_shown == shown) return;
|
||||
_shown = shown;
|
||||
if (isHidden()) show();
|
||||
_a_show.start([this] { animationCallback(); }, _shown ? 0. : 1., _shown ? 1. : 0., _st.duration);
|
||||
}
|
||||
|
||||
void CrossButton::animationCallback() {
|
||||
update();
|
||||
if (!_shown && !_a_show.animating()) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
void CrossButton::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
auto ms = getms();
|
||||
auto over = (_state & StateOver);
|
||||
auto shown = _a_show.current(ms, _shown ? 1. : 0.);
|
||||
p.setOpacity(shown);
|
||||
|
||||
paintRipple(p, _st.crossPosition.x(), _st.crossPosition.y(), ms);
|
||||
|
||||
CrossAnimation::paint(p, _st.cross, over ? _st.crossFgOver : _st.crossFg, _st.crossPosition.x(), _st.crossPosition.y(), width(), shown);
|
||||
}
|
||||
|
||||
void CrossButton::onStateChanged(int oldState, StateChangeSource source) {
|
||||
RippleButton::onStateChanged(oldState, source);
|
||||
|
||||
auto over = (_state & StateOver);
|
||||
if (over != (oldState & StateOver)) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
QPoint CrossButton::prepareRippleStartPosition() const {
|
||||
return mapFromGlobal(QCursor::pos()) - _st.crossPosition;
|
||||
}
|
||||
|
||||
QImage CrossButton::prepareRippleMask() const {
|
||||
return RippleAnimation::ellipseMask(QSize(_st.cross.size, _st.cross.size));
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -197,4 +197,35 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class CrossButton : public RippleButton {
|
||||
public:
|
||||
CrossButton(QWidget *parent, const style::CrossButton &st);
|
||||
|
||||
void showAnimated();
|
||||
void hideAnimated();
|
||||
void hideFast();
|
||||
|
||||
bool isShown() const {
|
||||
return _shown;
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
void onStateChanged(int oldState, StateChangeSource source) override;
|
||||
|
||||
QImage prepareRippleMask() const override;
|
||||
QPoint prepareRippleStartPosition() const override;
|
||||
|
||||
private:
|
||||
void startAnimation(bool shown);
|
||||
void animationCallback();
|
||||
|
||||
const style::CrossButton &_st;
|
||||
|
||||
bool _shown = false;
|
||||
FloatAnimation _a_show;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/effects/cross_animation.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Ui {
|
||||
|
@ -199,54 +200,15 @@ void MultiSelect::Inner::Item::paintOnce(Painter &p, int x, int y, int outerWidt
|
|||
|
||||
void MultiSelect::Inner::Item::paintDeleteButton(Painter &p, int x, int y, int outerWidth, float64 overOpacity) {
|
||||
p.setOpacity(overOpacity);
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(_color);
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
p.drawEllipse(rtlrect(x, y, _st.height, _st.height, outerWidth));
|
||||
|
||||
auto deleteScale = overOpacity + _st.minScale * (1. - overOpacity);
|
||||
auto deleteSkip = deleteScale * _st.deleteLeft + (1. - deleteScale) * (_st.height / 2);
|
||||
auto sqrt2 = sqrt(2.);
|
||||
auto deleteLeft = rtlpoint(x + deleteSkip, 0, outerWidth).x() + 0.;
|
||||
auto deleteTop = y + deleteSkip + 0.;
|
||||
auto deleteWidth = _st.height - 2 * deleteSkip;
|
||||
auto deleteHeight = _st.height - 2 * deleteSkip;
|
||||
auto deleteStroke = _st.deleteStroke / sqrt2;
|
||||
QPointF pathDelete[] = {
|
||||
{ deleteLeft, deleteTop + deleteStroke },
|
||||
{ deleteLeft + deleteStroke, deleteTop },
|
||||
{ deleteLeft + (deleteWidth / 2.), deleteTop + (deleteHeight / 2.) - deleteStroke },
|
||||
{ deleteLeft + deleteWidth - deleteStroke, deleteTop },
|
||||
{ deleteLeft + deleteWidth, deleteTop + deleteStroke },
|
||||
{ deleteLeft + (deleteWidth / 2.) + deleteStroke, deleteTop + (deleteHeight / 2.) },
|
||||
{ deleteLeft + deleteWidth, deleteTop + deleteHeight - deleteStroke },
|
||||
{ deleteLeft + deleteWidth - deleteStroke, deleteTop + deleteHeight },
|
||||
{ deleteLeft + (deleteWidth / 2.), deleteTop + (deleteHeight / 2.) + deleteStroke },
|
||||
{ deleteLeft + deleteStroke, deleteTop + deleteHeight },
|
||||
{ deleteLeft, deleteTop + deleteHeight - deleteStroke },
|
||||
{ deleteLeft + (deleteWidth / 2.) - deleteStroke, deleteTop + (deleteHeight / 2.) },
|
||||
};
|
||||
if (overOpacity < 1.) {
|
||||
auto alpha = -(overOpacity - 1.) * M_PI_2;
|
||||
auto cosalpha = cos(alpha);
|
||||
auto sinalpha = sin(alpha);
|
||||
auto shiftx = deleteLeft + (deleteWidth / 2.);
|
||||
auto shifty = deleteTop + (deleteHeight / 2.);
|
||||
for (auto &point : pathDelete) {
|
||||
auto x = point.x() - shiftx;
|
||||
auto y = point.y() - shifty;
|
||||
point.setX(shiftx + x * cosalpha - y * sinalpha);
|
||||
point.setY(shifty + y * cosalpha + x * sinalpha);
|
||||
}
|
||||
}
|
||||
QPainterPath path;
|
||||
path.moveTo(pathDelete[0]);
|
||||
for (int i = 1; i != base::array_size(pathDelete); ++i) {
|
||||
path.lineTo(pathDelete[i]);
|
||||
}
|
||||
p.fillPath(path, _st.deleteFg);
|
||||
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||
|
||||
CrossAnimation::paint(p, _st.deleteCross, _st.deleteFg, x, y, outerWidth, overOpacity);
|
||||
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
|
||||
|
@ -465,7 +427,6 @@ MultiSelect::Inner::Inner(QWidget *parent, const style::MultiSelect &st, const Q
|
|||
connect(_field, SIGNAL(focused()), this, SLOT(onFieldFocused()));
|
||||
connect(_field, SIGNAL(changed()), this, SLOT(onQueryChanged()));
|
||||
connect(_field, SIGNAL(submitted(bool)), this, SLOT(onSubmitted(bool)));
|
||||
_cancel->hide();
|
||||
_cancel->setClickedCallback([this] {
|
||||
clearQuery();
|
||||
_field->setFocus();
|
||||
|
@ -475,7 +436,11 @@ MultiSelect::Inner::Inner(QWidget *parent, const style::MultiSelect &st, const Q
|
|||
|
||||
void MultiSelect::Inner::onQueryChanged() {
|
||||
auto query = getQuery();
|
||||
_cancel->setVisible(!query.isEmpty());
|
||||
if (query.isEmpty()) {
|
||||
_cancel->hideAnimated();
|
||||
} else {
|
||||
_cancel->showAnimated();
|
||||
}
|
||||
updateFieldGeometry();
|
||||
if (_queryChangedCallback) {
|
||||
_queryChangedCallback(query);
|
||||
|
@ -510,7 +475,7 @@ void MultiSelect::Inner::setSubmittedCallback(base::lambda<void(bool ctrlShiftEn
|
|||
|
||||
void MultiSelect::Inner::updateFieldGeometry() {
|
||||
auto fieldFinalWidth = _fieldWidth;
|
||||
if (!_cancel->isHidden()) {
|
||||
if (_cancel->isShown()) {
|
||||
fieldFinalWidth -= _st.fieldCancelSkip;
|
||||
}
|
||||
_field->resizeToWidth(fieldFinalWidth);
|
||||
|
|
|
@ -25,7 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
namespace Ui {
|
||||
|
||||
class InputField;
|
||||
class IconButton;
|
||||
class CrossButton;
|
||||
class ScrollArea;
|
||||
|
||||
class MultiSelect : public TWidget {
|
||||
|
@ -154,7 +154,7 @@ private:
|
|||
int _fieldTop = 0;
|
||||
int _fieldWidth = 0;
|
||||
ChildWidget<Ui::InputField> _field;
|
||||
ChildWidget<Ui::IconButton> _cancel;
|
||||
ChildWidget<Ui::CrossButton> _cancel;
|
||||
|
||||
int _newHeight = 0;
|
||||
IntAnimation _height;
|
||||
|
|
|
@ -339,6 +339,27 @@ RoundImageCheckbox {
|
|||
check: RoundCheckbox;
|
||||
}
|
||||
|
||||
CrossAnimation {
|
||||
fg: color;
|
||||
size: pixels;
|
||||
skip: pixels;
|
||||
stroke: pixels;
|
||||
minScale: double;
|
||||
}
|
||||
|
||||
CrossButton {
|
||||
width: pixels;
|
||||
height: pixels;
|
||||
|
||||
cross: CrossAnimation;
|
||||
crossFg: color;
|
||||
crossFgOver:color;
|
||||
crossPosition: point;
|
||||
duration: int;
|
||||
|
||||
ripple: RippleAnimation;
|
||||
}
|
||||
|
||||
MultiSelectItem {
|
||||
padding: margins;
|
||||
maxWidth: pixels;
|
||||
|
@ -348,10 +369,9 @@ MultiSelectItem {
|
|||
textFg: color;
|
||||
textActiveBg: color;
|
||||
textActiveFg: color;
|
||||
deleteFg: color;
|
||||
deleteLeft: pixels;
|
||||
deleteStroke: pixels;
|
||||
duration: int;
|
||||
deleteFg: color;
|
||||
deleteCross: CrossAnimation;
|
||||
minScale: double;
|
||||
}
|
||||
|
||||
|
@ -368,7 +388,7 @@ MultiSelect {
|
|||
fieldMinWidth: pixels;
|
||||
fieldIcon: icon;
|
||||
fieldIconSkip: pixels;
|
||||
fieldCancel: IconButton;
|
||||
fieldCancel: CrossButton;
|
||||
fieldCancelSkip: pixels;
|
||||
}
|
||||
|
||||
|
|
|
@ -454,6 +454,8 @@
|
|||
'<(src_loc)/ui/buttons/history_down_button.h',
|
||||
'<(src_loc)/ui/buttons/peer_avatar_button.cpp',
|
||||
'<(src_loc)/ui/buttons/peer_avatar_button.h',
|
||||
'<(src_loc)/ui/effects/cross_animation.cpp',
|
||||
'<(src_loc)/ui/effects/cross_animation.h',
|
||||
'<(src_loc)/ui/effects/panel_animation.cpp',
|
||||
'<(src_loc)/ui/effects/panel_animation.h',
|
||||
'<(src_loc)/ui/effects/radial_animation.cpp',
|
||||
|
@ -462,8 +464,8 @@
|
|||
'<(src_loc)/ui/effects/rect_shadow.h',
|
||||
'<(src_loc)/ui/effects/ripple_animation.cpp',
|
||||
'<(src_loc)/ui/effects/ripple_animation.h',
|
||||
'<(src_loc)/ui/effects/round_image_checkbox.cpp',
|
||||
'<(src_loc)/ui/effects/round_image_checkbox.h',
|
||||
'<(src_loc)/ui/effects/round_checkbox.cpp',
|
||||
'<(src_loc)/ui/effects/round_checkbox.h',
|
||||
'<(src_loc)/ui/effects/widget_fade_wrap.cpp',
|
||||
'<(src_loc)/ui/effects/widget_fade_wrap.h',
|
||||
'<(src_loc)/ui/effects/widget_slide_wrap.cpp',
|
||||
|
|
Loading…
Add table
Reference in a new issue