I wrote the entire UI for my “Simple Skype” front end in wxRuby. wxRuby’s benefit comes from it’s use of widgets native to the window manager (i.e., Aqua on Mac OS X, etc.). And, while I only had a few problems with it, most of my problems were PEBKACs.
Sadly, the memory leak in my GUI, caused by the use of Bitmaps, was not among my PEBKACs. This is currently tracked as an open bug against Wx. It is unfortunate that this issue has apparently not received much attention since it was noted three years ago…
And so, on to another windowing toolkit… Take 2 will probably be written in Ruby/TK or FXRuby as I understand that both are fairly mature bindings.
In the meantime, below is the code, using rb-skypemac, that I was putting together.
require 'rubygems'
require 'wx'
require 'rb-skypemac'
require 'monitor'
include Wx
include SkypeMac
$BTN_WIDTH = 150
$BTN_HEIGHT = 150
$FONT_SIZE = 14
$IMAGE_DIR = "./images/"
$GREEN_IMG = $IMAGE_DIR + "skype_green2.gif"
$YELLOW_IMG = $IMAGE_DIR + "skype_yellow2.gif"
$RED_IMG = $IMAGE_DIR + "skype_red2.gif"
module SimpleSkypeUtil
def create_bitmap_text_button(labels, parent, status)
bitmap = case status
when "ONLINE": Bitmap.new($GREEN_IMG, BITMAP_TYPE_GIF)
when "DND": Bitmap.new($RED_IMG, BITMAP_TYPE_GIF)
else Bitmap.new($YELLOW_IMG, BITMAP_TYPE_GIF)
end
bitmap.draw do |dc|
dc.set_font Font.new($FONT_SIZE, FONTFAMILY_DEFAULT, FONTSTYLE_NORMAL, FONTWEIGHT_NORMAL)
dc.set_background_mode TRANSPARENT
dc.set_text_foreground BLACK
label_no = 0
extent = dc.get_text_extent(labels[0])
extent_y = extent[1] * labels.size
labels.each do |label|
extent = dc.get_text_extent(label)
text_x = ($BTN_WIDTH - extent[0]) / 2
text_y = ($BTN_HEIGHT - extent_y) / 2 + extent[1] * label_no
dc.draw_text label, text_x, text_y
label_no += 1
end
end
btn = BitmapButton.new(parent, -1, bitmap)
end
end
module SimpleSkype
class HangupDialog < Wx::Dialog
include SimpleSkypeUtil
# TODO: replace destroy_children call below to prevent this dialog from being nuked's unduly
def initialize(parent, id, title, call)
super(parent,
id,
title,
Point.new(parent.get_position.x + parent.get_size.get_width,
parent.get_position.y),
Size.new(150, 150),
DIALOG_EX_METAL|STAY_ON_TOP)
@call = call
set_size Size.new($BTN_WIDTH, $BTN_HEIGHT)
set_sizer(sizer = StdDialogButtonSizer.new)
btn = create_bitmap_text_button("Hang up call".to_a, self, :red)
btn.set_min_size Size.new($BTN_WIDTH, $BTN_HEIGHT)
sizer.add btn
evt_button(btn.get_id) { |e| @call.hangup; self.hide }
end
end
class SkypeApp < App
include SimpleSkypeUtil
include MonitorMixin
attr :frame
def handle_user_click(event, user)
call = Skype.call user
HangupDialog.new(@frame, -1, "Hang up call?", call).show_modal
end
def create_button_per_friend
@friends.map do |f|
labels = []
labels << "#{(f.fullname != "") ? f.fullname : f.handle}"
#labels << "(#{f.onlinestatus})"
btn = create_bitmap_text_button labels, @frame, f.onlinestatus
btn.set_min_size Size.new(150,150)
evt_button(btn.get_id) { |e| handle_user_click(e, f) }
btn
end
end
def redraw_friends_buttons
@frame.destroy_children
@sizer = BoxSizer.new(VERTICAL) if @sizer.nil?
@friends = Skype.online_friends.sort
@frame.set_client_size($BTN_WIDTH, $BTN_HEIGHT * @friends.size)
@friend_btns = create_button_per_friend
@friend_btns.each { |b| @sizer.add(b, 1, GROW|ALL, 2) }
@sizer.layout
@frame.set_sizer(@sizer) if @frame.get_sizer.nil?
@frame.show
end
def on_init
@friends = Skype.online_friends
@frame = Frame.new(nil,
1,
'Simple Skype',
Point.new(0, 80),
Size.new($BTN_WIDTH,$BTN_HEIGHT * @friends.size),
FRAME_EX_METAL)
redraw_friends_buttons
timer = Timer.new @frame, -1
evt_timer(-1) { redraw_friends_buttons }
timer.start 5000
end
end
end
app = SimpleSkype::SkypeApp.new
app.main_loop



0 comments ↓
There are no comments yet...Kick things off by filling out the form below.
Leave a Comment