Git Product home page Git Product logo

alloy's People

Contributors

bmiww avatar hellseher avatar paulapatience avatar scymtym avatar shinmera avatar trashtalk217 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alloy's Issues

Joining cells in grid-layout (feature request)

I've been playing around with the grid-layout to try and make a calculator and I've ran into something the toolkit is missing. I'd like to have a layout-element spanning multiple cells. I've been trying to think this through and I've been reading the grid-layout code, but I don't see a simple solution. My first idea was to have the array that stores the layout-elements be allowed to have copies which are deconstructed later into full elements. I'm wording this badly, but an example will show it better:

[ A, A, A, A
  B, C, D, E,
  F, F, G, H,
  F, F, I, J ]

But it seems that I can only have a layout-element once in the grid-layout, so this isn't going to fly.

I want to add this feature myself, but I would like some pointers on how to approach this problem. Any help would be appreciated.

System "sdf/bmfont" not found

Hello!
I had tried to install alloy-examples from Quicklisp, but I had an error:
System "sdf/bmfont" not found
What I need to do? Can I help to fix this problem?
Thanks

[feature request/idea] layout item more easily with a layout macro

Having a macro to do the heavy lifting for adding items to a layout, replaces and generates the same code, perhaps could be a good idead i.e originally:

...
      (alloy:enter "Frequency" l2 :row 2 :col 0)
      (alloy:enter freq l2 :row 2 :col 1)
      (alloy:enter "Amplitude" l2 :row 1 :col 0)
      (alloy:enter amps l2 :row 1 :col 1)
      (alloy:enter "Phase" l2 :row 0 :col 0)
      (alloy:enter phas l2 :row 0 :col 1)
...

now to:

(let ((l2 (make-instance 'alloy:grid-layout :layout-parent root-layout)))
      (alloy:layout-macro
       l2
       (("Frequency" freq)
        ("Amplitude" amps)
        ("Phase" phas))))

Macro details/specs:

(defmacro layout-macro (layout-obj layout-structure-lst)
 ... ;; implementation detail
)

This macro would:

  • determine the dimension of structure-lst
  • cases where dimension doesn't match, such as '((one-object) (two objects)), will be handled accordingly
  • generates the code which this macro replaces (see first code snippet)

GLFW call to SET-WINDOW-ICON failed with FEATURE-UNAVAILABLE on Wayland

System Info

Linux Distro: Fedora Silverblue 39 (Gnome 45.5) & Gentoo (Sway 1.8.1-r2)
SBCL: 2.3.6-2 (Fedora Silverblue) & 2.3.5 (Gentoo)

Expected Behavior

i can run alloy-example

Current Behavior

REPL Buffer

CL-USER> (org.shirakumo.alloy.examples:simple-window)
STYLE-WARNING:
   slot names with the same SYMBOL-NAME but different SYMBOL-PACKAGE (possible
   package problem) for class
   #<STANDARD-CLASS ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:WINDOW>:
       (ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW::ICON ORG.SHIRAKUMO.FRAF.GLFW:ICON)
       (ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:CURSOR
        ORG.SHIRAKUMO.FRAF.GLFW:CURSOR)
STYLE-WARNING:
   slot names with the same SYMBOL-NAME but different SYMBOL-PACKAGE (possible
   package problem) for class
   #<STANDARD-CLASS ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:WINDOW>:
       (ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW::ICON ORG.SHIRAKUMO.FRAF.GLFW:ICON)
       (ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:CURSOR
        ORG.SHIRAKUMO.FRAF.GLFW:CURSOR)
; Debugger entered on #<ORG.SHIRAKUMO.FRAF.GLFW:GLFW-ERROR {1002687103}>

Debugger Buffer

GLFW call to SET-WINDOW-ICON failed with FEATURE-UNAVAILABLE:
  Wayland: The platform does not support setting the window icon
   [Condition of type ORG.SHIRAKUMO.FRAF.GLFW:GLFW-ERROR]

Restarts:
 0: [RETRY] Retry SLY mREPL evaluation request.
 1: [*ABORT] Return to SLY's top level.
 2: [ABORT] abort thread (#<THREAD tid=4231 "sly-channel-1-mrepl-remote-1" RUNNING {10010B0003}>)

Backtrace:
 0: ((:METHOD (SETF ORG.SHIRAKUMO.FRAF.GLFW:ICON) :BEFORE (T ORG.SHIRAKUMO.FRAF.GLFW:WINDOW)) NIL #<ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:WINDOW (ORG.SHIRAKUMO.ALLOY:EXTENT 0.0px 0.0px 0.0px 0.0px) {1005F338..
      Locals:
        ORG.SHIRAKUMO.FRAF.GLFW::ICONS = NIL
        ORG.SHIRAKUMO.FRAF.GLFW::IMAGES = #.(SB-SYS:INT-SAP #X7F8F3CF34E90)
        ORG.SHIRAKUMO.FRAF.GLFW:WINDOW = #<ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:WINDOW (ORG.SHIRAKUMO.ALLOY:EXTENT 0.0px 0.0px 0.0px 0.0px) {1005F338D3}>
 1: ((SB-PCL::EMF (SETF ORG.SHIRAKUMO.FRAF.GLFW:ICON)) #<unused argument> #<unused argument> NIL #<ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:WINDOW (ORG.SHIRAKUMO.ALLOY:EXTENT 0.0px 0.0px 0.0px 0.0px) {1005F338D..
      Locals:
        SB-PCL::.ARG0. = NIL
        SB-PCL::.ARG1. = #<ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:WINDOW (ORG.SHIRAKUMO.ALLOY:EXTENT 0.0px 0.0px 0.0px 0.0px) {1005F338D3}>
 2: ((SB-PCL::EMF (SETF ORG.SHIRAKUMO.ALLOY.WINDOWING:ICON)) #<unused argument> #<unused argument> NIL #<ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:WINDOW (ORG.SHIRAKUMO.ALLOY:EXTENT 0.0px 0.0px 0.0px 0.0px) {100..
      Locals:
        SB-PCL::.ARG0. = NIL
        SB-PCL::.ARG1. = #<ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:WINDOW (ORG.SHIRAKUMO.ALLOY:EXTENT 0.0px 0.0px 0.0px 0.0px) {1005F338D3}>
 3: ((:METHOD ORG.SHIRAKUMO.ALLOY.WINDOWING:MAKE-WINDOW (ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:SCREEN)) #<ORG.SHIRAKUMO.ALLOY.EXAMPLES::SCREEN 1x1 HIDDEN @7F8F3C253A50> :TITLE NIL :ICON NIL :BOUNDS NIL :DECO..
      Locals:
        SB-PCL::.CLASS-ARG. = ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:WINDOW
        #:.DEFAULTING-TEMP. = NIL
        #:.DEFAULTING-TEMP.#1 = NIL
        #:.DEFAULTING-TEMP.#2 = NIL
        #:.DEFAULTING-TEMP.#3 = :NORMAL
        #:.DEFAULTING-TEMP.#4 = NIL
        #:.DEFAULTING-TEMP.#5 = NIL
        ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW::BACKGROUND-COLOR = (ORG.SHIRAKUMO.ALLOY.COLORED:RGB 0.0 0.0 0.0 1.0)
        ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW::DECORATED-P = T
        #:N-SUPPLIED-10 = 0
        #:N-SUPPLIED-8 = 0
        #:N-SUPPLIED-9 = 0
        #:NEW1 = NIL
        ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW::RESIZABLE-P = T
        ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:SCREEN = #<ORG.SHIRAKUMO.ALLOY.EXAMPLES::SCREEN 1x1 HIDDEN @7F8F3C253A50>
        ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:WINDOW = #<ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW:WINDOW (ORG.SHIRAKUMO.ALLOY:EXTENT 0.0px 0.0px 0.0px 0.0px) {1005F338D3}>
 4: ((FLET "THUNK0" :IN ORG.SHIRAKUMO.ALLOY.EXAMPLES:SIMPLE-WINDOW) #<ORG.SHIRAKUMO.ALLOY.EXAMPLES::SCREEN 1x1 HIDDEN @7F8F3C253A50>)
      Locals:
        SCREEN = #<ORG.SHIRAKUMO.ALLOY.EXAMPLES::SCREEN 1x1 HIDDEN @7F8F3C253A50>
 5: ((FLET "INIT2" :IN ORG.SHIRAKUMO.ALLOY.EXAMPLES:SIMPLE-WINDOW) #<ORG.SHIRAKUMO.ALLOY.EXAMPLES::SCREEN 1x1 HIDDEN @7F8F3C253A50>)
      Locals:
        SB-C::.ANONYMOUS. = #<ORG.SHIRAKUMO.ALLOY.EXAMPLES::SCREEN 1x1 HIDDEN @7F8F3C253A50>
 6: (ORG.SHIRAKUMO.ALLOY.RENDERERS.GLFW::CALL-WITH-SCREEN #<FUNCTION (FLET "INIT2" :IN ORG.SHIRAKUMO.ALLOY.EXAMPLES:SIMPLE-WINDOW) {53D8B06B}> ORG.SHIRAKUMO.ALLOY.EXAMPLES::SCREEN :BASE-SCALE 2.0)
      Locals:
        FUNCTION = #<FUNCTION (FLET "INIT2" :IN ORG.SHIRAKUMO.ALLOY.EXAMPLES:SIMPLE-WINDOW) {53D8B06B}>
        #:G5 = ORG.SHIRAKUMO.ALLOY.EXAMPLES::SCREEN
        SCREEN = #<ORG.SHIRAKUMO.ALLOY.EXAMPLES::SCREEN 1x1 HIDDEN @7F8F3C253A50>
        START = 135214565
        SB-DEBUG::MORE = (:BASE-SCALE 2.0)
 7: (SB-INT:SIMPLE-EVAL-IN-LEXENV (ORG.SHIRAKUMO.ALLOY.EXAMPLES:SIMPLE-WINDOW) #<NULL-LEXENV>)
      Locals:
        SB-KERNEL:LEXENV = #<NULL-LEXENV>
        SB-IMPL::ORIGINAL-EXP = (ORG.SHIRAKUMO.ALLOY.EXAMPLES:SIMPLE-WINDOW)
 8: (EVAL (ORG.SHIRAKUMO.ALLOY.EXAMPLES:SIMPLE-WINDOW))
      Locals:
        SB-IMPL::ORIGINAL-EXP = (ORG.SHIRAKUMO.ALLOY.EXAMPLES:SIMPLE-WINDOW)
 9: ((LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1))
      Locals:
        SLYNK-MREPL::FORM = (ORG.SHIRAKUMO.ALLOY.EXAMPLES:SIMPLE-WINDOW)
        SLYNK-MREPL::IN = #<SB-IMPL::STRING-INPUT-STREAM {7F8F435FDE13}>
10: (SLYNK::CALL-WITH-RETRY-RESTART "Retry SLY mREPL evaluation request." #<FUNCTION (LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1) {10032492AB}>)
      Locals:
        MSG = "Retry SLY mREPL evaluation request."
        THUNK = #<FUNCTION (LAMBDA () :IN SLYNK-MREPL::MREPL-EVAL-1) {10032492AB}>
11: ((LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1))
      [No Locals]
12: ((LAMBDA NIL :IN SLYNK::CALL-WITH-LISTENER))
      Locals:
        SB-C::OBJECT = #<SLYNK-MREPL::MREPL mrepl-1-1>
        SLYNK::SAVING = NIL
13: (SLYNK::CALL-WITH-BINDINGS ((*PACKAGE* . #<PACKAGE "COMMON-LISP-USER">) (*DEFAULT-PATHNAME-DEFAULTS* . #P"/var/home/adivin/") (* . #1=(ALLOY-EXAMPLES)) (** . #<QL-DIST:DIST shirakumo 2024.02.29-15.16...
      Locals:
        ALIST = ((*PACKAGE* . #<PACKAGE "COMMON-LISP-USER">) (*DEFAULT-PATHNAME-DEFAULTS* . #P"/var/home/adivin/") (* ALLOY-EXAMPLES) (** . #<QL-DIST:DIST shirakumo 2024.02.29-15.16.04>) (***) (/ (ALLOY-EXAMPLES)) ..)
        FUN = #<FUNCTION (LAMBDA () :IN SLYNK::CALL-WITH-LISTENER) {100324927B}>
14: (SLYNK-MREPL::MREPL-EVAL-1 #<SLYNK-MREPL::MREPL mrepl-1-1> "(org.shirakumo.alloy.examples:simple-window)")
      Locals:
        REPL = #<SLYNK-MREPL::MREPL mrepl-1-1>
        STRING = "(org.shirakumo.alloy.examples:simple-window)"
15: (SLYNK-MREPL::MREPL-EVAL #<SLYNK-MREPL::MREPL mrepl-1-1> "(org.shirakumo.alloy.examples:simple-window)")
      Locals:
        ABORTED = #<ORG.SHIRAKUMO.FRAF.GLFW:GLFW-ERROR {1002687103}>
        REPL = #<SLYNK-MREPL::MREPL mrepl-1-1>
        RESULTS = NIL
        STRING = "(org.shirakumo.alloy.examples:simple-window)"
16: (SLYNK:PROCESS-REQUESTS NIL)
      Locals:
        TIMEOUT = NIL
      Catch-tags:
        SLYNK::STOP-PROCESSING
17: ((LAMBDA NIL :IN SLYNK::SPAWN-CHANNEL-THREAD))
      Locals:
        SLYNK::CHANNEL = #<SLYNK-MREPL::MREPL mrepl-1-1>
18: ((LAMBDA NIL :IN SLYNK::SPAWN-CHANNEL-THREAD))
      Locals:
        SLYNK::CHANNEL = #<SLYNK-MREPL::MREPL mrepl-1-1>
        SLYNK::CONNECTION = #<SLYNK::MULTITHREADED-CONNECTION {1004522E63}>
19: (SLYNK-SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SLYNK:SLYNK-DEBUGGER-HOOK> #<FUNCTION (LAMBDA NIL :IN SLYNK::SPAWN-CHANNEL-THREAD) {10016F000B}>)
      Locals:
        CONTINUATION = #<FUNCTION (LAMBDA () :IN SLYNK::SPAWN-CHANNEL-THREAD) {10016F000B}>
        HOOK = #<FUNCTION SLYNK:SLYNK-DEBUGGER-HOOK>
20: ((FLET SLYNK-BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/var/home/adivin/.emacs.d/elpaca/repos/sly/slynk/backend/sbcl.lisp") #<FUNCTION SLYNK:SLYNK-DEBUGGER-HOOK> #<FUNCTION (LAMBDA NIL :IN SLYNK::SPAWN-CHA..
      Locals:
        SLYNK-SBCL::FUN = #<FUNCTION (LAMBDA () :IN SLYNK::SPAWN-CHANNEL-THREAD) {10016F000B}>
        SLYNK-SBCL::HOOK = #<FUNCTION SLYNK:SLYNK-DEBUGGER-HOOK>
21: ((LAMBDA NIL :IN SLYNK::CALL-WITH-LISTENER))
      Locals:
        SB-C::OBJECT = #<SLYNK-MREPL::MREPL mrepl-1-1>
        SLYNK::SAVING = NIL
22: (SLYNK::CALL-WITH-BINDINGS ((*PACKAGE* . #<PACKAGE "COMMON-LISP-USER">) (*DEFAULT-PATHNAME-DEFAULTS* . #P"/var/home/adivin/") (* . #1=(ALLOY-EXAMPLES)) (** . #<QL-DIST:DIST shirakumo 2024.02.29-15.16...
      Locals:
        ALIST = ((*PACKAGE* . #<PACKAGE "COMMON-LISP-USER">) (*DEFAULT-PATHNAME-DEFAULTS* . #P"/var/home/adivin/") (* ALLOY-EXAMPLES) (** . #<QL-DIST:DIST shirakumo 2024.02.29-15.16.04>) (***) (/ (ALLOY-EXAMPLES)) ..)
        FUN = #<FUNCTION (LAMBDA () :IN SLYNK::CALL-WITH-LISTENER) {10016F005B}>
23: ((LAMBDA NIL :IN SLYNK::SPAWN-CHANNEL-THREAD))
      Locals:
        SLYNK::CONNECTION = #<SLYNK::MULTITHREADED-CONNECTION {1004522E63}>
24: ((FLET SB-UNIX::BODY :IN SB-THREAD::RUN))
      [No Locals]
      Catch-tags:
        SB-THREAD::%RETURN-FROM-THREAD
25: ((FLET "WITHOUT-INTERRUPTS-BODY-172" :IN SB-THREAD::RUN))
      [No Locals]
26: ((FLET SB-UNIX::BODY :IN SB-THREAD::RUN))
      [No Locals]
      Catch-tags:
        SB-THREAD::%ABORT-THREAD
        SB-IMPL::%END-OF-THE-WORLD
        SB-INT:TOPLEVEL-CATCHER
27: ((FLET "WITHOUT-INTERRUPTS-BODY-165" :IN SB-THREAD::RUN))
      [No Locals]
28: (SB-THREAD::RUN)
      [No Locals]
29: ("foreign function: call_into_lisp_")
      [No Locals]

Steps to Reproduce

  1. use Wayland Gnome or Sway
  2. open sly in Emacs
  3. run (ql-dist:install-dist "http://dist.shirakumo.org/shirakumo.txt")
  4. run (ql:quickload 'alloy-examples)
  5. run (org.shirakumo.alloy.examples:simple-window)

Alloy on Mac Osx

The example on glfw, doesn't even start an window... Perhaps alloy is not supported on Mac Osx, for some reasons?
There is no error either. But cl-glfw3 is fine, the example basic-window ran fine.

Graphical cursor bug with textboxes

Problem: https://imgur.com/a/aRBL3MX

The cursor is not behaving nicely for me, it doesn't stick to the text but charges ahead.

Code I used in the examples/window.lisp file:

(define-example wheel-test (screen)
  (let* ((window (windowing:make-window screen))
         (focus (make-instance 'alloy:focus-list :focus-parent window))
         (layout (make-instance 'alloy:vertical-linear-layout :layout-parent window))
         (value 10)
         (text "Hello there!")
         (wheel (alloy:represent value 'alloy:wheel))
         (input (alloy:represent text 'alloy:input-box)))
    (alloy:enter wheel layout)
    (alloy:enter wheel focus)
    (alloy:enter input layout)
    (alloy:enter input focus)))

I've looked throught the codebase myself and I've isolated the problem to the renderer. Nothing seemed to be wrong in the components themselve. Sadly, I've not yet gotten the courage to dig into renderer side of things so I thought I'd make this an issue instead of a pull request.

Plot out of bounds (BUG)

When you have a plot with a specified y-range and data that falls out of that range the visual representation of the plot falls outside of the bounds of the component.

Example

(define-example plot (screen)
  (let* ((window (windowing:make-window screen :min-size (alloy:px-size 300 300)))
         (focus (make-instance 'alloy:focus-list :focus-parent window))
         (layout (make-instance 'alloy:vertical-linear-layout :layout-parent window))
         (button (alloy:represent "Hello" 'alloy:button))
         (parabola (make-array 100 :initial-contents (loop for i from 0 below 100 collect (- (* i i) 10))))
         (plot (alloy:represent parabola
                                'alloy:plot
                                :x-range '(0 . 100)
                                :y-range '(0 . 100))))
    (alloy:enter button layout)
    (alloy:enter plot layout)
    (alloy:enter button focus)
    (alloy:enter plot focus)))

I've been looking if there was a way to do this without altering the code a lot. But I haven't found it yet. I'll keep looking, but for now it's good to have shared it.

Allow it to run in a desktop environment on wayland.

I could not get font-mixing and canvas examples to work in gnome on Ubuntu 23.04 wayland.
I don't know the specific cause yet, but I couldn't find the issue, so I made one.
As a workaround, if I use Ubuntu on xorg in gdm, it works fine.

version

CL-USER> (ql:update-all-dists)
2 dists to check.
You already have the latest version of "quicklisp": 2023-06-18.
You already have the latest version of "shirakumo": 2023.09.21-11.49.34.
NIL
CL-USER> (lisp-implementation-version)
"2.3.8"

Rewrite Coordinate System

The current coordinate system as employed in Alloy uses absolute positioning for everything. This has the immediate advantage that comparisons and resolution are free. Determining whether one geometry is within another requires no context query.

However, this brings with it some serious costs that I think are too big a burden to justify. Most notably, when a layout is moved, not only do its coordinates need to be updated, but also all of its children. This can incur significant cost, for something that could be almost free. This is especially damning in relatively common cases like scrollable lists.

In order to remedy this, a new protocol needs to be introduced that can be used to resolve geometries to absolute variants. We already need a system like this in order to resolve relative units to absolute ones, in particular ph/pw unit types, so an extension of that to allow transforming entire geometries would be good.

Things to consider here are:

  • Should we only allow translation, or should rotations, skews, etc. also be allowed?
  • We should probably cache the transform at each layout and update it whenever the layout is moved. That way resolving a child geometry only ever needs to consider the immediate parent rather than all ancestors.
  • How do we perform geometry tests, most notably intersections?
  • Currently the protocol that updates the bounds of an element will cause a relayout to happen. We need to prevent this unless it is absolutely necessary due to resizes... and possibly other actions?
  • The renderers need to be updated to take the context into account.
  • Switching the system to be 0,0 in topleft corner with y growing down, rather than the current bottomleft, y frowing up.

Combo rendering not working well

All of the issues below have been found by testing the combo function in the alloy-examples package.

I've been testing out the software for the last few days and noticed the following two things. The combo doesn't correctly overlay the rest of the UI: example

It's also possible to select the value NIL even thought that's not in the options list: example-2-electric-boogalo
This can be reproduced by double clicking the box that opens the drop-down.

Also another minor nit-pick, what is currently called a combo-box in the code is actually a drop-down. A combo-box usually has a search function: Wikipedia

sliders loses focus while adjusting if mouse move out of the slider

While unfocused the components gain focus correctly corresponding to the mouse movements.

However, the components focused, slider in this case, will loses focus if mouse moves out of the component region.

The current behaviour can be reproduced with the example code you given me in this issue.
#1 (comment)

It will be better if the currently interacted components will not lose focus when mouse move out of it.

System "colored" not found

I'm looking to help with the development of Alloy in the summer and I'm trying to get my barrings in this codebase. When trying to set up Alloy, I wanted to take a look in the example directory. But when trying to CL-USER> (ql:quickload :alloy-examples) the system I got the following error:

System "colored" not found
   [Condition of type QUICKLISP-CLIENT:SYSTEM-NOT-FOUND]

What do I do about it and do you have any advice for prodding around in the project?

[Discussion] ideas for improving REPRESENT macro

I think the REPRESENT macro currently serves as the only and unified component initialization method, could use some work:

1. isolate data creation, perhaps move that to the user's side

introduce new functions: #'alloy:add-observable-callback for adding observable callbacks, #'alloy:set-data' for data setting, and corresponding new functions for each of type of data.

In each of the function we can reinforce validation accordingly, because #'expand-place-data and #'expand-compound-place-data already serve this purpose and exposed to the user, this would be just renaming some of the methods.

2. Considering remove the T case in 'represent-with'.

So that (alloy:represent "Hey!" T) becomes (alloy:represent "Hey!" 'alloy:label), this is would be much more consistent with the rest of the components.
Doing this for symbol, nil & T, and maybe #'component-class-for-object can be removed?

Autorepeat

I didn't put this in the pullrequest yesterday, because it's more opinionated, so I would like to hear your take on it.

In my opinion the UI we create should behave similair to the UI we daily interact with, unless there's a really good reason not to. I think this is helpfull because you can make use of pre-existing mental models of the user. So I've taken a look at some UI frameworks and looked at how the sliders behaved.

When looking at this and that, I found out a couple of things:

  • All sliders are gridded sliders, although some just have very small intervals between marks.
  • A lot of sliders implement autorepeat (or DAS) with the left/right keys (although it should probably be a flag).
  • The :step of most sliders is just the interval defined by :grid.

I personally find the :step slot to be a bit annoying, because in my opinion there's only one good value for it: the value you have for :grid. If it's smaller it can't bridge the gaps and if it's bigger you don't have the same amount of precise control that mouse users get. This doesn't mean that this design doesn't come up sometimes. The volumeslider of Linux Mint has 100 different values, but using the arrow keys you can only move in 5% steps. Something very similair is true for the volumeslider Youtube uses.

Of course the reason for this feature is to make sure that keyboard users don't have to wait forever to change the volume, but I'd argue that you can achieve the same speed using autorepeat and that it's not worth giving up the finer control.

TLDR: Implement autorepeat for sliders, maybe remove the :step slot.

SVG renderer fails to build

Log:

; compiling file "/gnu/store/747m7rqk4nj0j0n14kzj3465ccd1gkka-sbcl-alloy-0.0.0-2.ea02e45/share/common-lisp/sbcl/alloy/renderers/svg/renderer.lisp" (written 01 JAN 1970 12:00:00 AM):
; 
; caught ERROR:
;   READ error during COMPILE-FILE:
;   
;     The symbol "STYLE" is not external in the ORG.SHIRAKUMO.ALLOY.RENDERERS.SIMPLE package.
;   
;       Line: 32, Column: 53, File-Position: 845
;   
;       Stream: #<SB-INT:FORM-TRACKING-STREAM for "file /gnu/store/747m7rqk4nj0j0n14kzj3465ccd1gkka-sbcl-alloy-0.0.0-2.ea02e45/share/common-lisp/sbcl/alloy/renderers/svg/renderer.lisp" {1003C5FD53}>

[Discussion] Observing leave/parent leave events.

Want to bounce an idea at you.

I want to associate buttons/clickable elements with dedicated keyboard keys for them.
The first thought i had when i started going into that direction was - i'm going to initialize a component that will subscribe to a leave/enter event (of the component itself and its parents).

Would you imagine any immediate problems with turning all container/element classes observable?

Was thinking about how component/layout parents could notify their leave/enter events, and thought that the least performance impact could possibly be - setting up an observation on the leave event on a component of interest could iterate upwards creating an observation in all parents that would notify the initial child of interest when they've left. Possibly via specialized event rather than leave? Since it might then be of interest to have the event signature more along the lines of:

(alloy:on alloy:something-in-tree-left (observable-of-interest observable-that-left-their-parent parent-that-was-left)
  (handle))

As is currently - i could probably handle these things on a different level, but somehow am stuck on the idea, and wanted to test the waters.

GLFW window throws error when attempting to maximize or iconify on Windows

Here's the code that I'm working with so far (mainly just ripped from #1)

;;;; src/main.lisp

(in-package :sbla)

(defun main ()
  "Entrypoint of steel-bank-local-archive."
  (glfw:with-screen (screen)
    (let* ((window (windowing:make-window screen :bounds (alloy:px-size 400 400)))
           (focus (make-instance 'alloy:focus-list :focus-parent window))
           (layout (make-instance 'alloy:vertical-linear-layout :layout-parent window))
           (button (alloy:represent "Greet" 'alloy:button)))
      (alloy:enter button layout)
      (alloy:enter button focus)
      (alloy:on alloy:activate (button)
        (let ((window (windowing:make-window screen :background-color colors:white)))
          (alloy:enter (alloy:represent "Hey!" T) window)))))
  (uiop:quit))

The window launches without any significant issues, however when I try to either maximize or minimize the window, it crashes, and the following error gets spat out:

An error occured: There is no primary method for the generic function
                    #<STANDARD-GENERIC-FUNCTION ORG.SHIRAKUMO.ALLOY:HANDLE (86)>
                  when called with arguments
                    (#<WINDOWING:STATE {1006443653}> #<GLFW:SCREEN DEAD>).

Specs & other useful notes:

  • Ran with SBCL 2.2.10
  • Windows 10 (64-bit)
  • All dependencies are installed (from the shirakumo dist)

Inserting more than one layout into a borderlayout (possible bug)

The problem occurs with the following code:

(defun fig-one ()
  (glfw:with-screen (screen)
    (let* ((window (windowing:make-window screen :min-size (alloy:px-size 600 500)))
           (layout (make-instance 'alloy:border-layout :layout-parent window))
           (top-bar (make-instance 'alloy:horizontal-linear-layout
                                   :layout-parent layout
                                   :place :north))
           (side-bar (make-instance 'alloy:vertical-linear-layout
                                    :layout-parent layout
                                    :place :west))))))

(defun fig-two ()
  (glfw:with-screen (screen)
    (let* ((window (windowing:make-window screen :min-size (alloy:px-size 600 500)))
           (layout (make-instance 'alloy:border-layout :layout-parent window))
           (top-bar (make-instance 'alloy:horizontal-linear-layout
                                   :layout-parent layout))
           (side-bar (make-instance 'alloy:vertical-linear-layout
                                    :layout-parent layout))))))

I'm trying to insert two layouts into the borderlayout to make a sidebar and a topbar. In figure one, the problem is that :place isn't a valid argument for 'alloy:horizontal-linear layout so it's rejected. In figure two there's still a problem. When the layouts enter the borderlayout they do that with the default argument :center:

(defmethod enter ((element layout-element) (layout border-layout) &key (place :center) size)
  (let ((slot (border-place-slot place)))
    (when (slot-value layout slot)
      (cerror "Replace the element" 'place-already-occupied
              :element element :place place :layout layout :existing (slot-value layout slot)))
    (setf (slot-value layout slot) (list element size))))
(defmethod initialize-instance :after ((element layout-element) &key layout-parent)
  (when layout-parent
    (enter element layout-parent)))

And there can only be one layout-element in a borderlayout section so it produces an error. How could this be fixed? Should the layout-parent be left empty and you could enter the layout manually later? I've tried the following and it seems to work:

(defun fig-three ()
  (glfw:with-screen (screen)
    (let* ((window (windowing:make-window screen :min-size (alloy:px-size 600 500)))
           (layout (make-instance 'alloy:border-layout :layout-parent window))
           (top-bar (make-instance 'alloy:horizontal-linear-layout))
           (side-bar (make-instance 'alloy:vertical-linear-layout)))
      (alloy:enter top-bar layout :place :north)
      (alloy:enter side-bar layout :place :west))))

Is this the intentional solution to this problem?

[Help] Using alloy with other backends

I am aware this project is:

"currently still in its design phase"

I have seen some example code on some of the alloy demo videos, however, it still remain unfamiliar to me as to how to use alloy, such as using a different back-end, OpenGL, to avoid install trial, the game engine package.

Is there any example codes laying around somewhere in the project?
Or where can we find some basic introductory document explaining how alloy can be used?

I can't start the examples.

Hello!
I tried to start an examples, but they crushed with error:
:RGBA fell through ECASE expression. Wanted one of (1 2 3 4).
изображение
How can I fix this problem?
And why are there so few examples in package? Only two.
Thanks!

Redundancy in initarg names

I saw this, and it left me somewhat disappointed:

(define-example drop-files (screen)
  (let* ((window (windowing:make-window screen :class 'custom-window))
         (focus (make-instance 'alloy:focus-list :focus-parent window))
         (layout (make-instance 'alloy:border-layout :layout-parent window))
         (label (alloy:represent "Drop some files here!" 'alloy:button :focus-parent focus :layout-parent layout)))
    (setf (slot-value window 'label) label)))

It would be convenient to have a macro that allows one to define the parent/child relationships between GUI elements declarative, HTML-like manner. There's an example of such a thing for Racket's GUI library.

The Racket library relies on the fact that every GUI element has a parent, so it can just derive the parent from the element's place in the macro body.

But you couldn't write something like this for Alloy because there'd be no way to programmatically determine that the parent of one type of object is the :focus-parent, and the parent of another type is the :layout-parent, and so on. You can't even derive the prefix to parent from the name of the class.

This is probably being done to avoid name conflicts in the case of multiple inheritance. Perhaps instead of each class having its own parent field, there could be a child mixin class that provides the parent field.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.