Showing posts with label gui. Show all posts
Showing posts with label gui. Show all posts

Sunday, June 28, 2009

wxRuby: Changing Text Fonts and Colours

A reader recently asked me how to change the text font size and color for wxRuby controls such as the StaticText control. Let's take a look at how you can do this.

Imagine, if you will, that we have a StaticText control named my_control...

Changing Fonts

We'll begin by creating a new Font object by calling the Font.new() method:


my_font = Wx::Font.new()

Next, we'll set various attributes of our new Font object:

my_font.set_point_size(20)
my_font.set_family(Wx::FONTFAMILY_MODERN)
my_font.set_style(Wx::FONTSTYLE_ITALIC)
my_font.set_weight(Wx::FONTWEIGHT_BOLD)

Once we have our Font object defined to our satisfaction, we can then pass it to our control's set_font() method:

my_control.set_font(my_font)

Changing Colors

Text color is not an attribute of the Font object, but is rather the foreground color of the control. So, to change the color of the text, we call the control's set_foreground_colour() method and pass it a Colour object. We'll make it easy and use one of wxRuby's built-in Colour constants:

my_control.set_foreground_colour(Wx::RED)

Make a note of the spelling: colour, not color.

Further Reading

A simple working example can be found here.

Documentation of the Font object can be found here.

Documentation of the set_foreground_colour() method can be found here.

Documentation of the Colour object can be found here.

And there you have it. Let me know if you'd like to see more on this or other subjects.

Thanks for stopping by!

Sunday, November 11, 2007

Getting Started with the wxRuby GUI Toolkit

Many readers have asked "What is the best GUI toolkit?". There is no single answer to this question, and I won't try to lobby for my GUI of choice. Use whatever works best for you and your users.

I use the wxRuby library. It's cross-platform, provides a native look-and-feel, and is easy to install (via a gem) and distribute with your application (via RubyScript2Exe). Further features can be found in the wxRuby wiki here. wxRuby is the Ruby interface to wxWidgets, a very stable and widely-used widget toolkit.

Installing wxRuby is simple using RubyGems:


gem install wxruby

Though you can use a GUI designer, creating most forms "by hand" is probably simpler than you suspect. A useful wxRuby user interface can be created in less than 50 lines of code, as we shall see...

Let's create a simple form with a label, text box, combo box, and button. We start by requiring the wx library and including the Wx namespace:

require 'wx'
include Wx

We create a new class which inherits from the Wx::Frame class and includes an initialize method:

class MyFrame < Frame
def initialize()
super(nil, -1, 'My Frame Title')
end
end

The Frame class' super constructor method takes the following arguments (all but Parent are optional):

Parent: The window parent. This may be NULL. If it is non-NULL, the frame will always be displayed on top of the parent window on Windows.

ID: The window identifier. It may take a value of -1 to indicate a default value.

Title: The caption to be displayed on the frame’s title bar.

Position: The window position. A value of (-1, -1) indicates a default position, chosen by either the windowing system or Widgets, depending on platform.

Size: The window size. A value of (-1, -1) indicates a default size, chosen by either the windowing system or Widgets, depending on platform.

Style: The window style (ie, if the minimize, maximize, and close boxes appear on the Frame).

Further details on the Frame class can be found in the wxRuby wiki here.

Next, let's add the code to the initialize method to create a panel, which will contain the other controls:

@my_panel = Panel.new(self)

The self passed to the new constructor is a reference to the Frame object, which we are passing as the parent of the Panel object.

Next, we'll create a variety of controls, passing the newly created @my_panel as the parent of each control:

@my_label = StaticText.new(@my_panel, -1, 'My Label Text',
DEFAULT_POSITION, DEFAULT_SIZE, ALIGN_CENTER)
@my_textbox = TextCtrl.new(@my_panel, -1, 'Default Textbox Value')
@my_combo = ComboBox.new(@my_panel, -1, 'Default Combo Text',
DEFAULT_POSITION, DEFAULT_SIZE, ['Item 1', 'Item 2', 'Item 3'])
@my_button = Button.new(@my_panel, -1, 'My Button Text')

