When no emojis are found for the current search, Emojier switches to the
'All' page, but doesn't hide the 'Clear History' button, doesn't show the
'Skin Tone' button, and displays an incorrect placeholder message.
Arrow Down from the search field goes to the main gridView, but Arrow
Up from there doesn't go back. Our previous implementation using
KeyNavigation broke during refactoring, and was half-replaced.
Instead, fix the KeyNavigation, and make the handover pattern a bit
more obvious with a comment (similar to how we have them in a couple
of other places)
Most emojis and their variants in the "People" category follow the order
"Person, Man, Woman". But for a few, the order is random.
Also, for the "Select Variant" pop-up feature, Emojier expects variants
with mixed skin tones to be placed near the base emoji or variants with
only one skin tone. Emoji Version 17 adds six emojis that do not follow
this ordering, breaking the feature.
Sort the emojis by this pattern.
You can now zoom with Ctrl+scroll, keyboard shortcuts, and toolbar buttons.
This enlarges or shrinks the cells of the emoji grid, clamped between 1.5 and
8 grid units. Plain scrolling is unaffected and still scrolls the list.
The glyph font size is derived from the cell height instead of a fixed point
size, so it scales with the zoom (this also lets the inert minimumPointSize be
dropped). Size changes are coalesced on a short throttle so a fast wheel spin
triggers at most one relayout per frame instead of one per event. The skin-tone
variant popup tracks the same size.
Emojier tries to set the minimum window height to be large enough to fit
the full sidebar, to avoid having it be covered up by a scroll bar. The
required minimum size for this does not seem to be available (the
implicitHeight changes with window size), so we compute it from the
contentHeight and adjust for differences between explicit and implicit
header sizes. The problem now is that the explicit header size may be
fractional, but windows can't be; at least in some situations the window
ends up too small by a third of a pixel or so, which makes it uselessly
scrollable - the scrollbar is shown, but can't actually be moved because
we can't move it by fractions of a pixel (or even if we can, that would
be completely invisible).
Instead, round up the explicit header size to the nearest full pixel.
BUG: 523090
FIXED-IN: 6.7.4
All the functionality required by the toolbar here is provided by
Kirigami, with some of it working better than the implementation here.
So make use of the standardised solutions, reducing code and making some
things such as the "skin tone" menu button work better.
The only drawback is that we can no longer increase the size of the selected
skin tone emoji, because that would require a completely custom delegate
that would need to re-implement all the logic of the menu button again.
This commit removes emojis with mixed skin tone modifiers from the main
view. Instead, they are grouped in a dialog and filtered by the current
preferred skin tone.
This change adds translation contexts to all translatable strings in qml
files that did not have any. Occasionally, the existing translation
contexts are updated for consistency with the newly added ones.
The string themselves are unchanged, save for one instance where the
Accessible strings were somewhat awkward and were a bit streamlined, and
one set of accessible strings in PanelConfiguration that were not
marked as translatable, but are now.
Co-authored-by: Nate Graham <nate@kde.org>
The 'People and Body' category, is with 2261 emojis, by far the category
with the most emojis. Most of these are variants in skin tone.
By hiding 1615 of these variants and by showing only one type of variant
at a time, it's easier to discover emojis in the category/all view.
Amends 2d36238182
The clear history button in the page header should only show on the
Recent page, but a flipped boolean value made it appear also for
regular category pages (but not the All Emojis page).
This change restores the original behavior.
The emoji GridView currently uses the highlighted delegate style for the
currentItem; in QQC2 a solid color. We typically use this style to show
some persistent state (e.g. the currently open page from a sidebar with
delegates), and for simple selection of items in a list or grid we use
the regular view highlight (in QQC2, currently a solid outline with a
transparent background).
This change switches emojier to the second style.
All page loading actions in Emojier are implemented as replacing the
current page with a new one. This causes a warning on startup (as we're
trying to replace a page on an empty pageStack) and is generally not
necessary, as all the pages are the same, they just differ in some
properties.
So we can just create the page once and have the switching actions swap
out the relevant bits in that page, as we already do when a page is
switching to searching all data when nothing is found in the selected
category. This resolves the runtime warnings, saves the overhead of
having to create new pages, and allows a small interface convenience -
the user can now type a search term and then click the sidebar to choose
a category and only show results from that category. Before, the user's
search term would be cleared by the new page being loaded.
Setting the minimumHeight for the window causes a binding loop. The
precise cause is unclear, but it involves depending on both height and
implicitHeight, either by itself is fine.
We can avoid this by setting the binding imperatively in
Component.onCompleted.
The globalDrawer's collapsible property is bound to
!topContent.activeFocus. topContent is not an item but a list of
QObjects, so it does not have an activeFocus property, so this
is just !undefined. It's also not clear what this is even supposed
to do, the app does not set any topContent for the globalDrawer so
there's nothing in the list that could have activeFocus.
Just set it to always true.
The model, category, and page title of the CategoryPages are all
set from Emojier.qml... except when the user searches in a restricted
emoji set and the app switches to full search, then it happens from
inside CategoryPage. This means that the full model will have to be
either be accessed through an unqualified lookup from there or
explicitly passed to the page, and feels like improper separation of
concerns.
Instead, we provide a signal by which the page can request being
switched to the full data set, and handle all cases of setting the
data set and page title in one place, Emojier.qml.
Emojier's handling of copying is implemented in three different places
spread across both source files. As we want to modify the recents model
and access the window to show passive notifications, it makes sense to
handle this all centrally in the main app, and have the active page
signal it as needed. This allows for a less direct coupling of intent
and implementation, and helps reduce the coupling between both
components while reducing implementation duplication.
Emojier's category page sets default focus on the search field and sets
a forwardTo on the grid view to pass arrow keys and other interaction
keys that should operate on the view or delegate there. This works, but
means that focus always remains on the search field, and screen readers
are not informed about the currently selected item, giving no feedback
to the user and letting the explicitly set accessible properties on the
delegate go to waste.
Instead, we switch to regular handling where the delegate actually
receives focus, and set a forwardTo in the other direction, so that keys
the view/delgate do not handle are passed to the search field, allowing
modification of the search string from outside the search field. We
replace the remnant of a key passing mechanism, as using a forward
allows us to centralize the search modification behavior in one place,
rather than having two implementations that work differently. We also
make the Clear History button (sometimes) next to the search field
arrow key-accessible.
The delegate for creating category actions is its own small qml file.
Some parts of the action require access to data from the caller, which
means unqualified lookups or passing lots of extra information to the
delegate. Some of what is there is also essentially duplicated (such
as setting a string property category that is exactly the same as the
already existing property modelData.
It's easier, clearer, and less code to just merge the delegate into the
single place where it's used.
Emojier uses injected properties for its delegates. This is not
recommended and causes linter warnings.
This change switches this to required properties, which also allows
us to use ComponentBehavior: Bound to further reduce linter warnings.
Low-hanging fruit:
- qualify access where easily possible
- use correct number of parameters
- remove unused imports/add required imports
- explicit types
qmllint fails to properly handle the Qt.application property
(QTBUG-119643). Upstream recommends using the Application singleton
instead, as it resolves issues with the types (which are variable
depending on the imported modules) and is more accessible for tooling
(codereview qtdeclarative/+/350080). The main use for Qt.application
in p-d is to access the layoutDirection.
This change ports p-d to using the Application singleton.