Add 'clear' button to search bar and implement search indicator via spinner
This commit is contained in:
parent
d4336b56d6
commit
a2e120a8a3
@ -20,6 +20,7 @@ ColumnLayout {
|
|||||||
property alias font: input.font
|
property alias font: input.font
|
||||||
property alias echoMode: input.echoMode
|
property alias echoMode: input.echoMode
|
||||||
property alias selectByMouse: input.selectByMouse
|
property alias selectByMouse: input.selectByMouse
|
||||||
|
property var hasClear: false
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: timer
|
id: timer
|
||||||
@ -129,6 +130,39 @@ ColumnLayout {
|
|||||||
color: labelC.text ? "transparent" : backgroundColor
|
color: labelC.text ? "transparent" : backgroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ToolButton {
|
||||||
|
id: clearText
|
||||||
|
Layout.fillWidth: true
|
||||||
|
visible: c.hasClear && searchField.text !== ''
|
||||||
|
icon.source: "image://colorimage/:/icons/icons/ui/round-remove-button.svg?" + (clearText.hovered ? Nheko.colors.highlight : Nheko.colors.buttonText)
|
||||||
|
focusPolicy: Qt.NoFocus
|
||||||
|
onClicked: {
|
||||||
|
searchField.clear()
|
||||||
|
topBar.searchString = "";
|
||||||
|
}
|
||||||
|
hoverEnabled: true
|
||||||
|
background: null
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
// clear the default hover effects.
|
||||||
|
|
||||||
|
Image {
|
||||||
|
height: parent.height - 2 * Nheko.paddingSmall
|
||||||
|
width: height
|
||||||
|
source: "image://colorimage/:/icons/icons/ui/round-remove-button.svg?" + (clearText.hovered ? Nheko.colors.highlight : Nheko.colors.buttonText)
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
right: parent.right
|
||||||
|
margins: Nheko.paddingSmall
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
@ -38,6 +38,8 @@ Item {
|
|||||||
|
|
||||||
property int delegateMaxWidth: ((Settings.timelineMaxWidth > 100 && Settings.timelineMaxWidth < chatRoot.availableWidth) ? Settings.timelineMaxWidth : chatRoot.availableWidth) - chatRoot.padding * 2 - (scrollbar.interactive? scrollbar.width : 0)
|
property int delegateMaxWidth: ((Settings.timelineMaxWidth > 100 && Settings.timelineMaxWidth < chatRoot.availableWidth) ? Settings.timelineMaxWidth : chatRoot.availableWidth) - chatRoot.padding * 2 - (scrollbar.interactive? scrollbar.width : 0)
|
||||||
|
|
||||||
|
readonly property alias filteringInProgress: filteredTimeline.filteringInProgress
|
||||||
|
|
||||||
displayMarginBeginning: height / 2
|
displayMarginBeginning: height / 2
|
||||||
displayMarginEnd: height / 2
|
displayMarginEnd: height / 2
|
||||||
|
|
||||||
@ -561,7 +563,7 @@ Item {
|
|||||||
footer: Item {
|
footer: Item {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.margins: Nheko.paddingLarge
|
anchors.margins: Nheko.paddingLarge
|
||||||
visible: room && room.paginationInProgress
|
visible: (room && room.paginationInProgress) || chat.filteringInProgress
|
||||||
// hacky, but works
|
// hacky, but works
|
||||||
height: loadingSpinner.height + 2 * Nheko.paddingLarge
|
height: loadingSpinner.height + 2 * Nheko.paddingLarge
|
||||||
|
|
||||||
@ -570,7 +572,7 @@ Item {
|
|||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
anchors.margins: Nheko.paddingLarge
|
anchors.margins: Nheko.paddingLarge
|
||||||
running: room && room.paginationInProgress
|
running: (room && room.paginationInProgress) || chat.filteringInProgress
|
||||||
foreground: Nheko.colors.mid
|
foreground: Nheko.colors.mid
|
||||||
z: 3
|
z: 3
|
||||||
}
|
}
|
||||||
|
@ -450,6 +450,7 @@ Pane {
|
|||||||
id: searchField
|
id: searchField
|
||||||
visible: searchButton.searchActive
|
visible: searchButton.searchActive
|
||||||
enabled: visible
|
enabled: visible
|
||||||
|
hasClear: true
|
||||||
|
|
||||||
Layout.row: 5
|
Layout.row: 5
|
||||||
Layout.column: 2
|
Layout.column: 2
|
||||||
|
@ -39,6 +39,7 @@ void
|
|||||||
TimelineFilter::startFiltering()
|
TimelineFilter::startFiltering()
|
||||||
{
|
{
|
||||||
incrementalSearchIndex = 0;
|
incrementalSearchIndex = 0;
|
||||||
|
emit isFilteringChanged();
|
||||||
invalidateFilter();
|
invalidateFilter();
|
||||||
|
|
||||||
continueFiltering();
|
continueFiltering();
|
||||||
@ -82,6 +83,7 @@ TimelineFilter::event(QEvent *ev)
|
|||||||
continueFiltering();
|
continueFiltering();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
emit isFilteringChanged();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -172,6 +174,7 @@ TimelineFilter::setSource(TimelineModel *s)
|
|||||||
incrementalSearchIndex = 0;
|
incrementalSearchIndex = 0;
|
||||||
|
|
||||||
emit sourceChanged();
|
emit sourceChanged();
|
||||||
|
emit isFilteringChanged();
|
||||||
invalidateFilter();
|
invalidateFilter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,6 +203,12 @@ TimelineFilter::currentIndex() const
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TimelineFilter::isFiltering() const
|
||||||
|
{
|
||||||
|
return incrementalSearchIndex != std::numeric_limits<int>::max() && !(threadId.isEmpty() && contentFilter.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TimelineFilter::filterAcceptsRow(int source_row, const QModelIndex &) const
|
TimelineFilter::filterAcceptsRow(int source_row, const QModelIndex &) const
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,7 @@ class TimelineFilter : public QSortFilterProxyModel
|
|||||||
contentFilterChanged)
|
contentFilterChanged)
|
||||||
Q_PROPERTY(TimelineModel *source READ source WRITE setSource NOTIFY sourceChanged)
|
Q_PROPERTY(TimelineModel *source READ source WRITE setSource NOTIFY sourceChanged)
|
||||||
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
|
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
|
||||||
|
Q_PROPERTY(bool filteringInProgress READ isFiltering NOTIFY isFilteringChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TimelineFilter(QObject *parent = nullptr);
|
explicit TimelineFilter(QObject *parent = nullptr);
|
||||||
@ -28,6 +29,7 @@ public:
|
|||||||
QString filterByContent() const { return contentFilter; }
|
QString filterByContent() const { return contentFilter; }
|
||||||
TimelineModel *source() const;
|
TimelineModel *source() const;
|
||||||
int currentIndex() const;
|
int currentIndex() const;
|
||||||
|
bool isFiltering() const;
|
||||||
|
|
||||||
void setThreadId(const QString &t);
|
void setThreadId(const QString &t);
|
||||||
void setContentFilter(const QString &t);
|
void setContentFilter(const QString &t);
|
||||||
@ -46,6 +48,7 @@ signals:
|
|||||||
void contentFilterChanged();
|
void contentFilterChanged();
|
||||||
void sourceChanged();
|
void sourceChanged();
|
||||||
void currentIndexChanged();
|
void currentIndexChanged();
|
||||||
|
void isFilteringChanged();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void fetchAgain();
|
void fetchAgain();
|
||||||
|
Loading…
Reference in New Issue
Block a user