The EmojiInputDialog re-uses emoji buttons to help with performance as
filters are applied / removed. The downside of pre-creating the buttons
is that it currently takes upwards of 600ms (on my machine) to load all
emoji icons from disk at once. This will only become worse over time as
more emoji are added.
To alleviate this, defer loading the icons until they are needed for
painting (i.e. come into view).
This patch implements rubber band selection in table view while clamping
the rubber band rect to the widget inner rect, matching the behavior of
IconView and ColumnsView.
Previously when selecting a column that was partially scrolled out of
view the rubber band rect would extend outside the widget inner rect.
This patch rewrites the implementation to be more readable and clamps
the rubber band rect to the widget inner rect to match the behavior of
IconView.
Previously the rubber band rect of IconView was not properly constrained
to the widget inner rect, leaving a one pixel gap on the bottom and
right side. This patch removes the gap by inflating the constraint rect
by one pixel on each axis.
Currently, LibGUI modifies the Ctrl+Alt+Space key event to instead
represent the emoji that was selected through EmojiInputDialog. This is
limited to a single code point.
For multiple code point emoji support, individual widgets now set a hook
to be notified of the emoji selection with a UTF-8 encoded string. This
replaces the previous set_accepts_emoji_input() method.
Most of the emoji are 7x10px (or close to that). But some are larger, on
the order of 128x128px. The icon used for the SerenityOS category is one
such large emoji, and must be scaled down to an appropriate size for
rendering.
Currently, we use code point values as a tie break when sorting emoji by
display order. When multiple code point emoji are supported, this will
become a bit awkward. Rather than dealing with varying code point length
while sorting, just set a maximum display order to ensure these are
placed at the end.
This has two advantages: First the picker no longer changes the active
window state of its parent. Visually this is an additional hint that the
dialog is "fragile" and will close on loss of focus. Second, because
it contains a search box, its own input won't be preempted by global
application shortcuts when typing (pending #15129). This is a problem
in apps like PixelPaint which use shortcuts without modifiers.
Instead of having to negate every focusable widget or textbox, let
windows override all their widgets. These two Dialogs now block
themselves and each other.
This patch fixes an issue for applications that contain actions without
a modifier (e.g. PixelPaint). Previously when pressing any key bound to
an action while the CommandPalette was visible the action was forwarded
to the parent instead of the CommandPalette.
Previously Menus set themselves as active input solely to make
sure CaptureInput modals would close, but this is a functional
half-truth. Menus don't actually use the active input role; they
preempt normal Windows during event handling instead.
Now the active input window is notified on preemption and Menus
can remain outside the active input concept. This lets us make
more granular choices about modal behavior. For now, the only
thing clients care about is menu preemption on popup.
Fixes windows which close on changes to active input closing
on their own context menus.
Instead of letting buttons determine the relative position
of their menus, a workaround only used by Statusbar segments,
open them all uniformly for a nice, consistent UI.
Passing a rect to popup() now routes to open_button_menu(), an
analog to open_menubar_menu(), which adjusts the menu's popup
position in the same way. Fixes button menus obscuring the buttons
which spawn them and jutting out at odd corners depending on screen
position.
in exclusive, checkable groups. Instead of merely setting the
button checked, call click() so buttons with registered actions
can activate. Fixes ActionGroups like FileManager's view type
checkables not activating when cycled with the keyboard.
Unlike regular buttons, unchecked checkables don't need to repaint
on MouseUp to feel responsive when clicking rapidly. In fact, this
can lead to a flickering effect when a bogus unchecked state gets
painted again before the button's checked one.
To prevent lag when the displayed code points are redrawn in support of
a search box, only create the GUI::Button objects for the emoji a single
time. Re-use those buttons when adding them to the dialog.
This will allow easily adding components such as a search box. Also,
increase the number of emoji per row. This does not fix the issue where
too many emoji will cause the dialog to grow limitlessly, but it looks a
bit more reasonable now with the number of emoji that we have.
This adds icons for folder paths ending in ".git". This adds 16x16 and
32x32 versions of a folder with a Git logo for both the closed and open
versions of the folder icon.
This patch adds the ability to select multiple entries in a column using
a rubber band selection. Currently the implementation is lacking support
for expanding a selection using the ctrl modifier.
This patch extracts logic for getting colum at an event position and for
getting an index in a column at an event position from
index_at_event_position into separate functions.
Since 5064b58 SpinBox buttons are disabled if value reaches the
min or max allowed. Consequently this swallows the final MouseUp
event, leaving the repeat timer running. Fixes SpinBoxes
{dec,inc}rementing their value in perpetuity after min/max value
is reached through button clicking.
When the value for a SpinBox equals the max, disable the increment
button. Functionally, clicking the button doesn't do anything because
the set_value() clamps the value to min/max and updates the textbox.
However it is still nice to indicate to the user that they've reached
the max. Same goes for minimum value and the decrement button.
Previously the value of the SpinBox is re-evaluated after every change
to the TextBox control. This leads to very unintuitive behavior such as
the user deleting the contents of the box and it having no
visible effect. This happens because the TextBox no longer has a valid
number and so gets reset to the current m_value of the SpinBox.
By defering the update of to the SpinBox value until focus leaves the
control we provide a much more intuitive experience with the text box.
We do still validate when a user types something that it parses to an
int. If it does not we delete the most recent character. This in effect
prevents non-numeric numbers from being entered.
Upon losing focus the value will be checked. If empty we set the SpinBox
value to the minimum allowed value.
With a new DragCopy cursor icon being used on accepted events, this
caused a 'false assumption' that everything can be dropped into
AbstractView.
This will now only happen if the View is editable, which still isn't
perfect, but at least the Settings app will no longer change cursors.
Also note that we won't get "drag move" events as the comment below
says, which disables automatic scrolling when dragging an element.
When the location currently displayed in FileManager is removed, find
the nearest existing parent path and open it in the window.
Without the fix, the FileManager window remained in the deleted
directory.
Changing the path in 'DirectoryView' object will automatically update
other components in the FileManager (breadcrumb bar, directory tree
view).
This commit fixes FileSystemModel behaviour when the root path of the
model has been deleted.
In this case, the model index resolved for the root path is invalid and
passing it to 'begin_delete_rows' would trigger assertion failure.
Instead of deleting all children rows one by one, we simply invalidate
the whole model.
Now they can be dismissed by clicking anywhere outside themselves,
including on their parent windows. This is a better default for
them since they don't have title bars to flash, and it's more
consistent with other frameless windows in the system.
Applications using the Vim emulation engine now support line-wise text
selection.
We already have support for character-wise text selection, by pressing
`v` from normal mode.
However now can also trigger line-wise text selection by pressing
`shift+v` from normal mode, and then using vertical motion commands
(e.g. `j` or `k`) to expand the selection. This is a standard vim
feature.
In visual line mode the following operations are supported:
* `escape`: back to normal mode
* `u`: convert to lowercase
* `U`: convert to uppercase
* `~`: toggle case
* `ctrl+d`: move down by 50% of page height
* `ctrl+u`: move up by 50% of page height
* `d` or `x`: delete selection
* `c`: change selection
* `y`: copy selection
* `page up`: move up by 100% of page height
* `page down`: move down by 100% of page height
Notably I didn't implement pressing `v` to go to regular
(character-wise) visual mode straight from visual line mode. This is
tricky to implement in the current code base, and there's an
alternative, which is to take a detour via normal mode.