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.
This adds two new icons for browser context menu items "Close Other
Tabs" and "Download".
This adds existing icons where they were missing in context menu items.
Previously we allowed entering any day value greater than one. With this
patch the maximum input value is dynamic based on the selected month and
year.
Currently, LibUnicodeData contains the generated UCD and CLDR data. Move
the UCD data to the main LibUnicode library, and rename LibUnicodeData
to LibLocaleData. This is another prepatory change to migrate to
LibLocale.
Vectorscopes are a standard tool in professional video/film color
grading. *Very* simply, the Vectorscope shows image colors with hue as
the angle and saturation as the radius; brightness for each point in the
scope is determined by the number of "color vectors" at that point. More
specifically, the Vectorscope shows a 2D UV histogram of the image,
where U and V are the chroma ("color") channels of the image.
Co-authored-by: MacDue <macdue@dueutil.tech>
The histogram is perfectly fine with being drawn at any size, but the
code currently fixes its height to 65. Once the histogram is in a
subclass and several GML things around it change, the fixed height
breaks, so we move the height specification to GML. Additionally, the
container is specified to shrink as much as possible, alleviating a
hard-coded UI size. The user can now change histogram height in GML,
which is a lot more obvious.
Layer::erase_selection used to erase the entire bounding box of the
selection. With the add/subtract merge modes for the selection tool it
is possible to create selections which are not rectangular. This leads
to deleting pixels that were not selected.
This change adjusts the erase behavior to walk the selection rect and
check if a pixel is selected or not before deleting.
Wand Selection tool uses similar logic to the Bucket Tool. Flood filling
and threshold calculations to determine the affected area just in this
case we do not set the pixels of the selected area, instead we use
those pixels to alter the selection mask.
In the future we can probably abstract out the shared flood logic so
both tools can share the code.
Specializing point_position_to_preferred_cell for the
RectangleSelectTool as it selects a new cells with a rounding
behavior instead of a flooring behavior
This is done to allow querying the current active tool inside the
event_with_pan_and_scale_applied and event_adjusted_for_layer
functions without risking a null pointer dereference
This method is used to point a position at the preferred pixel of
the image. Certain tools may want to specify a different preferred
pixel for the same input position.
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).
And adjust some GML properties. Since a808cfa, splitters grow
opportunistically. Setting them to fixed sizes now quite literally
fixes them in place. Fixes immovable splitters missed in the
aforementioned commit.
When cropping to content with a layer not positioned at 0,0 the moved
layers content disappeared and the layers position was not updated
according to the crop offset.
There's probably an easier/more efficient way, but for my testcase this
improves the behavior.
Intrinsics, i.e. mostly constructor and prototype objects, but also
things like empty and new object shape now live on a new heap-allocated
JS::Intrinsics object, thus completing the long journey of taking all
the magic away from the global object.
This represents the Realm's [[Intrinsics]] slot in the spec and matches
its existing [[GlobalObject]] / [[GlobalEnv]] slots in terms of
architecture.
In the majority of cases it should now be possibly to fully allocate a
regular object without the global object existing, and in fact that's
what we do now - the realm is allocated before the global object, and
the intrinsics between both :^)
with the CaptureInput WindowMode. This mode will serve the same
function as accessories: redirecting input while allowing parent
windows to remain active.
with the RenderAbove WindowMode. This mode will ensure child
windows always draw above their parents, even when focus is lost.
RenderAbove modals are automatically themed the same as the old
ToolWindows. Fixes ToolWindows rendering above ALL normal windows,
regardless of parent. We can't rely on WindowType to create these
sort of effects because of WindowManager's strict display hierarchy.
The new layout system conveniently calculates these for us now.
In the case of Mandelbrot where it needs to be overriden, make
sure to disable obey min widget size first. In EmojiInputDialog's
case, the window needs to be resized instead to center correctly.
This adds menu item icons for Add Mask, Flatten Image, Fit Image To
View, and Generic 5x5 Convolution.
This modifies the menu item icon for Swap Colors to make the action more
obvious and improve accessibility.
This command finds the smallest non-empty content bounding rect
by looking for the outermost non-transparent pixels in the image,
and then crops the image to that rect.
It's implemented in a pretty naive way, but it's a start. :^)
The basic idea is that a global object cannot just come out of nowhere,
it must be associated to a realm - so get it from there, if needed.
This is to enforce the changes from all the previous commits by not
handing out global objects unless you actually have an initialized
realm (either stored somewhere, or the VM's current realm).
- Prefer VM::current_realm() over GlobalObject::associated_realm()
- Prefer VM::heap() over GlobalObject::heap()
- Prefer Cell::vm() over Cell::global_object()
- Prefer Wrapper::vm() over Wrapper::global_object()
- Inline Realm::global_object() calls used to access intrinsics as they
will later perform a direct lookup without going through the global
object
This is needed so that the allocated NativeFunction receives the correct
realm, usually forwarded from the Object's initialize() function, rather
than using the current realm.
Global object initialization is tightly coupled to realm creation, so
simply pass it to the function instead of relying on the non-standard
'associated realm' concept, which I'd like to remove later.
This works essentially the same way as regular Object::initialize() now.
Additionally this allows us to forward the realm to GlobalObject's
add_constructor() / initialize_constructor() helpers, so they set the
correct realm on the allocated constructor function object.