Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Fine-Tuned Zim Search #1189

Open
wants to merge 23 commits into
base: main
Choose a base branch
from

Conversation

ShaopengLin
Copy link
Collaborator

@ShaopengLin ShaopengLin commented Aug 29, 2024

Fixes (pat of) #413

Changes:

  • Improved Search Bar suggestion Layout.
    • Added Icon to suggestions
    • Proper font and layout sizes for suggestions.

@ShaopengLin
Copy link
Collaborator Author

ShaopengLin commented Aug 29, 2024

@kelson42 Could you do a pass on the UI first? I will be re-factoring the code and commits in the mean time but would want some feed-back during this time so I can incorporate those.

@kelson42 kelson42 force-pushed the Issue#413-search-UI-improvement branch from 0e7b89c to 3861988 Compare September 1, 2024 18:23
@kelson42
Copy link
Collaborator

kelson42 commented Sep 1, 2024

@ShaopengLin For me, it does not compile:

r/include/x86_64-linux-gnu/qt5/QtCore -I. -I. -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -o suggestionlistmodel.o src/suggestionlistmodel.cpp
src/suggestionlistmodel.cpp: In member function ‘void SuggestionListModel::resetSuggestions(const QStringList&)’:
src/suggestionlistmodel.cpp:110:21: error: loop variable ‘suggestion’ creates a copy from type ‘const QString’ [-Werror=range-loop-construct]
  110 |     for (const auto suggestion : suggestions)
      |                     ^~~~~~~~~~
src/suggestionlistmodel.cpp:110:21: note: use reference type to prevent copying
  110 |     for (const auto suggestion : suggestions)
      |                     ^~~~~~~~~~
      |                     &
cc1plus: all warnings being treated as errors

@ShaopengLin ShaopengLin force-pushed the Issue#413-search-UI-improvement branch from 3861988 to f0cec36 Compare September 2, 2024 01:57
@ShaopengLin
Copy link
Collaborator Author

ShaopengLin commented Sep 2, 2024

@kelson42 Made a quick fix to the compilation warning. Hopefully the libkiwix bug can be resolved.

@kelson42 kelson42 force-pushed the Issue#413-search-UI-improvement branch from f0cec36 to 5887e75 Compare September 2, 2024 18:36
Copy link
Collaborator

@kelson42 kelson42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ShaopengLin To me this is already almost perfect. My request would be:

  • Implement the checkbox "Select all" and grey everything
  • The suggestion overlay should be as broad as the search box
  • The search overlay is one or two pixel two high, it slightly covers the searchbox and it should not (see mockup)
  • If suggestions are displayed, we need to click twise on the suggestions settings to display the overlay, only one click should be necessary

At this stage, this is basically the only problems I have seen!

@ShaopengLin
Copy link
Collaborator Author

ShaopengLin commented Sep 4, 2024

@kelson42
For 1: To clarify, do you mean grey the 'Select All' checkbox? I am assuming this as we don't have 'true' multi-zim search yet. So having this feature enabled wouldn't make any sense.

For 2 & 3. After some digging, I found a way to circumvent several Qt Bugs. Aligning with Line Edit is now achievable. Link for future technical reference.

For 4: I have tried my best but cannot find a good solution. Qt doesn't naturally provide this and the best attempt at a hack causes the search to flicker. I would recommend have this for a different issue.

Without 4 implemented:

video1258420655.online-video-cutter.com.mp4

With 4:

video2258420655.online-video-cutter.com.1.mp4

@ShaopengLin ShaopengLin force-pushed the Issue#413-search-UI-improvement branch 2 times, most recently from 777c207 to 4a047b7 Compare September 4, 2024 11:18
@ShaopengLin
Copy link
Collaborator Author

Added 2&3 discussed here. Waiting on confirmation for 1.

@kelson42
Copy link
Collaborator

kelson42 commented Sep 8, 2024

For 1: To clarify, do you mean grey the 'Select All' checkbox? I am assuming this as we don't have 'true' multi-zim search yet. So having this feature enabled wouldn't make any sense.

Yes, please make the whole "All select" working fine (and then grey or hide it). Reason is that we will ASAP implement the multizim selection (in the libzim) and I want to have the UI ready.

For 2 & 3. After some digging, I found a way to circumvent several Qt Bugs. Aligning with Line Edit is now achievable. Link for future technical reference.

I don't understand, seem perfect to me.

