Wednesday 6 February 2013

Return colored Sidebar icons to Mac OS X Lion

Both Mac OX X Lion and Mountain Lion replaced traditional colored icons with gray ones which I didn't like at all. I was just looking at older Snow Leopard and the Finder looks way better there.



I did a little digging and came up with two solutions:


I tried both, worked like a charm :)


Tuesday 25 December 2012

Rails helpers you should be familiar with

AssetTagHelper

- helps you link html page with various assets as javascripts, stylsheets, images...
- useful if you have assets saved on different servers

javascript_include_tag(*sources)

- creates a script tag for each of the provided sources
- tarts from public/javascripts
- uses javascript_path to calculate the path to the javascript file

stylesheet_link_tag(*sources)

- creates a stylesheet link tag for each of the provided sources
- starts from public/stylesheets
- stylesheet_path caluculates locat

image_tag(source, options = {})

- creates a image tag for the provided image location
- image_path caluculates location
- aditional HTML params(align...) can be passed by using options hash

CaptureHelper

- very useful for reusing page parts at different locations by using yield

content_for(name, &block)
- saves the content of the block and provides it for later usage
- useful for action menus or similar components used at different
places but with similar functions

content_for?(name)

- checks weather we'll get any context by using content_for 

DateHelper

- useful for creating select tags for different date combos(full date, only year, time ...)
by using methods like select_date, select_time ...
- includes distance calculation methods like distance_of_time_in_words:
  distance_of_time_in_words(Time.now, Time.now + 5.minute) => "5 minutes" 

FormHelper

- helps with craeating forms closely related to Active Record models linked with a view

form_for(record, options = {}, &proc)

- creates a form and a scope around a specific model object that is used as a source for field data.
- accepts params :url (location where form is submitted to), :html (standard attributes) and :builder (custom form builder e.g. Formtastic)
- uses automated resource identification to configure submit location
- default protection from CSRF attacks
- support for multiple objects update by using square bracket notation => form_for "user[]" do ...

fields_for(record_name, record_object = nil, options = {}, &block)

- creates a scope arround a specific model object without creating tags
form_for @user do |f|
.....
fields_for @user.settings do |s| => params[:user][:settings]

field builders

check_box, email_field, file_field, hidden_field, label, number_field, password_field, radio_button, range_field, search_field, submit, telephone_field, text_area and text_field 

FormTagHelper

- same results as FormHelper but without a link to Active Model instance

NumberHelper

- helps with formatting numbers understandable to user

number_to_currency(number, options = {})

- number_to_currency(12345.60) => $ 12,345.60

number_to_human_size(number, options = {})

- number_to_human_size(1234) => 1.2 KB

 

TagHelper

content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block) 

- programmatically creates a HTML block by using provided tag name and content
- you can also pass a block to create more complex content

tag(name, options = nil, open = false, escape = true)  

-creates tag programmatically

 

TextHelper


pluralize - attempts to pluralize singular world

 

UrlHelper

- methods for generating links

button_to(name, options = {}, html_options = {})

- creates a form submit button directed at the URL from options parameter
- used for all resource modifier actions to prevent unwanted changes

link_to(*args, &block)

- creates a link for the given name and options
- options are processed by url_for method which returns URL for the provided options

Tuesday 18 December 2012

Rails attribute serialization

Switching to Postgres after working for over two years on Hbase is quite a change. The ability to use ActiveRecord feels like getting a nuke. Searches, orders, associations, you name it. But on the other hand, one of the things that felt missing was serialization of which I got so accustomed. It just felt wrong to create separate table for users settings. Why not just store it in the User table?!

Well, Active Record has an option for that. Attributes can be marked as serializable and stored in desired format in the database. Default format is YAML, but you can pass Array, Hash or Class of your own. I'll use Hash:
# model
class User < ActiveRecord::Base
  serialize :settings, Hash
end

# controller
def create
  @user = User.new(params[:user])
  ......
end
Unless a value has already been set for the settings attribute, this won't work since its not initialized.
We can fix that with after_initialize callback:
# initialization callback
def after_initialize
  self.settings ||= {} 
