In all of our releases, from our initial preview release up to and including our 0.3.x series, the gameboard has been a fixed size. We tried to choose a size that was large enough to be easily visible and still be small enough to fit on everyone's monitors. An assumption that we made is that everyone will be using, at a minimum, 1024x768 as their screen resolution. The size of the gameboard was adjusted to match that assumption.
While this assumption is probably true, we should not be taking it as a given. There could be people who still use 800x600, or even lower. Conversley, there also could be people with very large displays; sizes of 1600x1200 and 1920x1200 are not unheard of these days, and the gameboard would appear rather small on those monitors.
I'm still rather new at using the GTK to create user interfaces, and I'm still learning the ropes of custom widget creation. Until now, despite extensive google-ing, I have not been able to determine how to detect the actual assigned size of a widget.
A little bit of an explaination might be in order. In the GTK, you have the option of requesting a fixed size for your widgets, but that is not the most desirable approach. There are certain controls that act as containers. These controls allow you to add other controls to areas inside of them. Once you have added these controls, it will automatically size them for you, based on preference selections you make. As such, there is no fixed size for a widget, and the programmer's code usually never explicitly sets the widget size; there is no work left to be done. Because of this, I had no way of knowing how large the widget would be if I allowed it to scale freely.
And then I found it. It had looked dillegently, but had - in the end - given up. self.allocation.height and self.allocation.width allow you to determine the real height of your custom widget in pixels. With this information, the map can be made scalable. Can be, and has been. There is no tickbox to tick or slider to slide; just resize the window, and the gameboard should scale with it.
In addition to being scalable, there are two new preferences that can now be set; outline thickness and troop text size.
Resizing still takes a little bit of machine power, as a lot of memory space has to be adjusted to fit the new sizes, but we've been able to cut that down some already. Obviously there are still some practical restrictions on how small the map can be, and for now, there are also speed-related problems with gameboards that are exceedingly large. Even if we can't move beyond those problems, though, I think that this is still a nice improvement over the old fixed-size board.
The scaling gameboard means that in the future (hopefully by our 0.4 release), the gameboard will not have a rigid fixed size like it does now.
Showing posts with label cairo. Show all posts
Showing posts with label cairo. Show all posts
Saturday, January 19, 2008
Wednesday, January 16, 2008
Cairo and the GTK in Ruby. Creating Custom Widgets.
This post is more about programming than it is about OpenFracas.
When I was trying to learn how to use cairo to create custom widgets in the GTK with ruby, I ran into a real lack of documentation online. There were lists of functions and all, but lists of functions just don't compare to samples, as far as I'm concerned. So I've decided to put together a little bit of code that can be used as a how-to or as a starting point for someone else's projects
The following Ruby code is an example of a custom GTK control created using the RCairo SVG library (cairo is built into GTK 2.8+) by extending the Gtk::DrawingArea class.
#we need to include these for obvious reasons
require 'gtk2'
require 'cairo'
#This class extends Gtk::DrawingArea
class CustomWidget < Gtk::DrawingArea
end
That is a very basic example. From what I understand, it would be a good idea to try and buffer it by using an ImageSurface and creating a graphics context for it, then drawing to the ImageSurface's context. Once you're done, you can set the window context's source to the ImageSurface, and .fill the area.
for example, to create the image
@image = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, height, width) @imageContext = Cairo::Context.new(@image)
Then in the fRedraw function where context is the window's context
context.set_source(@image, 0, 0)
context.paint
You'll still need to add this control to a parent control such as a window or a layout container. You'll also need to .show it for it to be visible.
For drawing things with a fixed scale, you can use the .scale command to scale a context down to a specific size. There's a really good tutorial for using cairo for drawing here. It's in Python, but it's still very helpful.
When I was trying to learn how to use cairo to create custom widgets in the GTK with ruby, I ran into a real lack of documentation online. There were lists of functions and all, but lists of functions just don't compare to samples, as far as I'm concerned. So I've decided to put together a little bit of code that can be used as a how-to or as a starting point for someone else's projects
The following Ruby code is an example of a custom GTK control created using the RCairo SVG library (cairo is built into GTK 2.8+) by extending the Gtk::DrawingArea class.
#we need to include these for obvious reasons
require 'gtk2'
require 'cairo'
#This class extends Gtk::DrawingArea
class CustomWidget < Gtk::DrawingArea
def initialize#call Gtk::DrawingArea's constructor first
super()
#connect the expose event
#(means drawing is needed)
#to the fRedraw function
self.signal_connect("expose_event") doend
fRedraw
end
#called when we get an expose event
def fRedraw#create our drawing context.#whatever we draw on this ends up on the screen #self.window is a Gdk::Windowend
context = self.window.create_cairo_context
#get the actual height/width of this control
height = self.allocation.height.to_f
width = self.allocation.width.to_f
#make drawing occur offscreen (double-buffering)
rect = Gdk::Rectangle.new(0, 0, self.allocation.width, self.allocation.height)
self.window.begin_paint(rect)
#set the colour and flood the region
c.set_source_rgba(0.5, 0.4, 0.6, 0.9)
c.paint
#set the colour and draw a line
c.set_source_rgba(0, 0, 0, 0.9)
c.move_to(height / 2.0, width / 2.0)
c.rel_line_to(height, width)
c.stroke
self.window.end_paint
end
That is a very basic example. From what I understand, it would be a good idea to try and buffer it by using an ImageSurface and creating a graphics context for it, then drawing to the ImageSurface's context. Once you're done, you can set the window context's source to the ImageSurface, and .fill the area.
for example, to create the image
@image = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, height, width) @imageContext = Cairo::Context.new(@image)
Then in the fRedraw function where context is the window's context
context.set_source(@image, 0, 0)
context.paint
You'll still need to add this control to a parent control such as a window or a layout container. You'll also need to .show it for it to be visible.
For drawing things with a fixed scale, you can use the .scale command to scale a context down to a specific size. There's a really good tutorial for using cairo for drawing here. It's in Python, but it's still very helpful.
Subscribe to:
Posts (Atom)