Centering slots in Shoes

Hi

Recently on Stack Overflow I came across a question about how to center the stack in the application window. After brief search in the Shoes manual I realized that there are ways you can center other elements (e.g. para) within the parent slots but the centering of the slots themselves is not implemented (strangely enough).
Here I present a quick extension of the Flow and Stack classes which allows you to center (both horizontally and/or vertically) the slots. It is done by reopening of the Types module, apparently extending the two classes (thanks Satoshi for the hint).

module Shoes::Types
 def centr
  left=(self.parent.width-self.style[:width])/2
  self.move(left,self.top)
 end

 def middle
  top=(self.parent.height-self.style[:height])/2
  self.move(self.left,top)
 end
end

Below is a simple test application which exemplifies the use of the two new methods and the fact that you can center the slots in the main window and also within another slot

Shoes.app do
 @s=stack :width=>300, :height=>100,  do
  background red
 end
 @s.middle
 @s.append do
  @a=flow :width=>30, :height=>10,  do
   background green
  end
 @a.centr.middle
 end
end

 

The red Stack is vertically centered within the main application window and the green Flow is centered both horizontally and vertically within the red Stack.

The red Stack is vertically centered within the main application window and the green Flow is centered both horizontally and vertically within the red Stack.

 

If you run it in Shoes or Hackety Hack you should see something like that:

Hope you find it useful

MTFBWY

K

AddressBook search app written in MacRuby

In my pursuit of learning MacRuby, I decided to write a small utility application on top of Apple’s Address Book. The idea was to be able to quickly – in just a few key strokes and one or two mouse clicks – access the most common information about the person such as: full name, main phone number, email address and home address and have it copied to the system clipboard.

For that I made my application live in the system bar:

systemBar=NSStatusBar.systemStatusBar
@menu1=systemBar.statusItemWithLength(NSVariableStatusItemLength)
ico=NSImage.imageNamed('ab1').setSize([21,21])
@menu1.setImage(ico)
@menu1.setAction("toggleView:")

Assigning it an icon which when clicked would trigger appearance of a search panel similar to the Spotlight.

Additionally, I wanted to have the search panel appearing in response to the hot key. This can be done by registering the global monitor for the NSKeyDown event, like that:

eventMonitorG = NSEvent.addGlobalMonitorForEventsMatchingMask(
         (NSKeyDownMask),handler:Proc.new do |incomingEvent|
            targetWindowForEvent = incomingEvent.window
            if targetWindowForEvent!=@window
             if incomingEvent.type == NSKeyDown 
              if incomingEvent.keyCode == 53 #Esc
               if incomingEvent.modifierFlags==1310985 #Ctrl=Cmd
                #here comes code showing the search panel etc
                end
               end
              end
             end
           end)

The system contacts records can be accessed using the classes from AddressBook.framework. For my purpose I decided to search only by the full name so I had to extract these info from the Address Book. At the same time I fetched the unique identifier for each contact which later on will be used for getting the detailed information:

tempBook =ABAddressBook.addressBook
@tmpPeople=[]
tempBook.people.each do |p|
tmpPeople<< [p.valueForProperty(KABFirstNameProperty).to_s+" 
     "+p.valueForProperty(KABMiddleNameProperty).to_s+" 
      "+p.valueForProperty(KABLastNameProperty).to_s,
      p.valueForProperty(KABUIDProperty).to_s]

Filtering of the contacts occurs live while typing to a search box using a NSPredicte class and the string value sent by the search box. Here I am filtering by the occurrence of the string:

a=sender.stringValue
predicate=NSPredicate.predicateWithFormat("SELF[0] contains1 \'#{a}\'")
@results=@tmpPeople.filteredArrayUsingPredicate(predicate)


“@results” array is used to feed the data into a table residing in the drawer which opens when the array has at least one element.


To communicate between the app controller object and the table controller object I use the NSNotification center class sending the “@results” object as an “attachment” (line 1). The notification observer is defined in the table controller class (line 2):

