<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>RuGUI Framework Blog &#187; Vicente Mundim</title>
	<atom:link href="http://blog.rugui.org/author/vicente-mundim/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.rugui.org</link>
	<description>RuGUI is an open-source framework that makes building desktop applications very easy. Like Ruby on Rails, it aims to improve productivity, favoring convention over configuration, DRY and MVC patterns.</description>
	<lastBuildDate>Fri, 25 Sep 2009 16:06:07 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>New blog just for RuGUI!</title>
		<link>http://blog.rugui.org/2009/09/new-blog-just-for-rugui/</link>
		<comments>http://blog.rugui.org/2009/09/new-blog-just-for-rugui/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 19:16:56 +0000</pubDate>
		<dc:creator>Vicente Mundim</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[announcement]]></category>
		<category><![CDATA[RuGUI]]></category>

		<guid isPermaLink="false">http://blog.rugui.org/?p=214</guid>
		<description><![CDATA[
Today, I&#8217;ve setup this new blog for RuGUI. All posts that we&#8217;re in the Intelitiva&#8217;s blog were imported into this new blog.


This blog is the official RuGUI blog from now on. There is still some work to do in the blog, specially its appearence, hope to change it soon.

Cheers  
]]></description>
			<content:encoded><![CDATA[<p>
Today, I&#8217;ve setup this new blog for RuGUI. All posts that we&#8217;re in the <a href="http://blog.intelitiva.com">Intelitiva&#8217;s blog</a> were imported into this new blog.
</p>
<p>
This blog is the official RuGUI blog from now on. There is still some work to do in the blog, specially its appearence, hope to change it soon.
</p>
<p>Cheers <img src='http://blog.rugui.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rugui.org/2009/09/new-blog-just-for-rugui/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RuGUI repository and Issue Tracker changed</title>
		<link>http://blog.rugui.org/2009/08/rugui-repository-and-issue-tracker-changed/</link>
		<comments>http://blog.rugui.org/2009/08/rugui-repository-and-issue-tracker-changed/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 00:42:35 +0000</pubDate>
		<dc:creator>Vicente Mundim</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[announcement]]></category>
		<category><![CDATA[RuGUI]]></category>

		<guid isPermaLink="false">http://blog.intelitiva.com/?p=194</guid>
		<description><![CDATA[RuGUI repository and Issue Tracker moved in GitHub]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve decided to move the RuGUI repository in GitHub to its own account. Also we&#8217;ve decide to use the built-in GitHub Issue Tracker in order to simplify and centralize issue tracking for RuGUI.</p>
<p>Since RuGUI is an open source and free framework we wanted to give it its own space, completely independent of us here at Intelitiva. We think that this change will help RuGUI users and commiters to feel more confortable when contributing to RuGUI.</p>
<p>Cheers</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rugui.org/2009/08/rugui-repository-and-issue-tracker-changed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Be a Developer, not a Programmer!</title>
		<link>http://blog.rugui.org/2009/07/be-a-developer-not-a-programmer/</link>
		<comments>http://blog.rugui.org/2009/07/be-a-developer-not-a-programmer/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 19:57:15 +0000</pubDate>
		<dc:creator>Vicente Mundim</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://blog.intelitiva.com/?p=187</guid>
		<description><![CDATA[In the past days I&#8217;ve been thinking about those two words: Developer and Programmer. Wikipedia says that a Programmer is someone who writes computer software, while a Developer is someone concerned with the developement process, somenone who architects the software, on a higher level.
Well, for me, the difference is more simple. What is a program [...]]]></description>
			<content:encoded><![CDATA[<p>In the past days I&#8217;ve been thinking about those two words: Developer and Programmer. Wikipedia says that a <a href="http://en.wikipedia.org/wiki/Programmer">Programmer</a> is someone who writes computer software, while a <a href="http://en.wikipedia.org/wiki/Software_developer">Developer</a> is someone concerned with the developement process, somenone who architects the software, on a higher level.</p>
<p>Well, for me, the difference is more simple. What is a program anyway? It is a sequence of steps that should be followed to achieve a pre-defined goal, or to solve a specific problem. When you run a program it will always have the same behavior, in other words, it will do the same thing again and again and again. And what about Development? Development is the process of getting an initial idea and elaborate it, evolve it, so that it reaches its goal, in other words, solve the problem.</p>
<p>A <em>programmer</em> is someone who writes <em>programs</em>. A <em>developer</em> is someone who <strong>develops</strong> an <em>idea</em>, or a <em>solution</em>. This is an iterative process. First there is the idea (or solution), then you improve it, and you ask: &#8220;Is it good?&#8221;. The answer: &#8220;No&#8221;. So you improve it again, and repeat the question on and on until you are satisfied.</p>
<p>&#8220;When You&#8217;re A Hammer Everything Looks Like A Nail&#8221;. A very famous saying. But what does it has to do with Developers VS Programmers thing? Well, when all you see are <em>problems</em>, you tend to look (and fix) <em>problems</em>. Likewise, when all you see are <strong>solutions</strong>, you tend to look (and think) about <strong>solutions</strong>.</p>
<p>A developer should always think about the <strong>solution</strong>. The <em>problem</em> is there, he realizes it, he knows that. There is nothing he can do to change the <em>problem</em>. But he can, and will, find a <strong>solution</strong> for that <em>problem</em>. Focusing on finding the <strong>solution</strong>, he will often ask himself: &#8220;Is it a good solution? Can I improve it? Should I spend more time on it?&#8221;. Programmers, on the other hand, are easy to please. If they can solve a problem with 10 lines of bad code, why should they care if there is a solution that solves it using 5 lines of good, clear and simpler code? If they can write a single and huge method, why should they split it? Just because someone may want to use some of that functionality later? Bah&#8230;</p>
<h3>Does it look good? Definitly <strong>NO</strong>!</h3>
<p>Is not that every code you write is bad, but if you, the one person that has written it, do not have the nerve to judge it, who will? Maybe you could refator some method, or change the order in which you check for conditions in an <em>if</em>. Maybe you will just end up liking your code the way it is, and won&#8217;t change it at all. Nevertheless, you need to judge your code. If it is not good for you, then it ain&#8217;t good at all.</p>
<p>One of the greatest things about Ruby is its philosofy. Unlike other languages Ruby doesn&#8217;t oblige you to solve a problem with a single solution. For example, how can you get the size of an array? <code>[].size</code>. But you could also get its length <code>[].length</code>, or count how many items with <code>[].count</code> (for Ruby&gt;1.8.7). For each context there is a solution that may be better than another. There is no single way to do it. There is the way that it is best for you. The one you like the most. And this could be applied to any language, not only Ruby. Ruby only makes this easier by given these options in its core.</p>
<p>The most important thing to learn here is that code is less <strong>written</strong> than it is <strong>read</strong>. You will write your code once, but it will be read many times, by many people. Thus when you write some code you should always put yourself in the place of those who will read it later. If the code is not clear, than you should make it clear. Don&#8217;t just go adding some crazy documentation trying to explain the mess you&#8217;ve just made. Try to improve the code, refactor it, split it into multiple smaller methods, give a better name for the method or variable. You will get a good, clean, easy to read, running code, and, who knows, you may even reuse some of those smaller methods later.</p>
<p>Just think about it, you want to be a programmer, somenone who just repeats tasks, creating code that no one understands, solving bugs that were already solved, copying and pasting code everywhere trying to make it work? Or do you want to make code that will last, not because it is mythical, but because it&#8217;s good? Do you want to take a list of tasks you should do, and just do them, like a machine? Shouldn&#8217;t you discuss it, share your ideas, improve the solution?</p>
<p><strong>Be a developer, not a programmer!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rugui.org/2009/07/be-a-developer-not-a-programmer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Getting your feet wet with RuGUI</title>
		<link>http://blog.rugui.org/2009/04/getting-your-feet-wet-with-rugui/</link>
		<comments>http://blog.rugui.org/2009/04/getting-your-feet-wet-with-rugui/#comments</comments>
		<pubDate>Thu, 16 Apr 2009 21:51:21 +0000</pubDate>
		<dc:creator>Vicente Mundim</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[RuGUI]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.intelitiva.com/?p=46</guid>
		<description><![CDATA[If you have already read this article you may wonder: &#8220;Ok, I can do a Hello World application with some new framework, so now what?&#8221;.
&#8220;Hello World&#8221; applications are not usually very good examples of real world applications, they are just there to get you started. However no one would ever write a tutorial using a [...]]]></description>
			<content:encoded><![CDATA[<p>If you have already read <a href="http://blog.rugui.org/2009/01/hello-rugui/">this</a> article you may wonder: &#8220;Ok, I can do a Hello World application with some new framework, so now what?&#8221;.</p>
<p>&#8220;Hello World&#8221; applications are not usually very good examples of real world applications, they are just there to get you started. However no one would ever write a tutorial using a real (and I mean REAL) world application. What would be the better example to demonstrate the possibilities of a given framework is an endless debate.</p>
<p>For this tutorial I chose to build a simple calculator. Simple because it will not have many of the features other calculators have. Simple because it should be easy to write, and of course, because it should fit this tutorial. However it should also have enough features so that it   could show most of the RuGUI features.</p>
<p>RuGUI has evolved a little bit since I&#8217;ve written the first tutorial, for example, now we could have chosen to write this application using the <a href="http://www.qtsoftware.com/products/">Qt</a> framework. For now we will stay with the Gtk framework, later I will translate this tutorial for Qt users.</p>
<p>The full application source code can be downloaded <a href="http://github.com/vicentemundim/simple_calculator">here</a></p>
<h3>Talking about MVC</h3>
<p>First, let me explain how the <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controllerthing">MVC</a> pattern is used in RuGUI. RuGUI was initially inspired by the <a href="http://apps.sourceforge.net/trac/pygtkmvc/wiki">pygtkmvc</a> framework. Some of the features that come with RuGUI, like the <a href="http://en.wikipedia.org/wiki/Observer_pattern">Observer</a> pattern, implementation were inspired by pygtkmvc.</p>
<p>The idea behind using the observer pattern for model-&gt;controller interactions is great, so why didn&#8217;t we just use that framework? Well, it had some limitations at that time. You could have only one model, one view and one controller. I&#8217;ve seen that this has changed, and now you can have a different design for your controllers/views/models. Still, we were using ruby for our web applications and we wanted to continue to use it for the desktop applications.</p>
<p>RuGUI lets you design your controllers/views/models in any way you want. The principles are maintained, a model can be observed by controllers, and a controller may control any number of views, but also other controllers. The only &#8220;limitation&#8221; is that you may only have one MainController, but well, how could you have more than one?</p>
<h3>Enought of this talk, lets code something!</h3>
<p>First, lets generate the application, go to your projects directory and type:</p>
<pre>  rugui simple_calculator</pre>
<p>If you run the application (<code>rake run</code> or <code>./bin/simple_calculator</code>) you will see the &#8220;Hello World&#8221; application.</p>
<p><img src="http://blog.rugui.org/wp-content/uploads/2009/04/screenshot2.png" alt="Simple Calculator" title="Simple Calculator" width="255" height="199" class="alignleft size-full wp-image-99" /></p>
<p>We will stick with only one view for now, so it will have everything in it. It is pretty simple, a TextEntry above, to display the results. We could have used a Label, but the TextEntry is more powerful, and it is already styled for us. We just set it to not be editable, so that the users can only enter values using the buttons. We called it <code>display</code>; this will be used later to reference it in code.</p>
<p>Below the display, we have the input buttons. The numerical ones were called as <code>num_x_button</code> where <code>x</code> is the numerical value of the button. The operators were called <code>xxx_operation</code> where <code>xxx</code> is one of the available operations (sum, subtraction, division, multiplication). Finally, the backspace, equals, decimal separator, and clear buttons were called <code>backspace_button</code>, <code>equals_button</code>, <code>decimal_button</code>, and <code>clear_button</code> respectively.</p>
<p>A vertical layout and a table layout were used to pack the widgets together.  Notice that we will not set signal handlers in glade.</p>
<p>Ok, the view is ready (at least the glade file), so lets go to the model. What do we need?</p>
<ul>
<li>We need to keep track of which numerical keys were pressed.</li>
<li>The decimal separator button could cause us some trouble&#8230;</li>
<li>We will only be performing simple operations, so that after a second operator is pressed it takes the result of the first operation as its first parameter</li>
</ul>
<ul>
<li>For example: The user presses 4, then +, then 7, then *. In this moment we should have performed the first operation (4 + 7).</li>
</ul>
<ul>
<li>We have a backspace button, which clears the last digit (only digits)</li>
<li>We have the clear button, which clears it all.</li>
</ul>
<p>We could model this as a Calculator model class with these observable properties:</p>
<ul>
<li><strong>numerical_keys</strong>: An array with all the numerical keys and, possible a single decimal separator.</li>
<li><strong>operand</strong>: Saves the last operand after one of the operators are clicked.</li>
<li><strong>operation</strong>: Saves the last operator clicked.</li>
<li><strong>result</strong>: Saves the result of the last operation.</li>
</ul>
<p>We generate the model file:</p>
<pre>  script/generate model Calculator</pre>
<p>The observable properties in the Calculator class should look like this:</p>
<pre class="brush: ruby;">
  observable_property :numerical_keys, :initial_value =&gt; []
  observable_property <img src='http://blog.rugui.org/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> perand
  observable_property <img src='http://blog.rugui.org/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> peration
  observable_property :result
</pre>
<h3>But who is controlling it all?</h3>
<p>Since this is a simple application the MainController itself will be controlling everything, ahem, I mean, almost everything. One of the main problems I usually find in MVC application is the misuse of the models as &#8220;inteligent beings&#8221;. See, if someone was to know how to calculate the result, for example, that would be the model. By using the model we simplify the implementation and also allow it to be tested separately.</p>
<p>Lets take a look at the controller implementation, step by step:</p>
<pre class="brush: ruby;">
  def setup_views
    register_view :main_view
  end

  def setup_models
    register_model :calculator
  end
</pre>
<p>Here we register the MainView and the Calculator model, which we are going to use for this application.</p>
<pre class="brush: ruby;">
  on :backspace_button, 'clicked' do
    self.calculator.backspace
  end

  on :clear_button, 'clicked' do
    self.calculator.clear
  end

  on :equals_button, 'clicked' do
    self.calculator.calculate_result
  end
</pre>
<p>Ahm??? Get it? Here we are actually telling that for any view which has a button named <code>:backspace_button</code> that is <em>clicked</em>, we want to do something. In this case we are calling a method in the model. We could have done it in the older way, by setting a method handler in glade and declaring it here, like so:</p>
<pre class="brush: ruby;">
  def on_backspace_button_clicked(widget)
    self.calculator.backspace
  end

  def on_clear_button_clicked(widget)
    self.calculator.clear
  end

  def on_equals_button_clicked(widget)
    self.calculator.calculate_result
  end
</pre>
<p>However, there are some disadvantages in the latter wat. First you have to declare the method in a glade file and also in your code. Second, the method must contain all arguments needed for the handler, even if you don&#8217;t intend to use it. Finally, this would only work if you have created the widget in a glade file. For all these reasons the latter form is somewhat deprecated, it will still work, but you should prefer the first form.</p>
<pre class="brush: ruby;">
  on :main_window, 'delete-event' do
    quit
  end
</pre>
<p>When the main_window is close we quit the application.</p>
<pre class="brush: ruby;">
  (0..9).each do |numerical_key|
    on &quot;num_#{numerical_key}_button&quot;, 'clicked' do |widget|
      key = widget.name.match(/num_(\d)_button/)[1]
      self.calculator.numerical_keys &lt;&lt; key
    end
  end

  on :decimal_separator_button, 'clicked' do
    self.calculator.numerical_keys &lt;&lt; '.' unless self.calculator.numerical_keys.include?('.')
  end

  %w(sum subtraction multiplication division).each do |operation|
    on &quot;#{operation}_operation_button&quot;, 'clicked' do |widget|
      operation = widget.name.match(/([a-z]*)_operation_button/)[1]
      self.calculator.change_operation_to(operation)
    end
  end
</pre>
<p>Wew!!? What is this? Well, a little bit of meta-programming can do no harm, can it? I could have repeated this for each numerical key, but it just does not make any sense. Surely if I needed some performance I wouldn&#8217;t be doing this, but, hey this is a simple calculator! Let us use the power of Ruby language at our favor!</p>
<pre class="brush: ruby;">
  def property_numerical_keys_changed(model, new_value, old_value)
    self.main_view.display.text = new_value.join
  end

  def property_result_changed(model, new_value, old_value)
    self.main_view.display.text = new_value.to_s
  end
</pre>
<p>Finally we are actually messing with the MainView. But, just two methods? Yes, you are right, there are just two methods that changes the view. One is called every time the numerical_keys property is changed, basically, whenever the user clicks on a key button, but it can also happen when calculating the result. The other is called after the result changes, i.e., after it is calculated.</p>
<h3>Is there any logic in that?</h3>
<p>Almost forgot it&#8230; Yep, here it is (in the Calculator model, of course):</p>
<pre class="brush: ruby;">
  def change_operation_to(operation)
    if has_operand?
      calculate_result
    else
      save_operand
    end

    self.numerical_keys = []
    self.operation = operation
  end

  def has_operand?
    not self.operand.blank?
  end

  def save_operand
    self.operand = Calculator.to_operand(self.numerical_keys)
  end
</pre>
<p>The first method changes the current operation. If we have an operand, the we calculate the result, which will left us with only one operand, then we clear the numerical_keys and change the operation. If we don&#8217;t have an operand yet, we just save it, then clear the numerical_keys and change the operation. The save_operand method calls <code>Calculator.to_operand(numerical_keys_array)</code>, which just joins the array (remember that the input keys are strings, not integers) and transform it to a float.</p>
<pre class="brush: ruby;">
  def backspace
    self.numerical_keys.pop
  end

  def clear
    reset!
  end
</pre>
<p>These two are very simple, the first one just pops the last key from the numerical_keys property (it has no effect if the array is empty). The second calls a very useful (if used with extreme care) method of <code>RuGUI::BaseModel</code>, the <code>reset!</code> method. It will reset all observable properties of the model instance to their reset_value, which are, by default, equals to their initial_value.</p>
<pre class="brush: ruby;">
  def calculate_result
    if self.numerical_keys.empty?
      # we don't have a second operand, so there is nothing to be calculated.
      self.result = self.operand
    elsif self.operand.blank?
      # no operand, nothing to do.
    else
      second_operand = Calculator.to_operand(self.numerical_keys)
      self.numerical_keys = []
      send(&amp;amp;quot;calculate_#{self.operation}_result&amp;amp;quot;, second_operand)
      self.operand = self.result
    end
  end

  def calculate_sum_result(second_operand)
    self.result = self.operand + second_operand
  end

  def calculate_subtraction_result(second_operand)
    self.result = self.operand - second_operand
  end

  def calculate_multiplication_result(second_operand)
    self.result = self.operand * second_operand
  end

  def calculate_division_result(second_operand)
    self.result = self.operand / second_operand
  end
</pre>
<p>Well this is the most complicated one. Here are the scenarios it is covering:</p>
<ul>
<li>When we have no numerical_keys we just set the result equals to the operand. That enables us to let the users click in two operators sequentially to change the current operator.</li>
<li>When there is no operand there is nothing to calculate.</li>
<li>Otherwise we get the second operand, clear the numerical_keys (this will make the visor be cleared), then call the proper calculation method, given the current operation.</li>
</ul>
<p></p>
<h3>That&#8217;s it!</h3>
<p>Try this awesome simple calculator now! We&#8217;ve made it with only a few lines of code (less than 200 for the model, view, controller). It is still missing some usability and, better displaying of operations, not to say that it is very limited, but it served well for this tutorial.</p>
<p>This tutorial was written using another RuGUI application: <a href="http://github.com/vicentemundim/markup-translator/tree/master">Markup Translator</a>. It allows you to write in textile and see the HTML output on-the-fly side by side. It is still a work in progress, but feel free to check it out and explore its code!</p>
<p><a href="http://github.com/vicentemundim/markup-translator/tree/master"><img src="http://blog.intelitiva.com/wp-content/uploads/2009/04/screenshot1-300x218.png" alt="Markup Translator" title="Markup Translator" width="300" height="218" class="alignleft size-medium wp-image-100" /><br />
</a><br />
If you want to contribute for RuGUI, or if you have written an application using RuGUI, please let us know!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rugui.org/2009/04/getting-your-feet-wet-with-rugui/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>OlÃ¡ RuGUI! Desenvolvendo aplicaÃ§Ãµes desktop utilizando Ruby/GTK</title>
		<link>http://blog.rugui.org/2009/02/ola-rugui/</link>
		<comments>http://blog.rugui.org/2009/02/ola-rugui/#comments</comments>
		<pubDate>Tue, 03 Feb 2009 01:18:04 +0000</pubDate>
		<dc:creator>Vicente Mundim</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[RuGUI]]></category>

		<guid isPermaLink="false">http://blog.intelitiva.com/?p=10</guid>
		<description><![CDATA[Este post Ã© a traduÃ§Ã£o do post intitulado Hello RuGUI!

EntÃ£o vocÃª quer comeÃ§ar a brincar com GTK e Ruby mas ainda nÃ£o sabe por onde comeÃ§ar? NÃ£o tenha medo, estamos aqui para ajudÃ¡-lo. Existem muitos exemplos de programas &#8220;OlÃ¡, Mundo!&#8221; com Ruby/GTK. Bem, ambos Ruby e GTK sÃ£o excelentes escolhas para a construÃ§Ã£o de aplicaÃ§Ãµes [...]]]></description>
			<content:encoded><![CDATA[<p>Este post Ã© a traduÃ§Ã£o do post intitulado <a href="http://blog.rugui.org/2009/01/hello-rugui/">Hello RuGUI!</a></p>
<p><a title="RuGUI Framework" href="http://rugui.org"><img src="http://blog.rugui.org/wp-content/uploads/2009/01/logo_rugui.png" alt="RuGUI" /></a></p>
<p>EntÃ£o vocÃª quer comeÃ§ar a brincar com GTK e Ruby mas ainda nÃ£o sabe por onde comeÃ§ar? NÃ£o tenha medo, estamos aqui para ajudÃ¡-lo. Existem muitos exemplos de programas &#8220;OlÃ¡, Mundo!&#8221; com Ruby/GTK. Bem, ambos Ruby e GTK sÃ£o excelentes escolhas para a construÃ§Ã£o de aplicaÃ§Ãµes desktop. Ruby Ã© uma linguagem dinÃ¢mica com caracterÃ­sticas incrÃ­veis como closures e, Ã© claro, uma extensa biblioteca prÃ³pria. GTK, por sua vez, Ã© um framework amplamente utilizado, com muitas widgets Ãºteis alÃ©m de ter uma API Ã³tima para impressÃ£o, exibiÃ§Ã£o de vÃ­deos, reproduÃ§Ã£o de Ã¡udio, etc. Combine esses dois elementos e vocÃª chega ao Ruby/GTK, um Ã³timo framework&#8230; uhmmm&#8230; framework?</p>
<p>Deixe-me perguntar algumas questÃµes para vocÃª. Suponha que vocÃª esteja comeÃ§ando a escrever uma nova aplicaÃ§Ã£o desktop em Ruby/GTK, uma que seja realmente grande, com muitos casos de uso e pequenos detalhes. Como vocÃª desenharia sua estrutura de diretÃ³rios? E se vocÃª quisesse personalizar o estilo de um botÃ£o, ou alterar a cor de fundo de um TextView? E se sua aplicaÃ§Ã£o fosse um tipo de servidor, e vocÃª quisesse exibir uma mensagem toda vez que um usuÃ¡rio se conectasse? E se vocÃª quisesse alterar a mensagem na barra de status, alÃ©m de adicionar um Ã­cone para o cliente numa IconView?</p>
<p>Ã‰ claro que tudo isso poderia ser feito manualmente por vocÃª&#8230; Ou vocÃª poderia utilizar o <a href="http://rugui.org">RuGUI</a>, que lhe oferece:</p>
<ul>
<li>Uma abordagem MVC para aplicaÃ§Ãµes desktop</li>
<li>Uma estrutura de diretÃ³rios, pronta para uso, similar ao que se tem em aplicaÃ§Ãµes <a href="http://rubyonrails.org">Ruby on Rails</a></li>
<li>Uma maneira mais fÃ¡cil de personalizar widgets do que em aplicaÃ§Ãµes Ruby/GTK normais</li>
<li>ActiveSupport &#8211; bem, alguÃ©m poderia dizer que isso Ã© um requerimento/dependÃªncia, mas eu penso nisso mais como uma funcionalidade extra, uma vez que vocÃª acaba tendo uma API ruby muito mais rica e Ãºtil com ActiveSupport <img src='http://blog.rugui.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<p>Vejamos ele em aÃ§Ã£o com um simples &#8220;Hello, World&#8221;:</p>
<h3>Gerando o esqueleto da sua aplicaÃ§Ã£o</h3>
<p>O  <strong>RuGUI</strong> jÃ¡ cria essa aplicaÃ§Ã£o Hello World para nÃ³s. Na verdade este Ã© o ponto de partida de cada aplicaÃ§Ã£o que vocÃª virÃ¡ a fazer com o <strong>RuGUI</strong>. Uma vez instalado com uma gem vÃ¡ para um diretÃ³rio de sua escolha e digite num terminal:</p>
<pre>  rugui helloworld</pre>
<p>Isso irÃ¡ gerar uma aplicaÃ§Ã£o em {SEU_DIRETORIO}/helloworld.  A estrutura de diretÃ³rios serÃ¡ assim:</p>
<p><img src="http://blog.rugui.org/wp-content/uploads/2009/02/pastas_pt.png" alt="Estrutura de DiretÃ³rios de uma AplicaÃ§Ã£o RuGUI" width="585" height="440" class="size-full wp-image-16" /></p>
<p>Para rodar a aplicaÃ§Ã£o, entre no diretÃ³rio helloworld e digite:</p>
<pre>  ./bin/helloworld</pre>
<p>VocÃª poderia ter digitado tambÃ©m:</p>
<pre>  rake run</pre>
<p>Ou, se vocÃª precisar:</p>
<pre>  ruby app/main.rb</pre>
<p>A aplicaÃ§Ã£o deve ser similar a isso:</p>
<p><img src="http://blog.rugui.org/wp-content/uploads/2009/01/helloworld.png" alt="Hello, World!" /></p>
<p>Se vocÃª clicar no botÃ£o, verÃ¡ o texto acima sendo alterado. Como tudo isso funcionou?</p>
<h3>Hello world passo a passo</h3>
<p>Vamos analisar a aplicaÃ§Ã£o passo a passo:</p>
<p>Quando vocÃª roda a aplicaÃ§Ã£o, de qualquer forma (todas as trÃªs formas de iniciar a aplicaÃ§Ã£o acabam por fazer a mesma coisa), o script app/main.rb Ã© chamado. Aqui estÃ¡ o conteÃºdo desse arquivo:</p>
<pre class="brush: ruby;">
#! /usr/bin/ruby

# You can run this application by running this file.
# Do not modify it, unless you know what you are doing.

require File.join(File.dirname(__FILE__), '..', 'config', 'environment')

main_controller = MainController.new
main_controller.run
</pre>
<p>Como vocÃª pode ver, a primeira coisa que fazemos Ã© carregar o arquivo config/environment.rb. Isto irÃ¡ inicializar a aplicaÃ§Ã£o *RuGUI* com o ambiente padrÃ£o &#8212; development. VocÃª poderia ter especificado um ambiente diferente configurando a variÃ¡vel de ambiente RUGUI_ENV. Esse procedimento de inicializaÃ§Ã£o Ã© muito similar ao procedimento de inicializaÃ§Ã£o do Rails, ele foi basicamente copiado e adaptado.</p>
<p>Em seguida nÃ³s instanciamos o <code>MainController</code> e chamamos o mÃ©todo <code>run</code>. Simples, nÃ£o?</p>
<p>Agora sobre o <code>MainController</code>. O quÃª que ele Ã© mesmo? Ao contrÃ¡rio de aplicaÃ§Ãµes web, todas as aplicaÃ§Ãµes desktop possuem um conceito de loop principal. Basicamente, a aplicaÃ§Ã£o Ã© toda configurada antes de ser exibida. Ela entÃ£o entra num loop infinito, que Ã© responsÃ¡vel por exibir as widgets, disparar eventos conforme vÃ£o acontecendo (cliques em botÃµes, apertos de teclas, trÃ¡fego de rede, operaÃ§Ãµes de impressÃ£o, etc). Esses eventos podem alterar a aparÃªncia de widgets, os dados exibidos, ou qualquer outra coisa que vocÃª queira que seja feito.</p>
<p>EntÃ£o o <code>MainController</code> do <strong>RuGUI</strong> Ã© o ponto de partida real da programaÃ§Ã£o de sua aplicaÃ§Ã£o. Algo como a raiz de sua aplicaÃ§Ã£o. Melhor ainda, todos os controles sÃ£o filhos desse <code>MainController</code>, ou filhos de controles que sÃ£o filhos do <code>MainController</code>. Isso estÃ¡ ficando complicado, mas com o tempo vocÃª irÃ¡ entender.</p>
<p>Neste exemplo, nÃ³s temos apenas um controle, e ele Ã© o <code>MainController</code>. NÃ£o criamos outro controle por simplicidade. Aqui estÃ¡ seu cÃ³digo:</p>
<pre class="brush: ruby;">
class MainController &lt; RuGUI::BaseMainController
  # Add your stuff here.

  def setup_views
    register_view :main_view
  end

  def on_main_window_delete_event(widget, event)
    quit
  end
end
</pre>
<p>Ele configura a view principal e adiciona um manipulador para o evento em que a janela principal Ã© fechada, que Ã© usado para fechar a aplicaÃ§Ã£o. Este manipulador de eventos Ã© configurado no arquivo main_view.glade. Todo controle pode observar eventos configurados por widgets em arquivos glade de todas as views registradas nele.</p>
<p>A view principal utiliza um arquivo glade para simplificar a criaÃ§Ã£o e o posicionamento de widgets. NÃ³s poderÃ­amos ter criado as widgets manualmente, mas teriÃ¡mos perdido muitas das funcionalidades como a conexÃ£o automÃ¡tica de manipuladores de eventos, alÃ©m de ter de escrever muito mais cÃ³digo do que foi escrito:</p>
<pre class="brush: ruby;">
class MainView &lt; ApplicationView
  use_glade
  # Add your stuff here.

  def on_hello_button_clicked(widget)
    puts &quot;Hello button clicked.&quot;
    self.message_label.text = &quot;You clicked me!&quot;
  end
end
</pre>
<p>Aqui nÃ³s colocamos um manipulador de evento para o clique do botÃ£o hello_button. Ele imprime uma mensagem no console, e altera o texto da widget message_label. Algumas notas aqui:</p>
<ul>
<li>Todas as widgets criadas em arquivos glade possuem acessores de leitura para elas</li>
<li>Uma vez que estamos utilizando a nomeclatura e a estrutura de diretÃ³rios padrÃ£o nÃ£o tivemos que especificar o arquivo glade para a view, mas poderÃ­amos fazÃª-lo se quisÃ©ssemos. Ele foi meramente deduzido a partir do nome da classe (MainView =&gt; main_view).</li>
<li>A view tambÃ©m funciona como um observador para manipuladores de eventos de suas widgets. O manipulador do evento de clique de botÃ£o para o hello_button poderia ter sido declaro no controle, mas nÃ³s decidimos declarÃ¡-lo aqui para mostrar isso.</li>
</ul>
<p>Isso Ã© basicamente tudo o que hÃ¡!</p>
<h3>Mas, peraÃ­, eu consigo fazer isso em menos linhas!</h3>
<p>Ã‰ claro que sim, aqui estÃ¡:</p>
<pre class="brush: ruby;">
#! /usr/bin/ruby

require 'libglade2'

class MainViewGlade
  include GetText
  attr :glade

  def initialize(path_or_data, root = nil, domain = nil, localedir = nil, flag = GladeXML::FILE)
    bindtextdomain(domain, localedir, nil, &quot;UTF-8&quot;)
    @glade = GladeXML.new(path_or_data, root, domain, localedir, flag) {|handler| method(handler)}
  end

  def on_main_window_delete_event(widget, arg0)
    Gtk.main_quit
  end

  def on_hello_button_clicked(widget)
    puts &quot;Hello button clicked.&quot;
    @glade['message_label'].text = &quot;You clicked me!&quot;
  end
end

# Main program
if __FILE__ == $0
  # Set values as your own application.
  PROG_PATH = &quot;main_view.glade&quot;
  PROG_NAME = &quot;Hello World!&quot;
  MainViewGlade.new(PROG_PATH, nil, PROG_NAME)
  Gtk.main
end
</pre>
<p>No entanto, vocÃª muito provavelmente terÃ¡ uma grande dor de cabeÃ§a quando precisar adicionar mais funcionalidades Ã  aplicaÃ§Ã£o. <strong>RuGUI</strong> procura te ajudar ao deixar vocÃª separar a sua aplicaÃ§Ã£o em camadas bem definidas, cada uma com suas responsabilidades. Dessa forma fica muito mais fÃ¡cil fazer com que sua aplicaÃ§Ã£o evolua sem problemas na sua manutenÃ§Ã£o.</p>
<p>EstÃ¡ ficando animado? <a title="Getting started with RuGUI" href="http://rugui.org/GettingStarted">Comece</a> a usÃ¡-lo agora mesmo!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rugui.org/2009/02/ola-rugui/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Hello RuGUI! Developing desktop applications using Ruby/GTK</title>
		<link>http://blog.rugui.org/2009/01/hello-rugui/</link>
		<comments>http://blog.rugui.org/2009/01/hello-rugui/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 22:50:21 +0000</pubDate>
		<dc:creator>Vicente Mundim</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[RuGUI]]></category>

		<guid isPermaLink="false">http://blog.intelitiva.com/?p=5</guid>
		<description><![CDATA[Introduce basic concepts needed to start out with RuGUI framework.]]></description>
			<content:encoded><![CDATA[<p>You can check out a portuguese version of this post <a href="http://blog.rugui.org/2009/02/ola-rugui/">here</a></p>
<p><a href="http://rugui.org" title="RuGUI Framework"><img src="http://blog.rugui.org/wp-content/uploads/2009/01/logo_rugui.png" alt="RuGUI" /></a></p>
<p>So you want to start out playing with GTK and Ruby but donâ€™t know how to start? Fear not, weâ€™re here to help you. There are a lot of examples of â€œHello, World!â€ applications with Ruby/GTK. Well, both Ruby and GTK are great choices for building desktop applications. The first one is a dynamic language with amazing features like closures, and of course, with an extensive built-in library. The second one is a widely used GUI framework, with lots of helpful widgets and also a great library for printing, displaying videos, playing sounds, etc. Combine these two elements and you have Ruby/GTK, a great frameworkâ€¦ uhmmmâ€¦ framework?</p>
<p>Let me ask you a few questions. Suppose youâ€™re starting a new desktop application in Ruby/GTK, a really big one, with lots of use cases and small details. How would you layout your directory structure? What if you needed to customize the style of a button, or change the background color of a TextView? What if your application is a kind of server, and you want some message displayed every time an user connects to it? What if you wanted to change the status bar message, and also add an icon for the client in an IconView?</p>
<p>Of course you could do this yourselfâ€¦ Or you could use <a href="http://rugui.org" title="RuGUI Framework"><strong>RuGUI</strong></a> which gives you:</p>
<ul>
<li>A MVC approach to desktop applications</li>
<li>A ready to use directory layout similar to what youâ€™d see on a <a href="http://rubyonrails.org/">Ruby on Rails</a> application</li>
<li>An easier way of customizing widgets than in normal Ruby/GTK applications</li>
<li>An implementation of the Observer pattern</li>
<li>ActiveSupportâ€”hey, you could say that this is a requirement/dependency, but I think this is more like a feature since you&#8217;ll end up having a better ruby API with ActiveSupport <img src='http://blog.rugui.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<p>Letâ€™s see it in action with a simple Hello World application.</p>
<h3>Generating your application skeleton</h3>
<p><strong>RuGUI</strong> already creates this Hello World application for us. In fact this is the starting point for every application youâ€™ll ever make with <strong>RuGUI</strong>. Once it is installed as a gem go to a directory of your choice and type in a terminal:</p>
<pre>rugui helloworld</pre>
<p>This will generate an application in {YOUR_DIRECTORY}/helloworld. The directory structure will be like this:</p>
<p><img src="http://blog.rugui.org/wp-content/uploads/2009/02/pastas_en.png" alt="pastas_en" width="570" height="440" class="alignleft size-full wp-image-18" /></p>
<p>To run the application, enter the helloworld directory and type:</p>
<pre>./bin/helloworld</pre>
<p>You could also have typed:</p>
<pre>rake run</pre>
<p>Or even, if you must:</p>
<pre>ruby app/main.rb</pre>
<p>The application should look like this:</p>
<p><img src="http://blog.rugui.org/wp-content/uploads/2009/01/helloworld.png" alt="Hello World Application" /></p>
<p>If you click in the button you should see the top label changing. How did this all worked?</p>
<h3>Hello World step by step</h3>
<p>Letâ€™s analyse the application step by step:</p>
<p>When you run the application, in any way (all three ways of starting the application end up doing the same thing), the app/main.rb script gets called. Here are the content of that file:</p>
<pre class="brush: ruby;">
#! /usr/bin/ruby#

# You can run this application by running this file.
# Do not modify it, unless you know what you are doing.

require File.join(File.dirname(__FILE__), '..', 'config', 'environment')

main_controller = MainController.new
main_controller.run
</pre>
<p>As you can see, the first thing we do is to load the config/environment.rb file. This will initialize the <strong>RuGUI</strong> application with the default environmentâ€”development. You couldâ€™ve specified a different environment by setting the RUGUI_ENV environment variable. This initialization process is very similar to the Rails initialization process, it was mainly copied and adapted from it.</p>
<p>Next we instantiate the <code>MainController</code> and call its method <code>run</code>. Simple isnâ€™t?</p>
<p>Now to the MainController. What is it again? Unlike web applications, all desktop applications have a concept of a main loop. Basically, the application is set up before it is actually displayed. It then enters an infinite loop, which is responsible for displaying widgets and firing events as they happen (button clicks, keys pressed, network data, printing operations, etc). These events may alter the widgets visual, change data, or any other thing you might want them to do.</p>
<p>So <strong>RuGUI</strong>â€™s MainController is the actual programming starting point of your application. Something like the root of your application. Better yet, all other controllers are children of this MainController, or children of controllers which are themselves children of this MainController. This is getting a little complicated, but in time you will get it.</p>
<p>In this example we only have one controller, and it is the MainController. We didnâ€™t create another controller for simplicity. Here is its code:</p>
<pre class="brush: ruby;">
class MainController &lt; RuGUI::BaseMainController
  # Add your stuff here.

Â  def setup_views
Â    register_view :main_view
Â  end

  def on_main_window_delete_event(widget, event)
Â    quit
Â  end
end
</pre>
<p>It set up the main view and add a handler for the main window delete event, which is used to quit the application. This event handler is configured in the main_view.glade file. Every controller can observe events configured for widgets in glade files of all views registered for it.</p>
<p>The main view uses glade file to simplify the creation an positioning of widgets. We couldâ€™ve created the widgets by hand, but we wouldâ€™ve lost many features like the automatic connection of event handlers, and we would have to write a lot more code than we did:</p>
<pre class="brush: ruby;">
class MainView &lt; ApplicationView
Â  use_glade
  # Add your stuff here.

  def on_hello_button_clicked(widget)
Â    puts &quot;Hello button clicked.&quot;
Â    self.message_label.text = &quot;You clicked me!&quot;
Â  end
end
</pre>
<p>Here weâ€™ve put an event handler for the clicked event of the hello_button widget. It prints a message in the console and change the text of the message_label widget. A few notes here:</p>
<ul>
<li>All named widgets created in glade files have read accessors for them.</li>
<li>Since we are using default naming and directory conventions we didnâ€™t need to specify the builder file for the view, but we could have done it if we wanted. It was merely deducted from the class name (MainView =&gt; main_view)</li>
<li>The view itself is also an observer for event handlers of its widgets. The clicked event handler for the hello_button could have been declared in the controller, but weâ€™ve decided to declare it here to show this.</li>
</ul>
<p>This is basically all there is to it!</p>
<h3>But hey, I can do this with fewer lines!</h3>
<p>Of course you can, here it is:</p>
<pre class="brush: ruby;">
#! /usr/bin/ruby

require 'libglade2'

class MainViewGlade
  include GetText
  attr :glade

  def initialize(path_or_data, root = nil, domain = nil, localedir = nil, flag = GladeXML::FILE)
Â    bindtextdomain(domain, localedir, nil, &quot;UTF-8&quot;)
Â    @glade = GladeXML.new(path_or_data, root, domain, localedir, flag) {|handler| method(handler)}
Â  end

  def on_main_window_delete_event(widget, arg0)
Â    Gtk.main_quit
Â  end

  def on_hello_button_clicked(widget)
Â    puts &quot;Hello button clicked.&quot;
Â    @glade['message_label'].text = &quot;You clicked me!&quot;
Â  end
end

# Main program
if __FILE__ == $0
Â  # Set values as your own application.
Â  PROG_PATH = &quot;main_view.glade&quot;
Â  PROG_NAME = &quot;Hello World!&quot;
Â  MainViewGlade.new(PROG_PATH, nil, PROG_NAME)
Â  Gtk.main
end
</pre>
<p>But then, you will surely get a big headache when you need to add more functionality to the application. <strong>RuGUI</strong> tries to help you by letting you separate your application in well defined layers, each with his own responsabilities. This way its easier to make your application evolve without having maintainence problems.</p>
<p>Getting excited? <a href="http://rugui.org/GettingStarted" title="Getting started with RuGUI">Try</a> it out now!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rugui.org/2009/01/hello-rugui/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