end
Another thing we have to do is to make the form add settings parameter around the items we want to set. We are creating a new object with mass assignment so we need to tell the new method that these attributes are part of the settings hash not of the User model. For this this purpose fields_for helper comes in handy:
# form view
<%= f.fields_for :settings do |setting| %>
  Send newsletter <%= setting.check_box :send_newsletter %>
<% end %>
When we save the user and look in the database we should see serialized settings parameter saved as settings: {"send_newsletter"=>"1"} .
I think this is quite useful for avoiding creating all new table,  joins and so on....

Wednesday 21 November 2012

Pinterest styled list for Android

Pinterest is more and more popular and many apps use its "masonry" pattern. I used the same pattern in my last project and must say it wasn't as easy job as it looked at first. Here's what I'd been doing...

At first logical solution was to use vertical LinearLayouts inside a ScrollView - easy and simple.
All I had to add is code which adds elements proportionately in each LinearLayout.
<ScrollView>
<LinearLayout
   orientation="horizontal">

   <LinearLayout
     android:layout_weight="0.5"
     orientation="vertical">

   <LinearLayout
     android:layout_weight="0.5"
     orientation="vertical">

</LinearLayout>
</ScrollView>
This worked fine at the beginning but when I added more than 100 items, as expected, app started to crash. Well if you think about it it was obvious, with this approach we don't use recycling so layout constantly had 100 items filled with layouts, pictures, formatted text..

Second solution I thought of was two synchronized ListViews. They have internal caching so all I had to do is synchronize them.
<LinearLayout 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    android:paddingLeft="10dp"
    android:paddingRight="10dp">

    <ListView
        android:id="@+id/list_view_left"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:paddingRight="5dp"
        android:scrollbars="none" >
    </ListView>

    <ListView
        android:id="@+id/list_view_right"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:paddingLeft="5dp"
        android:scrollbars="none" >
    </ListView>

</LinearLayout> 
My first attempt was to add OnTouchListener which will pass the touch event to the opposite list and OnScrollListener which will update first opposite child.
listOne.setOnTouchListener(new OnTouchListener() {
    @Override
       public boolean onTouch(View arg0, MotionEvent arg1) {
       listTwo.dispatchTouchEvent(arg1);
       return false;
    }
});
listOne.setOnScrollListener(new OnScrollListener() {
   @Override
   public void onScrollStateChanged(AbsListView arg0, int arg1) {
   }
   @Override
   public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {
          if (l1.getChildAt(0) != null) {
              Rect r = new Rect();
              l1.getChildVisibleRect(l1.getChildAt(0), r, null);
              l2.setSelectionFromTop(l1.getFirstVisiblePosition(), r.top);
          }
    }
});  
Well this seemed as good solution. It was working with single list, scrolling was smooth so adding the same code to the opposite list should work fine but unfortunately it didn't. They ware both synced on first visible child so when one would disappear the other would automatically be positioned to match the new one. This made scrolling feel quite unnatural so other solution had to be found.

It occurred to me that I can just calculate distances from top of both elements, subtract one from another and add offset of the current element. Hmmm, well let's be more precise it took me a while get to this calculation but if you draw an example yourself, you'll see its just logical.
Source can be found on Github  
This solution works fine. I have few bugs to fix, simplify the code - make it more simple to use and that should be it. 
Still it bothers me if this can be implemented by using BaseAdapter and AdapterView. I'll  have an option to use adapters caching and what remains is child positioning. Well, I'll give it a try as soon as I find spare time...

Friday 6 July 2012

List of Android Adapters

Month ago I first saw ResourceCursorAdapter being used in Android development.
That gave me enough curiosity to summarize them all in a single place.


There are several types which differ by data source and manipulation complexity available to the user. Lets start...

BaseAdapter
Simple adapter implementation used for ListView. You provide data by overriding required methods that provide elements for the list. Mostly used for simple list implementations.

SimpleAdapter 
Very useful adapter that allows us to map data to elements in the layout file. You provide a grid (two same sized arrays) which tells which element goes into which place and map that contains all the data needed for this grid to know what to put where.

