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 racket-dev+unsubscr...@googlegroups.com.
To post to this group, send email to racket-dev@googlegroups.com.
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.

Reply via email to