NSNotificationCenter.defaultCenter.postNotificationName("viewControllerCNotification",object:@results)
NSNotificationCenter.defaultCenter.addObserver(self,selector:"receiveNotification:", name:"viewControllerCNotification",object:@results)

Finally, when I hover over email, telephone etc and click, the info gets copied to the system clipboard, using this simple snippet:

pasteboard=NSPasteboard.generalPasteboard
pasteboard.clearContents
pasteboard.writeObjects([value.stringValue])

If you want to see how other things were implemented, e.g. setting up the “run at login” – check the complete source code which is deposited at the GitHub.

If you find the information useful consider supporting the author.

MTFBWY

K

Drawing pixels in Shoes

Shoes is a nifty environment to write graphical platform independent programs in Ruby.

It however lacks one simple but sometimes needed possibility of drawing individual pixels. The smallest you can draw is a square 2×2 pixels or a line 2×1 pixel. Given that I found a small half-hack allowing you to draw the single pixels over the uniform background. It is not perfect, as you will see from the code but for many application it can be used. Here it comes:

As we can draw the 2×1 line, we can draw a background colored line over the half of the foreground line ending with a single pixel, like that

def point(x,y,color, bg_color)
 stroke color
 line x,y,x,y+1
 stroke bg_color
 line x,y+1,x+1,y+1

end
Shoes.app do
 background white
 point 40,40,blue,white
end

Obviously, if you wish to draw many pixels next to each other your “erasing lines” with start to mess with the patterns you want to draw.

MTFBWY
K

MacRuby vs Objective-C

After some simple fiddling with MacRuby and Objective-C it was a high time to write something real … simple but real. To make it funnier I decided to write programs both in pure Objective-C and in MacRuby.

As I am still into the Next Generation Sequencing using SOLiD platform, I decided  to write up a simple application using the scripts from my previous post: a conveter from SOLiD color space into nucleotide sequence and vice versa for Mac OSX.

It is very simple in general. You just have two text areas: one is an input and one t is output. The program converts from one type od sequence to another and the type (color space or nucleotide) is selected by the dedicated button.

The code is obviously quite simple, as most elements are wired in Interface Builder. In general, the length of the two programs is comparable, probably in MacRuby a bit shorter but maybe only because I feel more comfortable with Ruby than with Obj-C.

In few places using Ruby was so much easier than writing in Obj-C; the good example would be initialization of the Hash/NSDictionary used in one of the conversion methods. In Ruby it looks like that:

dic={
  "0"=>{"A"=>"A","C"=>"C","G"=>"G","T"=>"T"}, 
  "1"=>{"A"=>"C","C"=>"A","G"=>"T","T"=>"G"},
  "2"=>{"A"=>"G","G"=>"A","T"=>"C","C"=>"T"},
  "3"=>{"A"=>"T","T"=>"A","G"=>"C","C"=>"G"}
  }

Whereas in Obj-C, like that:
As pointed by Objective-C in his comment

*dict1=[NSMutableDictionary dictionaryWithObjectsAndKeys:@"A", @"A", @"C", @"C", @"G", @"G", @"T", @"T", nil];
*dict2=[NSMutableDictionary dictionaryWithObjectsAndKeys:@"A", @"C", @"C", @"A", @"G", @"T", @"T", @"G", nil];
*dict3=[NSMutableDictionary dictionaryWithObjectsAndKeys:@"A", @"G", @"G", @"A", @"C", @"T", @"T", @"C", nil];
*dict4=[NSMutableDictionary dictionaryWithObjectsAndKeys:@"A", @"T", @"T", @"A", @"G", @"C", @"C", @"G", nil];

NSMutableDictionary *dict=[NSMutableDictionary dictionary];
[dict setObject:dict1 forKey:@"0"];
[dict setObject:dict2 forKey:@"1"];
[dict setObject:dict3 forKey:@"2"];
[dict setObject:dict4 forKey:@"3"];