I recommend assigning all your form controls to instance variables. This is the reason for the '@' preceding each control variable name.

We want to bind the button click to a "my_button_click" method which we will add to this class later. We do with the evt_button method:

evt_button(@my_button.get_id()) { |event| my_button_click(event)}

Now we'll proceed to the layout: arranging the controls in the Panel. We'll do this using a BoxSizer, which we'll have arrange the controls vertically:

@my_panel_sizer = BoxSizer.new(VERTICAL)
@my_panel.set_sizer(@my_panel_sizer)

Next we add each control to the panel's sizer by calling the sizer's add method:

@my_panel_sizer.add(@my_label, 0, GROW|ALL, 2)
@my_panel_sizer.add(@my_textbox, 0, GROW|ALL, 2)
@my_panel_sizer.add(@my_combo, 0, GROW|ALL, 2)
@my_panel_sizer.add(@my_button, 0, GROW|ALL, 2)

See the Sizer.Add documentation for an explanation of the various parameters.

Our last line of code in the initialize method makes the frame visible:

show()

Don't forget to add the my_button_click method that is called by the button click:

def my_button_click(event)
# Your code here
end

That concludes our MyFrame class. Now we want to create a MyApp class that will call our MyFrame class:

class MyApp < App
def on_init
MyFrame.new
end
end

Finally, we create a new instance of our MyApp class and call its main_loop method:

MyApp.new.main_loop()

View the complete code here.

There you have it. A complete, but simple, wxRuby form. It's not much to look at...



...but it demonstrates the basics and we'll enhance it shortly.

Soon, we'll cover related topics: dressing up our GUI a little, using the wxSugar extensions, using a Forms designer such as wxFormBuilder.

Questions? Comments? Suggestions? Post a comment here or send me an email message.

Thanks for stopping by!

Digg my article

Sunday, October 21, 2007

Windows XP Visual Style Controls with wxRuby

wxRuby uses the native Microsoft Windows common controls when displaying widgets on a Windows OS. You may have noticed, however, that the form controls do not have the Windows XP look and feel. They have the flat and 2-dimensional look of earlier Windows versions...



...rather than having the rounded corners and 3-dimensional look of Windows XP...



Note, among other things, the "glowing button" effect when the mouse hovered over the "Get Films Data" button.

This is because Windows XP comes with both version 5 and version 6 of the Common Controls, but unless specifically instructed to use version 6, it will default to using version 5 controls.

So, how do you instruct Windows to use the version 6 controls for your wxRuby GUI application? By including a simple manifest XML file with your application.

Copy the following text into a new text file. Save the file as "rubyw.exe.manifest" in your ruby/bin folder, the same folder that contains rubyw.exe. You might also save a copy to the same folder as "ruby.exe.manifest".


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.8.6.0" processorArchitecture="X86"
name="Microsoft.Winweb.Ruby" type="win32"/>
<description>Ruby interpreter</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

When the ruby.exe or rubyw.exe interpreter is run, Windows will look for a manifest file matching the program name in the same folder. When it finds our manifest file, it will then use the version 6 controls, as defined in the <dependency> section of the manifest.

We place the file in our c:\ruby\bin directory because that is where ruby.exe and rubyw.exe are located. We name the file ruby.exe.manifest or rubyw.exe.manifest to match the name of the interpreter being run.

If you are compiling your application with RubyScript2Exe, copy the manifest file into the folder with your script, then embed the manifest file in your compiled executable using the RUBYSCRIPT2EXE.bin statement:

RUBYSCRIPT2EXE.bin = ["rubyw.exe.manifest"]

When your compiled executable is run, your manifest file will be extracted to the same temporary "/bin" folder as the rubw.exe (or ruby.exe) interpreter.

Questions? Comments? Suggestions? Post a comment here or send me email.

Thanks for stopping by!

Digg my article