ArrayAdapter
For me less convenient than the SimpleAdapter since default behavior is to map String array elements to single text field. You can override it and provide an array of complex object which have data to populate more complex rows.

SimpleCursorAdapter
An easy adapter to map columns from a cursor to elements defined  in the layout file. You can specify which columns you want, which views you want to display the columns, and the layout file that defines the appearance of these views.


CursorAdapter
More sofisitcated implementation of the SimpleCursorAdapter which is abstract so its up to you
to create views with cursor providing you the data from database.

ResourceCursorAdapter
Very similar to CursorAdapter. Doesn't have a newView method which makes it more appropriate
for not so complex views. 

SpinnerAdapter
Haven't used this one that much but from what I've seen enables you to define two views, one with data and the second dropdown with choices.

SimpleCursorTreeAdapter
The following two are my most favorite. They allow us to define list elements together with the groups they belong in. Very convenient for situations where you need list with grouped data. You provide both child and group views with appropriate data binding

CursorTreeAdapter
Same as previous but with more liberty and requirements. Better for complex lists.

HeaderViewListAdapter
ListAdapter used when a ListView has header views. This ListAdapter wraps another one and also keeps track of the header views and their associated data objects.

WrapperListAdapter
Haven't seen this one before. Haven't seen any examples but it seems it wraps another list adapter. Strange...

Well that's all I thing....
Now I have them all in single place so I don't have to look around. Sweet :)


Friday 29 June 2012

Installing Jelly Bean on Galaxy Nexus

As you know Google unveiled Android 4.1 Jelly Bean which looks amazing. Official ROM was leaked to the public and is now available for download. If you have a rooted Galaxy Nexus and if you want to play around with the latest Android (on your own responsibility) follow the instructions bellow. 



First of all, you need a ClockworkMod recovery that you can install the usual way, but also through the ROM manager. The procedure will delete personal information, but not the contents of internal memory.

  1. Download Jelly Bean ROM
  2. Move it to the phone's internal memory.
  3. Turn off your phone.
  4. Start the phone in recovery mode.
  5. Once the menu appears, enter your organization and recovery "install zip from SD card"
  6. Select Wipe & factory reset.
  7. Flash the ROM.
  8. Select Reboot System.

And there you have it ... Jelly Bean on Galaxy Nexus

Friday 18 May 2012

Using RVM with different versions of Rails on Mac OSX

I had to use both jRuby and Ruby with different versions of Rails on the same machine which turned out to be quite a frustration. I've heard about RVM which separates Ruby environments together with their gems from one another. I decided to give it a shot...
RVM installation (stable version)
  1. first lets install the RVM
    curl -L get.rvm.io | bash -s stable 
  2. after installation we'll have to reload the console and run:
    source ~/.rvm/scripts/rvm
  3. test if everything was OK
    type rvm | head -n 1 
    to get the message rvm is a function
Ruby installation 

I will be using jRuby 1.6.5 and Ruby 1.9.3 so we need to install those two:
rvm install  1.6.5
rvm install  1.9.3 
After installations finish, run rvm list to get the list of installed rubies.
I will use jRuby and set it as default as I use it most of the time:
rvm use 1.6.5 --default

Rails installation

First we'll need Gemsets. They can be regarded as folders with separate ruby setups, gems and irb, all separate and self-contained - from the system, and from each other.
Lets create one for the Rails we require 2.3.8
rvm gemset create rails238
rvm use 1.6.5@rails238

To install rails and remaining gems we can use gem install but since I use geminstaller we can just run this gem and it does the job for us.
gem install geminstaller
geminstaller

Before we can start anything we have to set path for our new jRuby in .profile and refresh it
with source ~/.profile.
At the end we can override rvmrc to load this gemset automatically:
rvm --rvmrc --create 1.6.5@rails238

For Rails 3.2, which I will use with Ruby,  the gemset stuff is same as before except I'll use bundle install.

We'll these are my notes for RVM installation. Off to checkout Pry, heard it's way better than IRB....