or as in my unintentionally “verbose” version like that:

NSMutableDictionary *dict1=[NSMutableDictionary dictionary];
[dict1 setObject:@"A" forKey:@"A"];
[dict1 setObject:@"C" forKey:@"C"];
[dict1 setObject:@"G" forKey:@"G"];
[dict1 setObject:@"T" forKey:@"T"];

NSMutableDictionary *dict2=[NSMutableDictionary dictionary];
[dict2 setObject:@"A" forKey:@"C"];
[dict2 setObject:@"C" forKey:@"A"];
[dict2 setObject:@"G" forKey:@"T"];
[dict2 setObject:@"T" forKey:@"G"];

NSMutableDictionary *dict3=[NSMutableDictionary dictionary];
[dict3 setObject:@"A" forKey:@"G"];
[dict3 setObject:@"G" forKey:@"A"];
[dict3 setObject:@"T" forKey:@"C"];
[dict3 setObject:@"C" forKey:@"T"];

NSMutableDictionary *dict4=[NSMutableDictionary dictionary];
[dict4 setObject:@"A" forKey:@"T"];
[dict4 setObject:@"T" forKey:@"A"];
[dict4 setObject:@"C" forKey:@"G"];
[dict4 setObject:@"G" forKey:@"C"];

NSMutableDictionary *dict=[NSMutableDictionary dictionary];
[dict setObject:dict1 forKey:@"0"];
[dict setObject:dict2 forKey:@"1"];
[dict setObject:dict3 forKey:@"2"];
[dict setObject:dict4 forKey:@"3"];

I agree that in Obj-C one could most likely code it shorter using predefined Arrays but still it would be Though it is not my point here, Obj-C code is still far from the simplicity of the code in Ruby.

There is also one more thing I like about MacRuby and it is the ability to use libraries written in Objective-C. To demonstrate this I used the library written by Arvin – big thanks – that simulates the effect of widow flipping and which I found at Stack Overflow.

For use in Objective-C version the library was simply included in the source code. For MacRuby program, more hassle was needed: the code had to be compiled as a Dynamic Library; only than it could be used, by simple command:

require 'AnimationWindow'

Simple and cool.

Below is a short screencast of the two versions of the program: top – in MacRuby and bottom – in Objective-C.

The source code for both programs can be downloaded from GitHub:

MTFBWY

K

The next generation sequencing platform sold by the Applied Biosystems – SOLiD – uses a special di-nucleotide encoding system called a color space (details can be found on the poster). The sequence in the simplest form is therefore represented by array of four characters 0, 1, 2, and 3. Each of these characters can correspond to four different transitions from one nucleotide base to another, e.g. 1 can be either CA, or AC, or, GT, or TG. Given that the short sequence like that: 01 can actually represent any of: AAC, CCA, GGT,or TTG. It is clear that to unambiguously convert the color space encoded sequence to its nucleotide form we need to know the first nucleotide in the sequence, thus A01 means AAC.

To convert short sequences one can use the scheme presented on the picture but for longer sequences it becomes quite challenging and it is easy to make a mistake. As the decoding of the following base depends on the identity of the former one, one mistake makes subsequent decoding completely erroneous.

Because of that I wrote two simple scripts in Ruby to do it for me.

First converts color space sequence into nucleotides, and the actual decoding is performed in line 11 using the rules written in DICT hash:

DICT={"0"=>{"A"=>"A","C"=>"C","G"=>"G","T"=>"T"},
      "1"=>{"A"=>"C","C"=>"A","G"=>"T","T"=>"G"},
      "2"=>{"A"=>"G","G"=>"A","T"=>"C","C"=>"T"},
      "3"=>{"A"=>"T","T"=>"A","G"=>"C","C"=>"G"}}

seq_in=ARGV[0][1..-1]
f_base=ARGV[0][0]
seq_out=f_base

seq_in.split(//).each do |ch|
 f_base=DICT[ch][f_base]
 seq_out+=f_base
end

puts "#{ARGV[0]}\n"
puts seq_out

Similarly the encoding into a color space from nucleotide sequence is performed very similarly, in line 11 using a corresponding set of rules.

DICT={"AA"=>"0", "CC"=>"0", "GG"=>"0", "TT"=>"0",
"AC"=>"1", "CA"=>"1", "TG"=>"1", "GT"=>"1",
"AG"=>"2", "GA"=>"2", "TC"=>"2", "CT"=>"2",
"AT"=>"3", "TA"=>"3", "GC"=>"3", "CG"=>"3"}

seq_in=ARGV[0][1..-1]
f_base=ARGV[0][0]
seq_out=f_base

seq_in.split(//).each do |ch|
 seq_out+=DICT[f_base+ch]
 f_base=ch
end

puts "#{ARGV[0]}\n"
puts seq_out

Just one note. this code works fine in Ruby 1.9.2. If you plan to use Ruby 1.8.7 you will have to modify lines 7, e.g. to

f_base=ARGV[0].split(//)[0]

Hope you find it useful

MTFBWY

K

jQuery and CSS web page language switching

While developing my home web-page I decided to add the functionality of language toggling ( in my case between English and Polish). The simplest solution would be to reload the the content of the whole page but I did not find it to be the most elegant.

Today, I am going to describe my solution to the language switching problem using jQuery and CSS. The idea is simple: each text (might also be other type) element in the web-page which will be changed after language toggling is provided in side by side in two languages and assigned a class of either e.g. “show” or “hide”.

<div class="show">SHOW</div>
<div class="hide">POKAZ</div>

In the CSS we definethe two classes as:

.show{
display: inline;
}
.hide{
display: none;
}

We also need a function which will switch the two classes for our elements. For this I at first tried to use jQuery .toggleClass() function but it did not produce the best results for me, so instead I used following function:

function lang_switch(){
	$('.show').addClass('sh').removeClass('show');
	$('.hide').addClass('hs').removeClass('hide');
	$('.sh').addClass('hide').removeClass('sh');
	$('.hs').addClass('show').removeClass('hs');
};

Notice, I am assigning temporary classes to the elements before applying the final class so to not confuse the already manipulated elements with these still to process.

A simple test file can be found here.

MTFBWY

K

For several days I was writing  scripts to display an image gallery over the Google Maps. My idea was to write a Ruby script which would search for all image galleries in a particular directory. Then based on the content of the directory and information in the index file it should produce HTML code which together with JS and JQuery creates GoogleMaps markers at the locations specified in the index file and attaches to the markers the image galleries. Additionally, I decided to have a drawer with the list of the locations/galleries on top of the Google Maps. Final map looks something like on the image on the right. The small black element on the right edge is a flap for the  drawer. You can see the two markers to which the gallerries are attached. Upon clicking a marker, the overlay opens with the corresponding gallery, as shown on the example on the left.

So, generally the task seemed to be easy but I have experience several problems. Firstofall, GoogleMaps has its special way of dealing with the Z-stack and because of that majority of image overlay displaying JS plugins failed miserably to display over the map. I tried to play with CSS and source codes but without any success. The satisfactory effect I obtained after tweaking a bit CSS source of the Fancybox plugin… but let us start from the beginning.

GALLERY SOURCES: I did not put much thought about it so you might find a better way to achieve the same. I dedicated a special folder in my web page where I store all images and named it “galleries”. It contains the subfolders with the particular galleries named “gal1″, “gal2″, etc. Each gallery folder contains jpg (other can be easily implemented) image files and the “index.txt” file with the following information:

  1. description or title of the gallery
  2. coordinates in GoogleMaps format (eg 71.018889, 25.797222) where the marker should be placed
  3. list of image titles

The example file could look something like that:

#title
en - Norkapp / Norway 2006
pl - Norkapp / Norwegia 2006
#title
#position
71.018889, 25.797222
#position
#pict
en - sdsds1
pl - sdsd
#pict
en - dsds2
pl - sdsd
#pict
en - dsds3
pl - dsds

As you noticed, both the title of the gallery and the titles for images are in two languages in case I want to implement the language toggling utility. You can put as many languages and label them as you wish.

HTML: The structure of HTML file is very simple. I basically do two things: first load the GoogleMap on load and attach the drawer which also places markers with galleries on the map by executing the CGI script:

<body onload="initialize()">
<div id="extruderTop" class="{title:'Our travels',url:'/cgi-bin/hell.cgi', data:'lang=en'}"/>
<div id="map_canvas"</div>
</body>

CGI script takes one argument; the code of the language to use for the galleries titles.

CGI – RUBY: I am using Ruby for CGI because I know it better than PHP and nowadays majority of Internet providers allows you to use this great programming language. So basicaly the script parses the information about the galleries. For each gallery, based on the retrieved data, it adds an element to the drawer, which will serve as the shorcut to the particular marker with the gallery. Additionally it injects the JavaScript code to execute the function which will actually place the marker on the map and attaches the fancy box gallery to its click event. I will not describe how the parsing is done by Ruby but the final outcome are three strings; first contains the coordinates of the marker, next contains the title/description of the gallery, and the last is the list of image locations,with its titles. These are incorporated into the HTML code like that:

puts "<script type='text/javascript'>\n"
puts "attachGallery(#{position},'#{description}',#{datas});</script>"
puts "<div class='text' onclick='$map.setZoom(5);$map.panTo(new google.maps.LatLng(#{position}));>"
puts description
puts "</div>"

As you can see, all magic will be done by the “attachGallery()” JavaScrpt function.

JAVASCRIPT: “attachGallery()” function is really simple:

function attachGallery(long,lat,titl,phots){
var pos = new google.maps.LatLng(long,lat);
var mark = new google.maps.Marker({position: pos, map: $map, title: titl});
google.maps.event.addListener(mark, 'click', show(pos,phots,titl));
};

It creates a new marker on the map at the provided position and with a title being the description for the gallery. Also it adds a click event listener which will execute the function “show()” which prepares and displays the actual gallery.

function show(pos,phots){
 return function(){
  $map.panTo(pos);
  photos=[];
  tmp=phots.split("#");
  for(i=0; i<tmp.length; i++){
   a=tmp[i].split(",");
   var t={"href": a[0],"title" : a[1]};
   photos.push(t);
  };
 $.fancybox(photos, {
   'type' : 'image',
   onStart:function(){$menu.toggle(false);},
   onClosed:function(){$menu.toggle(true);},
   'showTitle' : true,
   'titlePosition' : 'over'
  }
  );
}
}

This function parses the string with urls and titles of the images to display and creates an array “photos” of the objects wich will be used by fancybox to make a gallery and subsequenly displays the gallery. In fancybox setup we  disable the drawer when the gallery is displayed.

That would be all.

Just the last information about the requirements; you will need the following JavaScript libraries/pluggins:

  1. JQuery – for all the goddies
  2. mb.Extruder – for drawer implementation – if you wan to disable and enable it at the level of drawer you will need to modify the source code or used the version provided in the attached source code.
  3. Fancybox – for the gallery display – I have modified the CSS file to allow displaying over the GoogleMaps

If you want to see the gallery in action check my webpage (still under construction).

From here you can download full scripts. Of course the files will need to be placed where they belong and the paths should be updated accordingly.

I hope you will have fun. It is still not the final version though it is aleady usable. Grab it and modify it but remeber about the author (e.g. click the add link or support me via paypal:))

MTFBWY

K

Hackety Hack – my new Shoes IDE :)

I have just downloaded the latest official release of Hackety Hack v1.0 for MacOSX.  It is beautiful and to my surprise it nicely runs my old Table and Menu widgets – example below.

Hackety hack running Table example

Hackety hack running Table example

I think I will use it as my Shoes IDE.

Good work.

MTFBWY

K

 Page 1 of 3  1  2  3 »