While checking racket's gui possibilities, I've noticed that widgets (in
both amount and config) are limited - yes, they can do much enough, but
using somewhat different (yet minimalistic) style we can do way more while
dropping most of those widgets.
Please note that this is only an idea which seems (at least for me) nice
enough to be implemented when you see such frameworks as Qt Quick or
Flutter.
1. Canvas/DC changes
1.1: Canvas clipping
Currently, if we want to limit our drawing to a square, we use bitmap-dc%
class, which creates a new bitmap which will be then blitted to the canvas
or another bitmap.
This can be simplified (for users though) by making a clip operation
similar to the one found in nanovg.
Ideally it would use opengl stencil buffer or similar techniques, so we
could clip non-square shapes, but as I can see, racket/gui's canvas does
not use low-level graphics APIs directly.
Although it is probably possible to allow non-rectangular shapes in other
way.
Ideally clip operations should be stored in a stack (aka list (push=cons,
peek=car, pop=cdr) in terms of lisp) so you could restore previous clip
state - that would allow making multiple widgets which clip their drawing
context.
2. Windowing changes
2.1: Window transparency
Ideally it would be possible if we could make a window partially
transparent (in some places) so if user wants to have CSD, he could make
slightly better window borders. Although this should not be in priority.
2.2: Custom window shape
Supported by most operating systems, this could allow drawing shadows
around windows in window managers which do not draw shadows for windows
which use CSD, this could also allow passing clicks through context menu
windows, like that is done in Gtk3’s popovers.
2.3: Dragging windows
When user makes a click inside of a window, there should be an option to
initiate a drag/resize operation – that is definitely possible in Windows
(seen at least in WPF, although I do not know if Win32 API supports that)
and Linux (should be supported at least by GDK. If not, accessing X11 APIs
directly is possible). Please note that this feature is necessary for fast
window dragging when using CSD.
3. Core GUI library
3.1: Drawing
The GUI library i suggest implementing is based on a canvas (like QtGui in
Qt Quick/Widgets or Skia in Flutter, Chrome, or Android).
3.2: Views
Views are similar to Android’s activities or WPF/UWP’s windows – they can
be navigated to or closed to go back to the previous view. Each view has an
own style config as shown below.
3.3: Build context
After elements (see later) are created, they should be “built” so they know
their actual appearance and content. Build operation should be invoked once
drawn data (for example, text or image) or style config in the context
changes. Build operation also creates and builds child elements as shown in
2.4.
Context definition might look like that:
(define build-context%
(class object%
(super-new)
(init-field ; values necessary for determining element positions. For
example,
; that could be done using a list of geometries - when we
are
; inside of a container, we push a new item to the list;
when we
; leave the container, we pop an item from the list; when
we finish
; a widget, we update the topmost item so previously used
space cannot
; be used.
)))
While style config definition might look like this:
(define style-config%
(class object%
(super-new)
(init-field [primary-color (make-color ...)]
[secondary-color (make-color ...)]
[accent-color (make-color ...)]
[background-color (make-color ...)]
[text-color (make-color ...)]
[text-font (make-font …)]))
Please note that style config stores brand-specific values and not all view
authors might want to use other’s brand colors. This means that each value
should be replaceable with a ‘parent value or similar, so widgets and other
views can inherit parent view’s style config values.
3.4: Elements
There could be a small amount of premade elements which can be used in
building more complex elements and widgets. I suggest using: text element,
pane element (similar to div in html, can use styles from style config
and/or use own values, including stuff like border width/radius, shadow,
etc), image element, video element, text input element (possibly in 2
variations – text line and text editor), view element to embed a view as a
part of a current one, and canvas element for more complex rendering (like
combo boxes).
make-element function will create a new element with a build callback which
creates a portion of other elements, similar to how its done in Flutter or
React.
(define (make-element [build-callback])
...)
(make-element #:build-callback
(lambda ()
(new pane%
(new text% [text "Foo"]))))
4: What this will allow
4.1: Implementing beautiful widget sets like those defined in material or
fluent design specifications.
4.2: Easily implementing tons of custom widgets.
4.3: Building brand-flavored applications and views to be used in other
applications, which could be easily integrated with other application's
theme.
For example, we are writing a contacts application. While having an own
launcher and a widow, it could provide views which can be used in another
application to show, for example, a contact card, a contact list, etc. This
embedded view widget could also use parts of host application theme while
keeping bits of brand-specific stuff.
--
You received this message because you are subscribed to the Google Groups
"Racket Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/racket-dev/392a8e10-962f-4fb2-ae72-af22fcdc205a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.