custom control - drawing issues

Hi everyone,

I am not able to solve the problem with a custom control (see picture). How can get rid of those white corners? I assume you
need to work with masks but I just don’t get it. Can anyone give me a correct approach ?

project:
https://www.dropbox.com/s/3adfe3ogs1cw1vk/test_masks.xojo_binary_project?dl=0

You CAN create a mask for your image, but using the later Xojo versions, you don’t need to take that extra step. Make sure that the image is created on a transparent background (You don’t say what app you used to create the button pic), or is at least pure white &cFFFFFF. Save it as a .png and import it into your app. Xojo does a very good job for me of showing the pic on a transparent background (i.e. no white ghosts)

What are you trying to do there? You aren’t drawing to the mask in your code.

  1. Make a picture

  2. draw the mask:

// Fill the mask white bubble.Mask.Graphics.ForeColor = rgb(255, 255, 255) bubble.Mask.Graphics.FillRect(0, 0, bubble.Width, bubble.Height) // Now draw the black rounded rectangle (that will allow the gradient to show through behind) bubble.Mask.Graphics.ForeColor = rgb(0, 0, 0) bubble.Mask.Graphics.FillRoundRect( 0, 0, bubble.Width, bubble.Height, 13, 13 )

  1. then draw the gradient or whatever, you only need to draw the lines for the gradient because the corners are hidden by the mask.

On PC avoid doubleBuffer for canvas if you need transparency.

Hi Michel,
Can you elaborate on this?

On PC when doublebuffer is turned on, the canvas takes the color of the window background, and is opaque.

I basically wanted to create a transparent button control so to say. On MouseOver the frame will be drawn, otherwise only the Text.
For a simple rectancle it works but for other shapes am lost.

https://www.dropbox.com/s/ieywsyltz0s90kl/test_masks2.xojo_binary_project?dl=0

MouseExit:

MouseEnter:

[quote=232366:@Beatrix Willius]What are you trying to do there? You aren’t drawing to the mask in your code.

  1. Make a picture

  2. draw the mask:

// Fill the mask white bubble.Mask.Graphics.ForeColor = rgb(255, 255, 255) bubble.Mask.Graphics.FillRect(0, 0, bubble.Width, bubble.Height) // Now draw the black rounded rectangle (that will allow the gradient to show through behind) bubble.Mask.Graphics.ForeColor = rgb(0, 0, 0) bubble.Mask.Graphics.FillRoundRect( 0, 0, bubble.Width, bubble.Height, 13, 13 )

  1. then draw the gradient or whatever, you only need to draw the lines for the gradient because the corners are hidden by the mask.[/quote]

That won’t work unfortunately. it doesn’t give me results I want.

What did you try? Your code works here:

[quote] dim p as new Picture(g.Width, g.height, 32)
p.Mask.graphics.forecolor = &cffffff
p.Mask.graphics.fillrect 0, 0, p.Width, p.Height
p.Mask.graphics.forecolor = &c000000
p.Mask.graphics.fillroundrect 0, 0, p.Width, p.Height, 13, 13

dim endratio, ratio as double
dim max as integer = p.Height/2
dim sColor as color = &cffef32
dim eColor as color = &cffffffff

for i as Integer=0 to max
ratio = (( max - i ) / max )
endratio = ( i / max )
p.Graphics.ForeColor=rgb(eColor.Redendratio+sColor.Redratio, eColor.Greenendratio+sColor.Greenratio, eColor.Blueendratio+sColor.Blueratio,eColor.alphaendratio+sColor.Alpharatio)
p.Graphics.DrawLine 0,i,p.Width,i
next

return p[/quote]

Take note of the first line.

If you are on Windows, prepare for a lot of head-butting against the wall in this area. Even some of the commercial plugins have the little ring around that is the color of the parent window.

Are you on Windows?

[quote=232722:@Beatrix Willius]What did you try? Your code works here:

Take note of the first line.[/quote]

Gosh. That’s the result ->

This isn’t what I wanted and It looks horrible :slight_smile:

The best I could get is here:
https://www.dropbox.com/s/g1k8bqzwn1nw4aj/test_masks3.xojo_binary_project?dl=0

However if I change the backgorund color to a different color it’s doens’t look nice. I need a way to make a the inner
gradient from white to full “transparante white”.

