Discussion:
Scrolling an image in a Player
Sachin Desai
2005-12-18 22:48:31 UTC
Permalink
I need help in understanding how to scroll an image once it's
displayed as a graphic for a player. Basically what I'm trying to
accomplish is to scroll an image in a small window. I have the
player's form set to the image and the following code accomplishes
what I want but the rendering is not smooth, i.e. when I drag, I'm
not able to see any movement until the drag stops whereupon the image
renders.

If I replace "self graphicForm: f" with "f displayAt: self origin"
then I get the desired result which is having the image rendered
pretty much immediately as I drag. The one problem is the image is
not rendered in the player, instead it's rendered at some offset from
the player. Any ideas?

In general, if someone wants to display a changing image or graphics
in a window, what's the mechanism for doing this. I've tried to do
this with a player that load the image and a costume that listens on
the events and does the rendering. I'm not sure if this is the right
approach but any help would be gladly welcome.


onRedButtonDown
| nextPoint lastPoint f |
<on: redButtonDown>
lastPoint _ nil.
self closedHandCursor show.
[Sensor redButtonPressed] whileTrue: [
nextPoint _ Sensor cursorPoint.
lastPoint ifNil: [lastPoint _ nextPoint].
self delta: (nextPoint - lastPoint).
self imageOffset: (self imageOffset + self delta).
self drawingCanvas
translateBy: self delta
during: [:canvas |
canvas fillColor: Color white.
canvas paintImage: self form at: (self imageOffset).
f _ canvas contentsOfArea: (***@0 extent: ***@200).
self graphicForm: f].
lastPoint _ nextPoint.
].
self openHandCursor show.


-- Sachin
Bert Freudenberg
2005-12-19 00:43:39 UTC
Permalink
Uh oh, you're heavily mixing concepts here ... "Sensor" is from MVC,
it should not be accessed from Tweak code (or Morphic for that
matter). Also, that while-loop will block all of the UI.

Instead, use this:

self forEach: #mouseMove do: [:evt | ...] until: #mouseUp.

This will execute the block once for each mouse move event without
blocking.

Inside the block, you can either access the event (which is an
optional parameter to the block), or the "hand" (basically Tweak's
replacement of Sensor). "hand position" will answer the global mouse
coordinates. Use #globalToLocal: to convert this into local
coordinates, or simply use "self cursorPoint" which does that for you.

Drawing yourself should not be necessary. The player's graphic aspect
has an offset, a Point which will define a relative shift of the
graphic's form.

Directly drawing to the Display (using displayAt:) will not work, as
you discovered, since you cannot easily determine the global offset
of your player. If the security framework was already in place, it
would be all but impossible (unless you're given a "direct-display-
access" capability, etc. pp).

Also, for most simple stuff you do not need to have a separate
costume class. Just having a player will do fine. Only if you want to
have an MVC-like distinction between presentation and representation,
a separate costume is needed.

You might want to start with the tutorials on the Tweak website, they
do cover at least some of those basics.

- Bert -
Post by Sachin Desai
I need help in understanding how to scroll an image once it's
displayed as a graphic for a player. Basically what I'm trying to
accomplish is to scroll an image in a small window. I have the
player's form set to the image and the following code accomplishes
what I want but the rendering is not smooth, i.e. when I drag, I'm
not able to see any movement until the drag stops whereupon the
image renders.
If I replace "self graphicForm: f" with "f displayAt: self origin"
then I get the desired result which is having the image rendered
pretty much immediately as I drag. The one problem is the image is
not rendered in the player, instead it's rendered at some offset
from the player. Any ideas?
In general, if someone wants to display a changing image or
graphics in a window, what's the mechanism for doing this. I've
tried to do this with a player that load the image and a costume
that listens on the events and does the rendering. I'm not sure if
this is the right approach but any help would be gladly welcome.
onRedButtonDown
| nextPoint lastPoint f |
<on: redButtonDown>
lastPoint _ nil.
self closedHandCursor show.
[Sensor redButtonPressed] whileTrue: [
nextPoint _ Sensor cursorPoint.
lastPoint ifNil: [lastPoint _ nextPoint].
self delta: (nextPoint - lastPoint).
self imageOffset: (self imageOffset + self delta).
self drawingCanvas
translateBy: self delta
during: [:canvas |
canvas fillColor: Color white.
canvas paintImage: self form at: (self imageOffset).
self graphicForm: f].
lastPoint _ nextPoint.
].
self openHandCursor show.
-- Sachin
Sachin Desai
2005-12-19 01:15:31 UTC
Permalink
Post by Bert Freudenberg
Uh oh, you're heavily mixing concepts here ... "Sensor" is from
MVC, it should not be accessed from Tweak code (or Morphic for that
matter). Also, that while-loop will block all of the UI.
I thought that was the case. I tried looking for examples and I found
an old MVC one which is where the loop came from. I wasn't sure what
the Tweak equivalent would be. I also tried going through the code
but obviously didn't look hard enough.
Post by Bert Freudenberg
self forEach: #mouseMove do: [:evt | ...] until: #mouseUp.
This will execute the block once for each mouse move event without
blocking.
Inside the block, you can either access the event (which is an
optional parameter to the block), or the "hand" (basically Tweak's
replacement of Sensor). "hand position" will answer the global
mouse coordinates. Use #globalToLocal: to convert this into local
coordinates, or simply use "self cursorPoint" which does that for you.
Drawing yourself should not be necessary. The player's graphic
aspect has an offset, a Point which will define a relative shift of
the graphic's form.
I've made the necessary changes it works beautifully. Thanks very
much for the information, it's very informative.


-- Sachin.
Post by Bert Freudenberg
Post by Sachin Desai
I need help in understanding how to scroll an image once it's
displayed as a graphic for a player. Basically what I'm trying to
accomplish is to scroll an image in a small window. I have the
player's form set to the image and the following code accomplishes
what I want but the rendering is not smooth, i.e. when I drag, I'm
not able to see any movement until the drag stops whereupon the
image renders.
If I replace "self graphicForm: f" with "f displayAt: self origin"
then I get the desired result which is having the image rendered
pretty much immediately as I drag. The one problem is the image is
not rendered in the player, instead it's rendered at some offset
from the player. Any ideas?
In general, if someone wants to display a changing image or
graphics in a window, what's the mechanism for doing this. I've
tried to do this with a player that load the image and a costume
that listens on the events and does the rendering. I'm not sure if
this is the right approach but any help would be gladly welcome.
onRedButtonDown
| nextPoint lastPoint f |
<on: redButtonDown>
lastPoint _ nil.
self closedHandCursor show.
[Sensor redButtonPressed] whileTrue: [
nextPoint _ Sensor cursorPoint.
lastPoint ifNil: [lastPoint _ nextPoint].
self delta: (nextPoint - lastPoint).
self imageOffset: (self imageOffset + self delta).
self drawingCanvas
translateBy: self delta
during: [:canvas |
canvas fillColor: Color white.
canvas paintImage: self form at: (self imageOffset).
self graphicForm: f].
lastPoint _ nextPoint.
].
self openHandCursor show.
-- Sachin
_______________________________________________
Tweak mailing list
http://impara.de/mailman/listinfo/tweak
Continue reading on narkive:
Loading...