drawing images on text face after displayed = "highlighting text"
[1/14] from: fergus4:bellatlantic at: 1-Oct-2008 2:45
Is there a way to append an image object (a box for example) to a face that
has already been displayed. I'm looking to get simple highlight
functionality in an app in which a string is scanned for in a series of text
faces.
I've been able to highlight the search word in each face but if I click in
any of the text faces the face looses the highlight effect sort of like
loosing focus on normal highlighting.
I would like the highlight to remain until no longer needed
What I got working:
rebol []
pad: 20x30
window: layout [
bx: box red 0x0
panel: panel [
text 400 "Here is a simple example how to use DRAW dialect
for into alpha channel of the image. I think with the function make-alpha
(bellow in the example) you can draw almost any kind of transparent shape
though it is not the fastest method....IMO the possibility to use DRAW pens
for alpha channel should be done at Rebol's native level"
t: text 400 "Here is a simple example how to use DRAW
dialect for e-alpha (bellow in the example) you can draw almost any kind of
transparent shape though it is not the fastest method....IMO the possiinto
alpha channel of the image. I think with the function make-alpha (bellow in
the example) you can draw almost any kind of transparent shape though it is
not the fastest method....IMO the possibility to use DRAW pens for alpha
channel should be done at Rebol's native level"
text 500 "can draw almost any kind of transparent shape
though it is not the fastest method....IMO the possibility to use DRAW pens
for alpha channel should be done at Rebol's naHere is a simple example how
to use DRAW dialect for into alpha channel of the image. I think with the
function make-alpha (bellow in the example) you can draw almost any kind of
transparent shape though it is not the fastest method....IMO the possibility
to use DRAW pens for alpha channel should be done at Rebol's native level"]
button "Highlight" [foreach face panel/pane [if face/style = 'text [
system/view/focal-face: face
system/view/highlight-start: find face/text "into alpha channel of
the image"
system/view/highlight-end: find/tail face/text "into alpha channel
of the image"
show face
]]]
button "Paint" [foreach face panel/pane [if face/style = 'text [
keyword: "transparent"
xy: caret-to-offset face find face/text keyword
bx/offset: face/offset + pad + xy
bx/size: as-pair (5.9 * length? keyword) 15
show face
]]]
]
view window
-Alan Macleod
[2/14] from: anton::wilddsl::net::au at: 1-Oct-2008 18:17
Hi Alan,
The problem is, VID only provides one highlight-start and
highlight-end, and one caret, shared amongst all faces.
('Highlights' are separate from the concept of 'selection',
but VID calls the current text selection a 'highlight').
Therefore, you need to patch VID and the focus system so that it
does highlighting *optionally*, not automatically, and write a
custom text style which chooses not to exercise that option. :)
I expect each of your custom text faces should allow multiple
highlights, so create a 'highlights' facet block, and store
each pair of highlight-start/highlight-end in there.
To implement it, you need to maintain several 'highlight faces',
one for each highlight in the highlights facet.
(These highlight faces are like your red box.)
The highlight faces go into the PANE block of your custom
text style face.
See example code at bottom.
Your "Paint" button uses an interesting technique to
draw
the same box multiple times at multiple locations.
I don't recommend this technique, because you never know
when the next redraw will clear it.
You should better implement multiple boxes in your custom
text style's pane block.
There are more problems to solve, like accurately finding the
position of some text in all cases (ie. doing a better job than
CARET-TO-OFFSET does) and maybe opting out of the automatic
system caret placement on focus.
I've solved some of these problems already.
I have several modular VID patches, which allows customised
AREA and FIELD style replacements to draw their own
highlight and caret.
It should be relatively easy (for me, anyway!) to add multiple
highlighting to these styles.
http://anton.wildit.net.au/rebol/patch/caret-to-offset-patch.r
http://anton.wildit.net.au/rebol/patch/focus-system-patch.r
http://anton.wildit.net.au/rebol/patch/ctx-text-caret-highlight-patch.r
do http://anton.wildit.net.au/rebol/gui/demo-area.r
do http://anton.wildit.net.au/rebol/gui/demo-field.r
do http://anton.wildit.net.au/rebol/gui/demo-edit-panel.r
do http://anton.wildit.net.au/rebol/gui/demo-edit-panels.r
... so the answer to your question is: "yes".
Regards,
Anton.
Alan Macleod wrote:
> Is there a way to append an image object (a box for example) to a face that
> has already been displayed. I'm looking to get simple highlight
<<quoted lines omitted: 5>>
> I would like the highlight to remain until no longer needed
> -Alan Macleod
rebol []
stylize/master [
my-text: text with [
highlights: [] ; custom facet
init: [
pane: copy []
]
add-highlight: func [start end][
append append highlights start end
refresh-highlights
show self
]
highlight-box: make-face/spec 'box [
size: 50x18
effect: [merge multiply yellow] ; translucent
]
refresh-highlights: has [n][
n: 0
foreach [start end] highlights [
n: n + 1
if n > length? pane [
append pane make highlight-box []
]
pane/:n/offset: 30x22 * (n - 1)
; (use CARET-TO-OFFSET here etc.)
]
clear skip pane n ; remove old highlights
]
feel: make feel [
redraw: func [face action position][
;face/refresh-highlights
]
]
]
]
view layout [
my-text: my-text 400x300 {Hello how are you going^/Just wonderful
thankyou.}
btn "Add highlight" [my-text/add-highlight 10 20]
]
[3/14] from: henrikmk:gmai:l at: 1-Oct-2008 12:30
On Wed, Oct 1, 2008 at 10:17 AM, Anton Rolls <anton-wilddsl.net.au> wrote:
Anton, how do you solve marking up multiple lines? I'm building
something similar with boxes, but have yet to find out how to figure
out where text is broken into multiple lines for display, so I can
detect start of line and end of line.
--
Regards,
Henrik Mikael Kristensen
[4/14] from: fergus4:bellatlantic at: 1-Oct-2008 8:14
Henrik,
I was going to map the start and endpoints using caret_to_offset on find
text and find/tail text. And knowing the text field width paint multiple
boxes to fit the shape. Not pretty but I think good enough for what I want.
Or is the function that highlight_start and highlight-end uses available or
is it hidden too deep (not mezzazine)
Anton, or Henrik,
Is it possible to use the draw dialect to "paint" these highlights? The way
a simple paint program pains into an area?
[5/14] from: henrikmk:gma:il at: 1-Oct-2008 14:26
On Wed, Oct 1, 2008 at 2:14 PM, Alan Macleod <fergus4-bellatlantic.net> wrote:
> Henrik,
>
> I was going to map the start and endpoints using caret_to_offset on find
> text and find/tail text. And knowing the text field width paint multiple
> boxes to fit the shape. Not pretty but I think good enough for what I want.
I use almost the same method.
> Or is the function that highlight_start and highlight-end uses available or
> is it hidden too deep (not mezzazine)
>
> Anton, or Henrik,
>
> Is it possible to use the draw dialect to "paint" these highlights? The way
> a simple paint program pains into an area?
You can probably do that with the SHAPE command in DRAW. To ensure
accurate painting, I would use SIZE-TEXT as it can accurately detemine
the width and height of the area you need to paint per row.
My implementation uses plain boxes and then SIZE-TEXT to calculate the
size of one highlight box. It works for all font sizes I've tested so
far. My only problem right now is detecting the start and end point of
multi-line text as I want a more accurate depiction of the selected
text.
To detect multiple line highlights: If the Y position of
caret-to-offset is not identical for start and end position, then you
are using multiple lines.
--
Regards,
Henrik Mikael Kristensen
[6/14] from: fergus4:bellatlantic at: 1-Oct-2008 8:41
Henrik,
How do you use size-text to find the size for a row or highlighted section?
I can only find the size of the entire text face.
[7/14] from: henrikmk:gmai:l at: 1-Oct-2008 15:02
On Wed, Oct 1, 2008 at 2:41 PM, Alan Macleod <fergus4-bellatlantic.net> wrote:
> Henrik,
>
> How do you use size-text to find the size for a row or highlighted section?
> I can only find the size of the entire text face.
You shouldn't use size-text on the original face.
Something like:
size-text make t [size: 2000x50 text: highlighted-text]
Explanation: You make a copy of the original text face for measurement
purposes, and then let it only contain the highlighted text. (I guess
View needs to render the text internally to return the size of it.)
You then need the exact same text attributes (font and para) for it to
measure the size correctly. You also need a rather big size in order
for the text in the new face to flow correctly to avoid unintended
linebreaks as we want the text to match the original.
--
Regards,
Henrik Mikael Kristensen
[8/14] from: fergus4:bellatlantic at: 1-Oct-2008 11:47
I tried some similar things to get the highlighted text in a temp face but
could not get it to work...
Thanks again..
-Alan Macleod
[9/14] from: henrikmk::gmail at: 1-Oct-2008 17:54
On Wed, Oct 1, 2008 at 5:47 PM, Alan Macleod <fergus4-bellatlantic.net> wrote:
> I tried some similar things to get the highlighted text in a temp face but
> could not get it to work...
My code so far (stolen from your original code submission):
rebol []
pad: 20x30
set-highlight: func [
"Sets the highlight boxes in the given text face"
face [object!]
strings [block!] "Block of one or multiple string pairs describing
the highlight start and end points"
/no-show
/local access
] [
if all [
access: get in face 'access
in access 'set-face*
] [
access/set-highlight* face strings
]
if not no-show [show face]
face
]
get-highlight: func [face [object!]] [
; unimplemented
]
window: layout [
style hl-text text with [
pane: make block! []
hl: none
; a single highlight face
hl-face: make face [
color: 255.0.0
edge: none
para: make para [origin: 0 margin: 0]
effect: [gradient 0x1 255.128.0 255.0.0] ; just to make it look
a little cooler
]
; the pane which stores all highlight faces
hl-pane: make face [color: none pane: make block! []]
; the position in pane for the highlight pane as used by set-highlight*
hl-pane-block: none
make-hl-face: func [face str pos sz] [
append face/hl-pane-block make face/hl-face [offset: pos - 2
size: sz text: str]
]
split-lines: make block! []
access: make access [
set-highlight*: func [face [object!] strings [block!] /local pos
end-pos split-lines str sz done] [
face/hl: strings
clear face/hl-pane-block
; create highlight boxes
foreach [start end] face/hl [
; paint a box for each highlight by finding the position on
where to paint it using caret-to-offset to get the position.
; is the highlight split over multiple lines?
; the end-pos can't be used here, we need to do the split
thing before calculating positions
str: copy/part start end
sz: size-text make face/hl-face [size: 2000x50 text: str]
pos: caret-to-offset face start
end-pos: caret-to-offset face end
either pos/y <> end-pos/y [ ; multiple lines
; ---------- The code in this block is not working
correctly ------------
; paint one box per line for multiple line highlights
; that means that each line must paint right from start or
beginning of line to either the end of highlight or end of line
; generate split-lines list of all indexes required for
painting the lines
clear split-lines
line-pos: start
; we should be able to use the line list, but something is
not right here.
; the line list is not set, but it would be manipulated by
something, so we should figure out what that is
until [
; calculate start of line or none
sol:
; calculate end of line or none
eol:
case [
; start of line to end of line
all [sol eol] [repend split-lines [sol eol] false]
; start of text to end of line
all [none? sol eol] [repend split-lines [start eol] false]
; start of line to end of text
all [sol none? eol] [repend split-lines [sol end] true]
]
]
foreach [start end] split-lines [
str: copy/part start end
sz: size-text make face/hl-face [size: 2000x50 text: str]
pos: caret-to-offset face start
make-hl-face face str pos sz
]
][
make-hl-face face str pos probe sz
]
]
show face
]
]
append init [
; prepare the highlight face to have the right font
hl-face/font: make font [offset: 0x0 color: white]
unless all [block? pane none? pane] [pane: make block! []]
; position the hl-pane
hl-pane/color: none
hl-pane/size: size ; perhaps size optimize it later
hl-pane/offset: offset
append pane hl-pane
; prepare hl-pane-block
hl-pane-block: get in last pane 'pane
]
]
bx: box red 0x0
panel: panel [
tt: hl-text 500 font-size 12 {Here is a simple example
how to use DRAW dialect
for into alpha channel of the image. I think with the function make-alpha
(bellow in the example) you can draw almost any kind of transparent shape
though it is not the fastest method....IMO the possibility to use DRAW pens
for alpha channel should be done at Rebol's native level}
t: text 400 {Here is a simple example how to use DRAW
dialect for e-alpha (bellow in the example) you can draw almost any kind of
transparent shape though it is not the fastest method....IMO the possiinto
alpha channel of the image. I think with the function make-alpha (bellow in
the example) you can draw almost any kind of transparent shape though it is
not the fastest method....IMO the possibility to use DRAW pens for alpha
channel should be done at Rebol's native level}
text 500 {can draw almost any kind of transparent shape
though it is not the fastest method....IMO the possibility to use DRAW pens
for alpha channel should be done at Rebol's naHere is a simple example how
to use DRAW dialect for into alpha channel of the image. I think with the
function make-alpha (bellow in the example) you can draw almost any kind of
transparent shape though it is not the fastest method....IMO the possibility
to use DRAW pens for alpha channel should be done at Rebol's native level}]
button "Highlight" [foreach face panel/pane [if face/style = 'text [
system/view/focal-face: face
system/view/highlight-start: find face/text "into alpha
channel of the image"
system/view/highlight-end: find/tail face/text "into alpha
channel of the image"
show face
]]]
button "Paint" [foreach face panel/pane [if face/style = 'text [
keyword: "transparent"
xy: caret-to-offset face find face/text keyword
bx/offset: face/offset + pad + xy
bx/size: as-pair (5.9 * length? keyword) 15
show face
]]]
button "Box highlight" [
set-highlight tt reduce [
; one start and end highlight component per line
find tt/text "IMO" skip find tt/text "IMO" 10
find tt/text "native" skip find tt/text "native" 4
]
]
]
view window
--
Regards,
Henrik Mikael Kristensen
[10/14] from: fergus4:bellatlantic at: 1-Oct-2008 12:23
Looks nice. I can't get it to do multiple faces though. I'll work on it.
Thanks.
-Alan
[11/14] from: anton:wilddsl:au at: 2-Oct-2008 2:36
Hi Henrik,
In my edit-panel style, I stored the text data as lines
(a block of strings), not a single string, so I didn't have
this problem.
face/line-list used to be a block of offsets to each line,
but, while the facet still exists, it is set to none by
the View system, probably natively. So it's a mystery to me.
Regards,
Anton.
Henrik Mikael Kristensen wrote:
[12/14] from: anton:wilddsl:au at: 2-Oct-2008 2:37
Hi Alan,
Alan Macleod wrote:
> Henrik,
>
> I was going to map the start and endpoints using caret_to_offset on find
> text and find/tail text. And knowing the text field width paint multiple
> boxes to fit the shape. Not pretty but I think good enough for what I want.
>
> Or is the function that highlight_start and highlight-end uses available or
> is it hidden too deep (not mezzazine)
Hidden too deep I think. But can be worked around, I think.
> Anton, or Henrik,
>
> Is it possible to use the draw dialect to "paint" these highlights? The way
> a simple paint program pains into an area?
Yes, it is.
> How do you use size-text to find the size for a row or highlighted
section?
> I can only find the size of the entire text face.
You can't do it in place. I've obtained this by use of workarounds
which you can see working pretty well in
demo-caret-to-offset-patch.r and
test-caret-to-offset-patch.r
See my lengthy investigations in these files.
http://anton.wildit.net.au/rebol/doc/field-text-draw.r
http://anton.wildit.net.au/rebol/view/draw/smooth-font-scaling.r
http://anton.wildit.net.au/rebol/patch/demo-caret-to-offset-patch.r
http://anton.wildit.net.au/rebol/patch/test-caret-to-offset-patch.r
Especially those last two files.
Regards,
Anton.
[13/14] from: henrikmk:gma:il at: 1-Oct-2008 19:26
On Wed, Oct 1, 2008 at 6:36 PM, Anton Rolls <anton-wilddsl.net.au> wrote:
> Hi Henrik,
> In my edit-panel style, I stored the text data as lines
<<quoted lines omitted: 3>>
> but, while the facet still exists, it is set to none by
> the View system, probably natively. So it's a mystery to me.
Thanks for the reply, Anton. I was wondering about line-list myself
and how useless it is for this case. Now I don't need to waste any
more hours on that. :-)
--
Regards,
Henrik Mikael Kristensen
[14/14] from: carl:cybercraft at: 1-Oct-2008 21:35
A quick response...
One simple way to have an image appear after the layout has been shown would be to include
it in the original layout and change its offset to -100x-100 (or whatever's required
to stop it being visible) before the layout is shown. Then when you want to show the
image just change its offset again - and the image too, if required.
Hope that's useful, and within the ballpark of what you're wanting to do...
-- Carl Read.
On Wednesday, 1-October-2008 at 2:45:35 Alan Macleod wrote,
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted