win-offset? screen-offset? bug
[1/12] from: rotenca:telvia:it at: 22-Mar-2002 14:00
I find these standard functions wrong (beyond they have the same comment):
win-offset?: func [
{Given any face, returns its screen absolute offset.}
face [object!]
/local xy
][
xy: 0x0
while [face] [if face/parent-face [xy: xy + face/offset] face:
face/parent-face]
xy
]
screen-offset?: func [
{Given any face, returns its screen absolute offset.}
face [object!]
/local xy
][
xy: face/offset
while [face/parent-face] [face: face/parent-face xy: xy + face/offset]
xy
]
The problem is that they do not add the edge size of panels.
Are I right?
The first is an important function because it is used at every event by
system/view/screen-face/feel/event-funcs/1
and by
system/view/wake-event
The second is used only by system/words/choose.
---
Ciao
Romano
[2/12] from: brett:codeconscious at: 23-Mar-2002 15:05
Hi Romano,
> I find these standard functions wrong (beyond they have the same comment):
>
> win-offset?: func [
> screen-offset?: func [
> The problem is that they do not add the edge size of panels.
>
> Are I right?
Yes and no. The functions are correct in my opinion as they should not be
dependent on VID styles. I believe the problem is with panels/layout.
Look at this example code, the panel-face variable is pointing
to something that does not exist in the face object model.
view lyo: layout [
style button button 200x20
across
panel-face: panel 300x300 [
blue-box: box blue
red-box: box red
] edge [size: 5x5 color: orange]
green-face: box green
return
button "Move to phantom face" [
green-face/offset: win-offset? panel-face
show green-face
]
button "Move to actual panel face" [
green-face/offset: win-offset? lyo/pane/1
show green-face
]
]
Now have a look at these results:
>> panel-face/style
== panel
>> lyo/pane/1/style
== panel
>> lyo/pane/1/var
== panel-face
>> panel-face/var
== panel-face
>> equal? lyo/pane/1 panel-face
== false
>> panel-face/pane
== none
>> type? lyo/pane/1/pane
== block!
The panel-face variable appears to get set to some intermediate face made
during
the construction of the panel but which is not actually part of the final
face object
model.
I haven't worked out how to fix it but you can see a work around in the code
anyway.
Regards,
Brett
[3/12] from: brett:codeconscious at: 23-Mar-2002 17:09
Hi again,
> dependent on VID styles. I believe the problem is with panels/layout.
I think I've found why the win-offset? and screen-offset? functions
have problems with PANEL now. It was the interaction between the INIT
of PANEL and the processing of the LAYOUT function.
The problem I think is that within LAYOUT the variable is set before
the INIT of the face is processed. It should be after. This is because
during the processing of INIT the face is swapped when the
PARENT-FACE field is not none - this the case with the PANEL
style. Therefore the variable is invalidated.
I've included a patch below that modifies the LAYOUT function.
It would be better if LAYOUT was amended so I'll let feedback
back know too.
Watch line wrap...
; PATCH LAYOUT FUNCTION TO HANDLE PANELS
if 1202930 = checksum mold :layout [
use [
layout-function code-to-move block-to-change
removal-point
insertion-point
] [
; Code to search for
code-to-move: [
if :var [set :var new new/var: to-word :var var: none]
]
; The actual function definition (in context)
layout-function: second :layout
; Find the block to change and the the point of change
block-to-change: second third find layout-function 'while
removal-point: find block-to-change code-to-move
insertion-point: find block-to-change 'break
; Copy the code to just before the BREAK - ie after INIT has been
processed.
insert insertion-point copy/part removal-point length? code-to-move
; Remove the code from it's original position
remove/part removal-point length? code-to-move
]
Print "Layout patch for PANEL applied."
]
Regards,
Brett
[4/12] from: rotenca:telvia:it at: 23-Mar-2002 14:32
----- Original Message -----
From: "Brett Handley" <[brett--codeconscious--com]>
To: <[rebol-list--rebol--com]>
Sent: Saturday, March 23, 2002 5:05 AM
Subject: [REBOL] Re: win-offset? screen-offset? bug
> Hi Romano,
>
> > I find these standard functions wrong (beyond they have the same comment):
> >
> > win-offset?: func [
> > screen-offset?: func [
> Yes and no.
After the post i have made some check and now i 'm retty sure they are wrong,
at the end i post my patches.
> The functions are correct in my opinion as they should not be
> dependent on VID styles. I believe the problem is with panels/layout.
> Look at this example code, the panel-face variable is pointing
> to something that does not exist in the face object model.
I know that problem, but it is another problem. It can be solved in this way:
l: layout [p: panel [button]]
p: p/parent-face
The only "error" of layout is the variable assignement, not the cascade of
face/pane (else it does not works) which, btw, is fully set for a window only
by the display code activated by View, not by the layout function (this means
that immediately after a layout the parent-face field is not correctely set in
ALL the faces, but this is another problem :-).
The win-offset? give a wrong result also if you do not use the panel style:
l: layout [p: box 200x200 edge [size: 50x50]]
f: make-face/spec 'button [action: func [face value][print win-offset? f]]
p/pane: reduce [f]
view l
which gives 20x20 when the true offset of the button f in the window is 70x70.
> The panel-face variable appears to get set to some intermediate face made
> during
<<quoted lines omitted: 3>>
> I haven't worked out how to fix it but you can see a work around in the code
> anyway.
Yes, to reach the right face you must get the parent-face of the face pointed
by the var, in your example:
panel-face: panel-face/parent-face
Here are my patched win-offset? screen-offset?:
win-offset?: func [
{Given any face, returns its window offset. Patched by Ana}
face [object!]
/local xy
][
xy: 0x0
if face/parent-face [
xy: face/offset
while [face: face/parent-face] [
if face/parent-face [
xy: xy + face/offset + either face/edge [face/edge/size][0x0]
]
]
]
xy
]
screen-offset?: func [
{Given any face, returns its screen absolute offset. Patched by Ana}
face [object!]
/local xy
][
xy: face/offset
while [face: face/parent-face][
xy: xy + face/offset + either face/edge [face/edge/size][0x0]
]
xy
]
---
Ciao
Romano
[5/12] from: brett:codeconscious at: 24-Mar-2002 12:17
Hi Romano,
> The only "error" of layout is the variable assignement, not the cascade of
> face/pane (else it does not works) which, btw, is fully set for a window
only
> by the display code activated by View, not by the layout function (this
means
> that immediately after a layout the parent-face field is not correctely
set in
> ALL the faces, but this is another problem :-).
Well variables returned from layout *are* pretty important :^)
As for parent-face I don't know if that is really a problem, just a matter
of usage, we know it it gets calculated after View been activated.
> The win-offset? give a wrong result also if you do not use the panel
style:
> l: layout [p: box 200x200 edge [size: 50x50]]
> f: make-face/spec 'button [action: func [face value][print win-offset?
f]]
> p/pane: reduce [f]
> view l
Ah that example helps considerably :^)
Yes it does look like a problem.
> > I haven't worked out how to fix it but you can see a work around in the
code
> > anyway.
>
> Yes, to reach the right face you must get the parent-face of the face
pointed
> by the var, in your example:
>
> panel-face: panel-face/parent-face
Now doubt you'll see my later message - which I think fixes this problem.
> Here are my patched win-offset? screen-offset?:
Thanks for your patches, I'm going to add them to my patches.r script along
with my change to layout.
Regards,
Brett.
[6/12] from: rotenca:telvia:it at: 24-Mar-2002 13:09
Hi, Brett
> Well variables returned from layout *are* pretty important :^)
I agree. But see below...
> > > I haven't worked out how to fix it but you can see a work around in the
> code
<<quoted lines omitted: 6>>
> > panel-face: panel-face/parent-face
> Now doubt you'll see my later message - which I think fixes this problem.
I've seen. But I am not sure it is a good idea, because the panel style is
used internally by RT styles and custom styles and i do not know if your
change can mess something. To be sure, we should check all the styles and all
request-file/date/... the choice and so on, to be sure that that fix does not
mess something. And we should change many scripts. In my programs i make a new
assignement to the parent-face after every use of a panel style and I think
that many other people has made something like this. So the fix create to me
more problems than it fix. The direct solution is very simple (get the parent
of the face) and i already use it in many scripts.
> Regards,
> Brett.
---
Ciao
Romano
[7/12] from: brett:codeconscious at: 25-Mar-2002 1:10
> I've seen. But I am not sure it is a good idea, because the panel style is
> used internally by RT styles and custom styles and i do not know if your
> change can mess something. To be sure, we should check all the styles and
all
> request-file/date/... the choice and so on, to be sure that that fix does
not
> mess something. And we should change many scripts. In my programs i make a
new
> assignement to the parent-face after every use of a panel style and I
think
> that many other people has made something like this. So the fix create to
me
> more problems than it fix. The direct solution is very simple (get the
parent
> of the face) and i already use it in many scripts.
I see your point but I disagree. Nothing demands all scripts to change.
People can choose to use the patch or not - even on a script by script
basis if necessary. They can test and if they don't like it they don't
need to use it. Also while the direct solution is simple it is, in my
opinion, likely to fail in future. So I think you should change the
script if you want it to work on later versions of View - whether you
use my patch or not (see below).
Your logic would imply that you will not use your modified win-offset?
and screen-offset? functions. I most likely will - they will save me
time in future.
As for checking all the styles, etc, that is RT's job - I've notified
them of the bug through feedback. They'll decide whether it should be
changed or not. Though I believe it is only variables set to PANEL that
are affected at this time (Rebol/View).
BTW, I did a quick search but could not find PANEL being used by RT
styles internally could you give an example please?
>From my point of view I prefer not to make my scripts dependent on
bugs. I'd rather patch a bug so that my script will not break when the
bug is eventually fixed or make it tolerant to change. And I do expect
a change. The core language is changing so I assume the graphical
mezzanine functions are open to change too.
As I mentioned above I believe the direct solution is likely to fail in
futur and even if you don't agree with the patch, I think you should
use a different workaround. It should not be too hard to make these
changes - they are simple.
If the code is:
lyo: layout [p: panel [b: box]]
Then instead of:
p: p/parent-face
This is better:
p: b/parent-face
or perhaps not as nice:
p: lyo/pane/1
These workarounds are dependent on good behaviour not bad.
Anyways this discussion illustrates a fundamental issue with
distributed systems. I was once told by a project leader of Java
projects that Java meant "Write once, test everywhere". Rebol is not at
that stage (yet?). Maybe though some conventions or language support
are required to ensure my changes and yours will work on all systems.
Regards,
Brett.
[8/12] from: rotenca:telvia:it at: 24-Mar-2002 15:11
Hi Brett,
I have found another solution: to fix the panel style (calling it panel2):
stylize/master [
panel2: image with[
feel: none append init [
set var parent-face: layout/parent/size/styles second :action
self size copy self/styles
]
]
]
I have not tested it very much.
---
Ciao
Romano
[9/12] from: rotenca:telvia:it at: 24-Mar-2002 20:04
Hi Brett,
> I see your point but I disagree. Nothing demands all scripts to change.
> People can choose to use the patch or not - even on a script by script
<<quoted lines omitted: 3>>
> script if you want it to work on later versions of View - whether you
> use my patch or not (see below).
I understand your point of view. But if RT doesn't want to make many scripts
fail, they must introduce a new style with a different behaviour. I put
patches in my user.r so i can't easy change layout for every script i launch
(perhaps it is not the best choice).
> Your logic would imply that you will not use your modified win-offset?
> and screen-offset? functions. I most likely will - they will save me
> time in future.
True. If the patch generates more problems than it resolve it should not been
used. We must evaluate if the patch is time saving or time wasting, it is not
always easy. For example i have a patch of mine to make show-popup truely
modal, but i think it is an hack which can easy fail in the next version, so i
do not use it. I have a patch whic makes layout more fast but i think that
layout is a function that will change in future, so i do not want to use a
patch which i am sure it will fail in the next version only for a 20-30% gain.
Instead i think that your patch of FTP must be used, because we have no
alternative to read some sites, so i think which it is a good patch. And i
think that win-offset and screen-offset are so buggy that they must absolutely
changed by RT. The last two, indeed, are not patches in the true sense of
word, are different and indipendent functions which i could use with a
different name.
> As for checking all the styles, etc, that is RT's job - I've notified
> them of the bug through feedback. They'll decide whether it should be
Tell me: the feedback send you back a ticket? The last 2 times i emailed them
they do not send back any ticket like in the previous times. (i do not speack
of answer, i see one of them every four bugs sent :-)
> changed or not. Though I believe it is only variables set to PANEL that
> are affected at this time (Rebol/View).
I think you are right.
> BTW, I did a quick search but could not find PANEL being used by RT
> styles internally could you give an example please?
I did not say that it is used, i said we must check all the RT code to be sure
nothing is mess. Indeed, I can't find any use of it. And i ask myself why RT
in the How-to on making sub-panels does not speak of panel style?
> From my point of view I prefer not to make my scripts dependent on
> bugs. I'd rather patch a bug so that my script will not break when the
> bug is eventually fixed or make it tolerant to change. And I do expect
> a change. The core language is changing so I assume the graphical
> mezzanine functions are open to change too.
Well, but often bugs are corrected with a new function, a new arg, a new flag.
For example: a new panel style like mine in the previous message. We can not
know what will make RT. Another thing: if layout changes and the bug is not
repaired or is repaired with a new style, your patch will fail, else if RT
changes layout and the style, both method will fail. It is not easy to say
what is the right thing, and in this case i prefer not to change layout. But i
could be wrong.
> As I mentioned above I believe the direct solution is likely to fail in
> futur and even if you don't agree with the patch, I think you should
<<quoted lines omitted: 9>>
> p: lyo/pane/1
> These workarounds are dependent on good behaviour not bad.
This is a good point, but not always i have a var pointer to the inner faces.
I have took my decision: i'll use a new panel style like panel2 in the
previous message, so i should be in a safe zone :-)
> Anyways this discussion illustrates a fundamental issue with
> distributed systems. I was once told by a project leader of Java
> projects that Java meant "Write once, test everywhere". Rebol is not at
> that stage (yet?). Maybe though some conventions or language support
> are required to ensure my changes and yours will work on all systems.
Back compatibility is a must for RT? I do not know.
---
Ciao
Romano
[10/12] from: brett:codeconscious at: 25-Mar-2002 7:27
Hi Romano,
Thanks for your message. Your panel2 style looks promising.
> Tell me: the feedback send you back a ticket? The last 2 times i emailed
them
> they do not send back any ticket like in the previous times. (i do not
speack
> of answer, i see one of them every four bugs sent :-)
No. No feedback ticket.
Regards,
Brett.
[11/12] from: rotenca:telvia:it at: 24-Mar-2002 23:49
Hi, Brett
Here it is my last version of panel, the previous one did not work with local
words (because layout do not preserve binding):
stylize/master [ana-panel: IMAGE with [
words: [setvar [new/var: second args next args]]
feel: none
append init [
parent-face: layout/parent/size/styles second :action self size copy
self/styles
if word? var [set var parent-face]
]
]
]
use [p][layout [ana-panel setvar 'p [text]] dump-face p]
---
Ciao
Romano
[12/12] from: brett:codeconscious at: 25-Mar-2002 19:57
Hi Romano,
> Here it is my last version of panel, the previous one did not work
with local > words (because layout do not preserve binding):
Now you are getting innovative ;^)
I was thinking some more about the issue of bugs, patches and
distributed systems. The situation with the bug in layout is a bit like
the Intel Pentium floating point bug that came out a few years back.
Compiler writers included code that could tolerate that problem to take
the burden off the programmers.
Now my preference is to write scripts as much as possible against a bug
free environment - I don't want to clutter my code with exceptions
(bugs) that having nothing to do with the logic of my script. But I
take your point that patches introduce potentially more problems.
So perhaps the solution of the compiler writers should be used here.
Obviously not a ground-shaking conept, but it seems like a good
compromise. It comes back to the smart script builder (or library) idea
that has ben discussed before. Perhaps we could use a smart Rebol
script builder to "finalise" (make) a script. To finalise a script
might mean applying patches and bug fixes automatically, with a version
check in built to warn the user if they are using the script against an
untested version or product of Rebol. This is close to what Rebol does
with NEEDS anyway. The problem then is that a given script has a built
in obsolesence and another later version script would need downloading
when the old one "expired". Back to the "upgrade to solve" problem :-/
Oh well.
Brett.
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted