Question on using images on panels

I’m trying to place a simple logo on one of the panels within the center
of my main gui. In DialogBlocks, the panel class is LogoPanel which
when using xrcise to generate the ruby file from xrc, creates:

@logo = finder.call(“logo”)
@logo.extend(LogoPanel)

In my main loop I have:

class GuiMain < XrcFrameMain
def initialize
super()
evt_menu( @mb_fm_new, :on_new_workspace )
evt_menu( @mb_fm_save, :on_save_workspace )
evt_menu( @mb_fm_exit, :on_exit )
st_response(“Idle…”,2)
st_response(Time.now.strftime("%B %d, %Y"), 1)
end
end

module LogoPanel

logo image

img_file = File.join( File.dirname(FILE)+"/…/images/kirin",
‘logo.png’)
@bitmap = Wx::Bitmap.new(img_file, Wx::BITMAP_TYPE_PNG)
self.paint do |dc|
dc.draw_line(@bitmap, @offset, @offset, false)
end
end

which generates the following error:

E:\Gui-Development\Kirin>ruby start
E:/Gui-Development/Kirin/lib/main.rb:25:in <module:LogoPanel>': undefined metho dpaint’ for LogoPanel:Module (NoMethodError)
from E:/Gui-Development/Kirin/lib/main.rb:20:in <top (required)>' from start:12:inload’
from start:12:in `’

I can’t make the LogoPanel a class because I will receive an error that
it was expecting a module to be there. So, I believe the class for this
particular panel expects a module class. Without this code in there, or
just using:

module LogoPanel
end

… the gui will show but the section where the logo should appear is all
white as it is missing the paint.

This is a rather important topic for me because I’d like to understand
better how to paint and change the appearance of my GUI in many areas…

For instance, I want to add a custom png file as the background of my
entire GUI and then paint the logo on the side, etc. This app will be
used cross platform so the images will have to be converted to a usable
source, which I haven’t gotten into yet.

Any ideas on everything I just posted?

Thanks.

Hello Alpha,

On Fri, Jan 22, 2010 at 12:36 PM, Alpha B. [email protected]
wrote:

def initialize

logo image

img_file = File.join( File.dirname(FILE)+“/…/images/kirin”,
‘logo.png’)
@bitmap = Wx::Bitmap.new(img_file, Wx::BITMAP_TYPE_PNG)
self.paint do |dc|
dc.draw_line(@bitmap, @offset, @offset, false)
end
end

This part is where you have the problem, your doing the call to
self.paint
in the top level of the module, which self is the Module Class, and in
which
does not have a paint method associated with the module itself. Even
after
you extend your object to include the Module, this code still is
expecting
self to be the Module, not the class instance that your extending.
Therefore, your problem lies with this.

The solution to this, is to do the following with your module:

module LogoPanel
def setup_resources
img_file =
File.join(File.dirname(FILE),“…”,“images”,“kirin”,“logo.png”)
@bitmap = Wx::Bitmap.new(img_file, Wx::BITMAP_TYPE_ANY)
self.evt_paint do |event|
self.paint do |dc|
dc.draw_bitmap(@bitmap,0,0,false)
end
end
end
end

Then just after your @logo.extend(LogoPanel), you just type
@logo.setup_resources()

Now, you’ll notice two things different in my version, compared to
yours, as
far as setting things up, I put everything into a Method that you will
need
to invoke, in order to get your Bitmap to use for drawing, and in the
method
in which I get the filename. With File.join(), it has a variable
argument
passing setup to the signature for it, so you can pass as many
parameters to
it that you want, and it will build up the path, with the operating
system
slash in use. This is the optimal method in which to build paths, as
it’s
never a guarantee that the ‘/’ slash character will work. File.join()
will
automatically use the correct path separator for you.

Lastly, I used draw_bitmap, instead of draw_line, as this is just the
most
simplest way in which to do this, when not using a Wx::StaticBitmap, to
display the Image, which is another option, instead of you drawing it
yourself, as WxWidgets and wxRuby will handle the drawing of the bitmap
for
you.

which generates the following error:

I can’t make the LogoPanel a class because I will receive an error that
This is a rather important topic for me because I’d like to understand
better how to paint and change the appearance of my GUI in many areas…

For instance, I want to add a custom png file as the background of my
entire GUI and then paint the logo on the side, etc. This app will be
used cross platform so the images will have to be converted to a usable
source, which I haven’t gotten into yet.

As for this, if you want to use a custom png for the background of your
entire GUI, the best suggestion to use, is the evt_erase_background
method
for catching background erases, and drawing custom images for the
background
of your application. In this method, you need to do the following:

self.evt_erase_background do |event|
self.paint do |dc|
dc.draw_bitmap(@bitmap,0,0,false)
end
end

hth,

Mario

Hi Mario,

It’s all working now. Here’s the touched up code:

I’m able to color the background of the main gui and place the logo in.
There’s only one issue and that is I notice I see a border on the logo.
My guess is it’s due to a border I might have set in dialogblocks so
I’ll troubleshoot from there.

thanks again.

Okay one last follow-up. Here’s what it’s looking like with the code.
Keep in mind that these two images are just examples and not what I’ll
actually use in my GUI.

The two problems I see are:

The Kirin logo to the top left just below the toolbar has a tiny bit of
gray space just above the top of it. In addition, it has some strange
white border around the image. I checked dialogblocks and removed all
of the borders, setting them to 0 and unclicked them but they still
appear.

Secondly, when the image is sized there’s tearing across the platform.

Lastly, I’m not sure how to use just a small one pixel png image and
stretch it as the entire background of my program using this code.

Thoughts?

Many thanks.

My fix for this was the following:

  1. Until I can figure out how to make a small static image (say 1px x
    10px) stretch and fill the entire window of my gui on user resize, and
    have it paint correctly, I ended up forcing a no-resize option on the
    gui and created a static image using the suggestions posted above.

  2. The small gap between the picture was borders that were set on the
    sizers themselves with dialogblocks. On almost all elements that
    dialogblocks places on the screen, they all seem to start out with a 5
    width top,right,left,bottom border. So, if anyone encounters something
    similar, make sure to remove all the borders. The same thing happens
    when you insert spacers.

So, this particular issue is closed unless someone can guide me with a
step-by-step process on how to set a small .png as a scaled background
on resize events.

Thanks.

Hi Mario,

I’m losing hair and you just saved me from pulling out the rest of it.
My thanks!

I actually understood everything you said and fixed it in a matter of 30
seconds. Once I saw how you extended the module, I felt a little silly.
But, that’s okay since I’m a novice designer in ruby. :slight_smile:

Here’s what I did and why I did it with changes from you:

My new module is:

module LogoPanel
def setup_resources
img_file =
File.join(File.dirname(FILE),"…",“images”,“kirin”,“logo.png”)
@bitmap = Wx::Bitmap.new(img_file, Wx::BITMAP_TYPE_ANY)
self.evt_paint do |event|
self.paint do |dc|
dc.draw_bitmap(@bitmap,0,0,false)
end
end
end
end

And I actually accessed it in initializers like such:

class GuiMain < XrcFrameMain
def initialize
super()

# File Menu - new workspace
evt_menu( @mb_fm_new, :on_new_workspace )
# File Menu - save workspace
evt_menu( @mb_fm_save, :on_save_workspace )
# File Menu - exit
evt_menu( @mb_fm_exit, :on_exit )
# Status Bar text (3 frames so 0,1,2 are relevant array positions)
st_response("Idle...",2)
st_response(Time.now.strftime("%B %d, %Y"), 1)

# setup the logo here
@logo.setup_resources()

end
end

I didn’t want to put the @logo.setup_resources() after the code in the
ruby file that’s being translated from XRC because it states not to
change any of the file but to instead extend upon the file.

My biggest issue has been trying to understand how to tie in modules and
other classes and where to place the code. You’ve helped me out a bunch
with regards to this. I plan on changing my initializers so that the
events are all stored in a method like:

def register_event_handler
evt_menu( @mb_fm_new, :on_new_workspace )
evt_menu( @mb_fm_save, :on_save_workspace )
evt_menu( @mb_fm_exit, :on_exit )
end

and then the initializers file can look like such:

class GuiMain < XrcFrameMain
def initialize
super()

# Status Bar text (3 frames so 0,1,2 are relevant array positions)
st_response("Idle...",2)
st_response(Time.now.strftime("%B %d, %Y"), 1)

# setup the logo here
@logo.setup_resources()

# process events
register_event_handler

end
end

I can do the same for objects that I need to have painted.

But, I’m unsure about how to go about painting the main gui. I see your
code but I’m not sure I understand it. Is it going into my
initializers?

self.evt_erase_background do |event|
self.paint do |dc|
dc.draw_bitmap(@bitmap,0,0,false)
end
end

and then supply a bitmap for it like I did with the logo? If so, then I
understand what you are trying to tell me and I thank you once again.

My largest issue was finding very little documentation on how to use
both WxRuby and DialogBlocks together simultaneously. I’ve been
figuring it all out as I go and the one tutorial I did fine was very
basic and trivial. So, it didn’t help me out as much as it could have.

Thank you.