For 4: I have tried my best but cannot find a good solution. Qt doesn't naturally provide this and the best attempt at a hack causes the search to flicker. I would recommend have this for a different issue.

Open issues then please and give all the references. That sounds really weird to me that you face difficulty on this. From my perspective (very far away) you should display the overlay when the settings button get the focus, not when you click on it. Maybe unfocusing the searchbar helps as well.

@ShaopengLin
Copy link
Collaborator Author

@kelson42 The checkbox UI has been added.

@kelson42
Copy link
Collaborator

kelson42 commented Sep 9, 2024

@veloman-yunkan I will check a last time rhat everything works fine but so far I'm concerned LGTM. Can you pleaee start with the code review?

@kelson42

This comment was marked as off-topic.

Copy link
Collaborator

@kelson42 kelson42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ShaopengLin Please respect the mockup:
image

  • Background should be white
  • To make a big box if there is only two items, the "Select All" should be directly below the list of items
  • For each item the margins around the checkboxes are not regular, the space between favicon and test if far too big.. and the ZIM title sticks too much to the favicon.
  • Ensure that the text "Select all" is properly aligned with the favicons
  • "Kiwix Search" label should not be bold, try to stick to the mockup AFAP
  • Actually the whole suggestions item are in the wrong size/fonting, see
    image

Please make an overall check that you check AFAP to the mockup, at the pixel level.

@ShaopengLin
Copy link
Collaborator Author

@kelson42 What is the font family used in the mock-up?

@kelson42
Copy link
Collaborator

kelson42 commented Sep 9, 2024

@kelson42 What is the font family used in the mock-up?

All the details are here... but please don't take measure to change the default font. If you see something to change there, please create an issue.

@ShaopengLin
Copy link
Collaborator Author

ShaopengLin commented Sep 9, 2024

@veloman-yunkan @kelson42 Code review should hold off. To have the exact spacings like the mock up, will need a somewhat large architectural change to this PR (due to Qt not offering those stylistic changes and I will have to implement/style the icon and text painting myself.)

@kelson42
Copy link
Collaborator

kelson42 commented Sep 9, 2024

@veloman-yunkan @kelson42 Code review should hold off. To have the exact spacings like the mock up, will need a somewhat large architectural change to this PR (due to Qt not offering those stylistic changes and I will have to implement/style the icon and text painting myself.)

I disagree, a lot of things can be fixed without changing the font (like font size, font boldness, etc...)

@ShaopengLin
Copy link
Collaborator Author

@kelson42 I am mostly talking about the spacing between icon and text. I agree with you the fonts and boldness are easy to change.

@kelson42
Copy link
Collaborator

kelson42 commented Sep 9, 2024

@kelson42 I am mostly talking about the spacing between icon and text. I agree with you the fonts and boldness are easy to change.

OK, do your best to fix the most and we will tackle what is left at the end.

@kelson42
Copy link
Collaborator

@ShaopengLin Any news here so I can make a new review pass? A rebase would be welcome too.

@ShaopengLin
Copy link
Collaborator Author

I was mostly focusing on TOC. Finalizing the UI here is my next step.

@ShaopengLin
Copy link
Collaborator Author

@veloman-yunkan I have removed Multizim.

@kelson42
Copy link
Collaborator

kelson42 commented Sep 28, 2024

@veloman-yunkan I have removed Multizim.

@ShaopengLin Where it the PR with this part of the code? Please open it immediatly and adapt PR description accordingly.

@ShaopengLin
Copy link
Collaborator Author

Moved Multi-Zim to #1218

@veloman-yunkan
Copy link
Collaborator

I have a question about interaction of the following enhancements brought by this PR to the suggestion list:

  1. Different types of suggestions grouped by their source (Kiwix search, bookmarks, history, open tabs) as visualized on the mockup.
  2. Infinite scroll

At this point, there is only one group (Kiwix search) which make dealing with infinite scroll easy. But what's your vision regarding the operation of the infinite scroll when another group of suggestions is added?

@ShaopengLin
Copy link
Collaborator Author

@veloman-yunkan It will largely depend on the scrolling behaviour.
If we use one scroller for all suggestion groups, we can just add seperator rows in the model, then fetch equal amount from all.

If each group gets a scroller, we might need to replace qcompleter with a popup widget that contain two views.

The second one is the better option IMO andwhat I think we should be able to do. We seem to be controlling a major portion of the completing behaviour already.

Copy link
Collaborator

@veloman-yunkan veloman-yunkan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you can think of a way to further split this PR, then we can make faster progress on merging it in two steps. Otherwise, I think that the review process will take too long.
But please don't actually split the PR - describe your proposal first and we'll proceed with it if promises to take us to our destination faster.

kiwix-desktop.pro Show resolved Hide resolved
src/suggestionlistmodel.cpp Show resolved Hide resolved
src/searchbar.cpp Outdated Show resolved Hide resolved
src/suggestionlistmodel.cpp Show resolved Hide resolved
src/suggestionlistmodel.h Outdated Show resolved Hide resolved
src/suggestionlistmodel.cpp Show resolved Hide resolved
Comment on lines +223 to +241
/* See SearchBar border and margin size in resources/css/style.css */
int top = searchGeo.height() - 6; /* top&bottom margin + border */
int width = searchGeo.width() - 6; /* left&right margin + border */

#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool lineEditFlipped = KiwixApp::isRightToLeft();
#else
bool lineEditFlipped = m_searchbarInput.isRightToLeft();
#endif

/* When not flipped, match left of completer to search bar. Popups are
shifted by margin and border so we undo those changes to stay in border.
When flipped, we first match left of completer to right of search bar.
In addition to the popup shift due to border and margin, We move right by
one more border size to match the right border pixel. We then move it
left by width to match left of search bar.
*/
int left = lineEditFlipped ? -searchLineEditGeo.left() + 4 - width
: -searchLineEditGeo.left() + 3;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too many magic numbers.

@@ -80,6 +80,14 @@ SearchBarLineEdit::SearchBarLineEdit(QWidget *parent) :
m_suggestionView->setRootIsDecorated(false);
m_suggestionView->setStyleSheet(KiwixApp::instance()->parseStyleFromFile(":/css/popup.css"));

/* See line-height&padding resources/css/popup.css QHeaderView::section. */
m_suggestionView->setIconSize(QSize(24, 24));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does Qt provide a way of obtaining values from the stylesheet in effect?

Note that this comment applies to other magic number (CSS property values duplicated/hardcoded in C++ code) of this commit.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think its possible unless we parse the entire CSS to a global object like a JSON object. That will be a whole new project in itself.

/* See resources/css/popup.css QHeaderView::section.
Take line-height + 5 padding top and bottom.
*/
return QSize(0, 34);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this value cannot be computed from values obtained from CSS, then you can at least minimize the maintenance burden by defining a few constants in a dedicated source file and cross referencing it with the css file so that at most 2 locations have to be updated if/when any of those values changes. For example

css_constants.h

namespace CSS
{

// Need a good explanation of why this file is needed and the logical connection
// of these values to their counterparts in the CSS files must be emphasized.
// A cross reference to each constant from this file must be put beside the respective
// property in the CSS file.

// QHeaderView::section:line-height
const int SUGGESTION_LINE_HEIGHT = 24;

// QHeaderView::section:padding-top
const int SUGGESTION_LINE_PADDING_TOP = 5;
}

and then

return QSize(0, CSS::SUGGESTION_LINE_HEIGHT + CSS::SUGGESTION_LINE_PADDING_TOP + CSS::SUGGESTION_LINE_PADDING_BOTTOM);

Note that the current value of 34 doesn't match the formula from the code comment and the actual CSS values (which rather evaluates to 39).

All other similar magic numbers introduced in C++ code by this PR must be eliminated in a similar way.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@veloman-yunkan I furthur propose we can use multi-level namespaces to further structure the CSS. If a file wants to use, for example, CSS::QTabBar::QWidget, they can do an aliasing to get a shorter name.

One question, why does it evaluate it to 39?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One question, why does it evaluate it to 39?

Your formula says line-height + 5 padding top and bottom

Relevant CSS is

QHeaderView::section {
    ...
    padding-top: 10px;
    ...
    padding-bottom: 5px;
    ...
    line-height: 24px;
    ...
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah.. I forgot to explain the padding top has an extra 5px. Will restructure this in the next PR with better explanations.

Comment on lines 6 to 70
void SuggestionListDelegate::paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
/* Paint without text and icon */
QStyleOptionViewItem opt(option);
QStyledItemDelegate::paint(painter, opt, QModelIndex());

paintIcon(painter, opt, index);
paintText(painter, opt, index);
}