[quote=232723:@Merv Pate]If you are on Windows, prepare for a lot of head-butting against the wall in this area. Even some of the commercial plugins have the little ring around that is the color of the parent window.

Are you on Windows?[/quote]

Nope. :slight_smile:

I tried it on Windows, doesn’t look good there either.

Sigh… the mask is just another picture. So manipulate it.

[quote=232718:@Rob Egal]I basically wanted to create a transparent button control so to say. On MouseOver the frame will be drawn, otherwise only the Text.

MouseExit:

MouseEnter:
[/quote]
2006 called, they’d like their button back.
:wink:

[quote=232733:@Tim Parnell]2006 called, they’d like their button back.
;)[/quote]

That’s not part of the discussion. In same cases it makes sense and you don’t even know where I need to use that kind of style.

You need to mask the mask. First draw the gradient in a picture that will act as the mask. Then create a second picture that draws white at just the rounded corners and draw that onto the gradient. Now this gradient image represents the masking you want. Create a third picture and set it’s mask to the gradient and return that.

[code]Function makeMask(g as Graphics, corner As integer) As Picture
//make an image of the gradient
dim gradmask As Picture = new Picture(g.Width, g.Height, 32)
dim gg As Graphics = gradmask.Graphics
gg.ForeColor = &cFFFFFF //fill white so it’s ‘clear’
gg.FillRect(0, 0, g.Width, g.Height)
dim max as integer = g.Height/2 //fill with gradient
dim ratio as double
for i as Integer=0 to max
ratio = i / max * 255
gg.ForeColor=rgb(ratio, ratio, ratio)
gg.DrawLine 0,i,g.Width,i
next

//make an image that will draw white at just the corners
dim rectmask As Picture = new Picture(g.Width, g.Height, 32)
gg = rectmask.Mask.Graphics
gg.ForeColor = &c000000
gg.FillRect(0, 0, g.Width, g.Height)
gg.ForeColor = &cFFFFFF
gg.FillRoundRect(0, 0, g.Width, g.Height, corner, corner)

//draw the white corners onto the gradient (so the corners are clear)
gradmask.Graphics.DrawPicture(rectmask, 0, 0)

//make an image with the constructed gradient
dim p As new Picture(g.Width, g.Height, 32)
p.Mask.Graphics.DrawPicture(gradmask, 0, 0)

return p

End Function
[/code]

Also, I modified it to take the corner radius so call it like this…

dim p as Picture = self.makeMask2(g, 13)

[quote=232808:@Will Shank]You need to mask the mask. First draw the gradient in a picture that will act as the mask. Then create a second picture that draws white at just the rounded corners and draw that onto the gradient. Now this gradient image represents the masking you want. Create a third picture and set it’s mask to the gradient and return that.

[code]Function makeMask(g as Graphics, corner As integer) As Picture
//make an image of the gradient
dim gradmask As Picture = new Picture(g.Width, g.Height, 32)
dim gg As Graphics = gradmask.Graphics
gg.ForeColor = &cFFFFFF //fill white so it’s ‘clear’
gg.FillRect(0, 0, g.Width, g.Height)
dim max as integer = g.Height/2 //fill with gradient
dim ratio as double
for i as Integer=0 to max
ratio = i / max * 255
gg.ForeColor=rgb(ratio, ratio, ratio)
gg.DrawLine 0,i,g.Width,i
next

//make an image that will draw white at just the corners
dim rectmask As Picture = new Picture(g.Width, g.Height, 32)
gg = rectmask.Mask.Graphics
gg.ForeColor = &c000000
gg.FillRect(0, 0, g.Width, g.Height)
gg.ForeColor = &cFFFFFF
gg.FillRoundRect(0, 0, g.Width, g.Height, corner, corner)

//draw the white corners onto the gradient (so the corners are clear)
gradmask.Graphics.DrawPicture(rectmask, 0, 0)

//make an image with the constructed gradient
dim p As new Picture(g.Width, g.Height, 32)
p.Mask.Graphics.DrawPicture(gradmask, 0, 0)

return p

End Function
[/code]

Also, I modified it to take the corner radius so call it like this…

dim p as Picture = self.makeMask2(g, 13)

That’s just perfect!!