notjack
2020-5-18 07:09:37

So picts can display inline in the REPL. How do I make an animation that displays inline in the REPL?


notjack
2020-5-18 07:09:51

(or at least, in drracket’s REPL)


spdegabrielle
2020-5-18 07:10:57

Plot does it.


notjack
2020-5-18 07:11:15

oh right!


notjack
2020-5-18 07:11:20

got any examples handy?


spdegabrielle
2020-5-18 07:12:33

Not to hand sorry. I’m assuming a timer.


laurent.orseau
2020-5-18 07:13:18

A snip% can be a canvas% I think, so using a thread an a timer you should be able to animate it


notjack
2020-5-18 07:14:13

why does it being a canvas% matter? (I have very little experience with racket’s GUI framework)


spdegabrielle
2020-5-18 07:14:45

Check out the animated canvas package on PLaneT


spdegabrielle
2020-5-18 07:15:10

a canvas holds the dc


spdegabrielle
2020-5-18 07:26:08

I just remembered the animated map snip made by @alexharsanyi I’ll see if I can find the link to his blog


laurent.orseau
2020-5-18 07:27:52

As @spdegabrielle says, the canvas holds a dc%, which is what you need to draw, and you can also ask the canvas to refresh, which is what you need to animate.



notjack
2020-5-18 07:37:29

@laurent.orseau so this is as far as I’ve gotten: (define animation-snip% (class how do I make it both a snip% and a canvas% ?


laurent.orseau
2020-5-18 07:50:15

Hmm, I think you need to implement a new snip% instead, not a canvas% directly. I see Alex is typing, so he’ll be able to help more :slightly_smiling_face:


alexharsanyi
2020-5-18 07:50:25

@notjack you only need to make it a snip%, but than you’ll need to define a snip-class% as well and there are a few more steps required: the snip will need to have a get-extent and a draw method defined, as well a copy method if it needs to be displayed in the DrRacket REPL (because the REPL creates copies of all snips).



notjack
2020-5-18 07:51:09

currently I’m starting from the pict-snip code: https://github.com/racket/pict-snip/


laurent.orseau
2020-5-18 07:51:11

laurent.orseau
2020-5-18 07:51:21

that’s a canvas-snip%


alexharsanyi
2020-5-18 07:51:39

the beginning of the blog post shows how to create a snip%, for DrRacket REPL use, you’ll need to add a copy method to it.


alexharsanyi
2020-5-18 07:52:24

and also note that DrRacket REPL will display a copy of the snip (good to know if you plan to interact with it from the GUI)


notjack
2020-5-18 07:53:12

I don’t plan to interact with it from the GUI, but I do want it to automatically play the animation


notjack
2020-5-18 07:54:35

more specifically: I have a list of picts, and I want to have them play one after the other with a second or so delay between picts. I’m currently using slideshow/play to get it to play in a slideshow, but I’m only using that because it was easy. I’d really like something in the REPL.


laurent.orseau
2020-5-18 07:56:11

ah, but you want a snip-canvas% instead, because the canvas-snip is a canvas with a single snip, so you still need a frame%


notjack
2020-5-18 07:56:39

so just something like (animate-these-picts-please frame-picts #:framerate 2) that turned into a movie playing in the repl at a rate of 2 FPS would be perfect


notjack
2020-5-18 07:57:43

@alexharsanyi going through your chess snips post now, thank you so much for writing that


notjack
2020-5-18 07:57:54

yup


alexharsanyi
2020-5-18 07:58:38

I am not aware of any libraries which let you do this in the REPL, but it should not be too complex to write such a function by creating an animation-pict% object with a list of picts


notjack
2020-5-18 07:59:11

I’ve tried this before and the wall I hit was the animation part


laurent.orseau
2020-5-18 08:06:46

laurent.orseau
2020-5-18 08:07:05

but it’s not straightforward though


soegaard2
2020-5-18 08:08:11

@alexharsanyi Your whole series of blog posts on the GUI has been excellent.


laurent.orseau
2020-5-18 08:14:09

Adapted from the docs.


laurent.orseau
2020-5-18 08:15:14

in the interactions: (define sn (new circle-snip%)) sn Then move the mouse over the snip, and draw is apparently called repeatedly. Looks slow but it’s a start


alexharsanyi
2020-5-18 08:17:59

@notjack, here is a sample animation-snip% which cycles a list of picts: https://gist.github.com/alex-hhh/d6bdc9f9b671876d6726396e3c7b05c9


alexharsanyi
2020-5-18 08:18:50

thanks


spdegabrielle
2020-5-18 08:20:04

it occurs to me that is it is 1:20 am for @notjack


notjack
2020-5-18 08:21:28

yes, I made poor choices tonight


soegaard2
2020-5-18 08:28:20

Why is there an (make-object ...) around the class form? (define animation-snip-class (make-object (class snip-class% (super-new) (send this set-classname "animation-snip-class"))))


alexharsanyi
2020-5-18 08:30:51

you only need a single instance of the snip class. So I create an anonymous class derived from snip-class% than create an object from that class and assign it to animation-snip-class.


notjack
2020-5-18 08:30:52

it’s a singleton object


notjack
2020-5-18 08:31:27

I think there’s a util package somewhere that adds an object form so you can do (object snip-class% (super-new) …)


notjack
2020-5-18 08:31:44

that ought to be in the racket/class library IMO


soegaard2
2020-5-18 08:38:37

Well, I see that removing it leads to an error. But … The documentation says: > (send a-snip set-snipclass class) → void? > class : (is-a?/c snip-class%) And is-a?/c can handle a class. > (is-a?/c type) → flat-contract? > type : (or/c class? interface?)


notjack
2020-5-18 08:39:53

I think is-a/c? takes a class and produces a contract that accepts an object of that class


notjack
2020-5-18 08:40:27

so (is-a?/c snip-class%) means “any snip-class% object”


soegaard2
2020-5-18 08:41:49

You are right: > Accepts a class or interface and returns a flat contract that recognizes objects that instantiate the class/interface.


soegaard2
2020-5-18 08:42:22

so the shorthand class ought to be class-object ?


notjack
2020-5-18 08:43:43

maybe? not sure


notjack
2020-5-18 08:43:56

it gets all confusing because classes are first class values, but also not all values are objects


alexharsanyi
2020-5-18 08:44:54

I am just speculating, but I think the snip hierarchy reuses the term “class” for something different than racket/class


alexharsanyi
2020-5-18 08:45:21

so set-snip-class assigns a “snip class” to a snip


notjack
2020-5-18 08:45:25

that too


soegaard2
2020-5-18 08:45:52

Maybe it accepted both before contracts were introduced?


alexharsanyi
2020-5-18 08:47:56

The purpose of the snip class is to hold the “read” method for deserializing snips — it has no purpose in the example I shown, but snips without a snip class cannot be added to an editor, so it is required.


notjack
2020-5-18 08:53:37

@alexharsanyi May I use that animation code you wrote in a library I’m writing under the apache 2 license? Will include a link to the gist in the source.


alexharsanyi
2020-5-18 08:54:34

Yes, no problem


notjack
2020-5-18 08:59:21

notjack
2020-5-18 09:00:23

now, challenge mode: can I turn it into a gif or some other file I can copy-paste into a slack channel…


soegaard2
2020-5-18 09:03:56

notjack
2020-5-18 09:04:16

closest I can get so far is a few pictures of my planner solving a block-pushing puzzle:


notjack
2020-5-18 09:04:34

notjack
2020-5-18 09:04:46

notjack
2020-5-18 09:04:57

notjack
2020-5-18 09:05:57

@soegaard2 any ideas on how to get that to happen automatically when I select the animation snip and ctrl-C it?


soegaard2
2020-5-18 09:07:06

The animation-snip needs to generate the gif and then put it on the paste board.


soegaard2
2020-5-18 09:07:37

There must be a method that can be overriden to change the behaviour of “copy”.


notjack
2020-5-18 09:07:56

ah well, future work


spdegabrielle
2020-5-18 09:48:50

Giving my laptop fan a good run though


spdegabrielle
2020-5-18 11:13:04

the gui doesn’t support gif, or at least on MacOs, copying gifs to the pasteboard, though images on the pasteboard can go into gui.

To add gifs to the macos pasteboard to require sending multiple representations so receiving applications can find an interpretation they can use. I presume it is much the same on linux and windows. I think the code is mostly in pasteboard, though I’ve not worked out how the snipclass copy method calls it.

https://github.com/racket/gui/blob/master/gui-lib/mred/private/wx/cocoa/clipboard.rkt

https://github.com/racket/gui/blob/master/gui-lib/mred/private/wx/cocoa/image.rkt



sorawee
2020-5-18 23:48:48

Is there a way to detect if a file path is a part of Racket or a package?


sorawee
2020-5-18 23:49:26

E.g., given #<path:/Applications/Racket v7.7/collects/racket/require.rkt> or #<path:/Applications/Racket v7.7/share/pkgs/r5rs-lib/r5rs/private/r5rs-trans.rkt>, return #t because it belongs to Racket/its standard distribution.


sorawee
2020-5-18 23:50:50

Given #<path:/Users/sorawee/git/rosette/rosette/base/struct/struct.rkt> and a package name rosette, return #t too


sorawee
2020-5-18 23:53:12

OK, I think whereis/find-system-path is the answer. Let’s see…


mflatt
2020-5-18 23:53:40

There’s also path->pkg.


sorawee
2020-5-19 00:00:13

Thanks!


sorawee
2020-5-19 00:10:49

Is my assumption correct that (build-path (find-system-path 'collects-dir) 'up "share" "pkgs") will always link to the default pkgs?


sorawee
2020-5-19 00:11:25

Alternatively, given a package name (output of path->pkg), how do I check if it’s a part of the standard distribution?


mflatt
2020-5-19 00:18:47

No, it depends on the configuration. I think you’re looking for find-pkgs-dir.


mflatt
2020-5-19 00:19:51

Do you mean whether it’s implied by dependencies from main-distribution? I think you’d have to explore the dependency tree.


sorawee
2020-5-19 00:34:59

Thanks. This is exactly what I need