void SuggestionListDelegate::paintIcon(QPainter *p,
const QStyleOptionViewItem &opt,
const QModelIndex &index) const
{
QRect pixmapRect = opt.rect;

/* See line-height&padding resources/css/popup.css QHeaderView::section.
We need to add 10px of padding to match header.
*/
QSize mapSize = QSize(24, 24);
auto pixmap = index.data(Qt::DecorationRole).value<QIcon>().pixmap(mapSize);
if (KiwixApp::isRightToLeft())
{
int rightEnd = pixmapRect.width() - mapSize.width();
pixmapRect.setX(pixmapRect.x() + rightEnd - 10);
}
else
pixmapRect.setX(pixmapRect.x() + 10);

pixmapRect.setY(pixmapRect.y() + (pixmapRect.height() - mapSize.height()) / 2);
pixmapRect.setSize(mapSize);
p->drawPixmap(pixmapRect, pixmap);
}

void SuggestionListDelegate::paintText(QPainter *p,
const QStyleOptionViewItem &opt,
const QModelIndex &index) const
{
auto& searchBar = KiwixApp::instance()->getSearchBar();
auto lineEditGeo = searchBar.getLineEdit().geometry();

/* See SearchBar border in resources/css/style.css. Align text with text in
line edit. Remove border from left() as completer is inside border.
*/
auto left = lineEditGeo.left() - 1;
QRect textRect = opt.rect;
if (KiwixApp::isRightToLeft())
{
/* Calculate the distance of right side of search bar to line edit as
text now starts on the right.
*/
auto searchGeo = searchBar.geometry();
auto right = searchGeo.width() - left - lineEditGeo.width();
textRect.setWidth(textRect.width() - right);
}
else
textRect.setX(textRect.x() + left);

int flag = {Qt::AlignVCenter | Qt::AlignLeading};
QString text = index.data(Qt::DisplayRole).toString();
p->drawText(textRect, flag, text);
return;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please elaborate in the commit message why custom painting of suggestions is needed, i.e. why it couldn't be solved with CSS. Hopefully, you'll find a better solution while trying to describe the problem.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, I had spent quite a lot of time to figure out how to do it by style and Qt simply does not provide any API to do this. They are drawing the elements manually themselves as well...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please prepare the next version of the PR so that custom drawing is localized in a few commits at the end so that that change can be easily excluded via a single git checkout. Then I will try to find a better solution.

@veloman-yunkan
Copy link
Collaborator

@veloman-yunkan It will largely depend on the scrolling behaviour. If we use one scroller for all suggestion groups, we can just add seperator rows in the model, then fetch equal amount from all.

If each group gets a scroller, we might need to replace qcompleter with a popup widget that contain two views.

The second one is the better option IMO andwhat I think we should be able to do. We seem to be controlling a major portion of the completing behaviour already.

Another option is to provide a "... load more ... " entry at the bottom of each group (but that's a different type of UI that doesn't - strictly speaking - qualify as infinite scrolling).

@ShaopengLin
Copy link
Collaborator Author

ShaopengLin commented Sep 30, 2024

@veloman-yunkan That was my previous approach, which indeed doesn't satisfy kelson's vision of infinite scrolling.

@kelson42
Copy link
Collaborator

kelson42 commented Oct 1, 2024

@veloman-yunkan That was my previous approach, which indeed doesn't satisfy kelson's vision of infinite scrolling.

@veloman-yunkan @ShaopengLin I have created #1194, at this stage I believe we should let it work like it is now.

@ShaopengLin
Copy link
Collaborator Author

But please don't actually split the PR - describe your proposal first and we'll proceed with it if promises to take us to our destination faster.

@veloman-yunkan A proposal I see now is to have:

  • UI improvements, which involves CSS constant management, popup behavior, etc. to one PR,
  • Endless scrolling.

This was what I had in mind when structuring this PR, where I do all the functionality changes, and then the UIUX changes.

@veloman-yunkan
Copy link
Collaborator

veloman-yunkan commented Oct 2, 2024

But please don't actually split the PR - describe your proposal first and we'll proceed with it if promises to take us to our destination faster.

@veloman-yunkan A proposal I see now is to have:

  • UI improvements, which involves CSS constant management, popup behavior, etc. to one PR,

  • Endless scrolling.

This was what I had in mind when structuring this PR, where I do all the functionality changes, and then the UIUX changes.

@ShaopengLin Go ahead with it!

@kelson42
Copy link
Collaborator

kelson42 commented Oct 7, 2024

What is the status here, now that we have two additional PRs?

@ShaopengLin
Copy link
Collaborator Author

@kelson42 I believe veloman is reviewing #1224

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants