Wednesday, July 3, 2013
5 good tips for a good Project manager
Sunday, February 20, 2011
Developing mobile apps using ROR
For the native app solution we can use the Rhodes.Rhodes is an open source Ruby-based framework to rapidly build native apps for all major smartphone operating systems (iPhone, Windows Mobile, RIM, Symbian and Android). These are true native device applications (NOT mobile web apps) which work with synchronized local data and take advantage of device capabilities such as GPS, PIM contacts and calendar, camera, native mapping, push, barcode, signature capture, and Bluetooth.
Rhodes is the ONLY framework with: support for Model View Controller (other frameworks force you to put all business logic into the view as JavaScript), synchronized data (the price of entry for enterprise apps), support for ALL devices (Android and iPhone is not “crossplatform”), and a hosted build service (RhoHub – which changes the game for mobile app development entirely). Rhodes has many other major advantages over every other framework and underlying SDK, which can be summarized as modern development goodness for mobile apps.
For the 2nd option, web app disguised as a mobile app, I'd recommend Sencha Touch. Sencha has done an amazing job mimicking the look and feel of native iphone/android apps with their Javascript library. With this solution it would be just like any other web app though it's targeted for android and iphone via it's UI.
Monday, January 17, 2011
JCrop with Paper Clip Plugin
In our application we have a create a user model that is set to use paper clip plugin.
User Model:
class User < ActiveRecord::Base has_attached_file :avatar, :styles => { :small => "100x100#", :large => "500x500>" }, :processors => [:cropper]
after_update :reprocess_avatar, :if => :cropping?
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
def cropping?
!crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
end
#To restore the original image after it is cropped. The size can vary.
def avatar_geometry(style = :original)
@geometry ||= {}
@geometry[style] ||= Paperclip::Geometry.from_file avatar.path(style)
end
# To reprocess the attached file if we’re cropping it.
private
def reprocess_avatar
avatar.reprocess!
end
end
User Controller:
def create
@user = User.new(params[:user])
if @user.save
flash[:notice] = 'User was successfully created.'
if params[:user][:avatar].blank?
redirect_to(@user)
else
render :action => 'cropping'
end
else
render :action => 'new'
end
end
# PUT /users/1
def update
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
flash[:notice] = 'User was successfully updated.'
if params[:user][:avatar].blank?
redirect_to(@user)
else
render :action => 'cropping'
end
else
render :action => "edit"
end
end
Cropping.html file should have the following set
function update_crop(coords) {
var ratio = <%= @user.avatar_geometry(:original).width %> /
<%= @user.avatar_geometry(:large).width %>;
$('#crop_x').val(Math.floor(coords.x * ratio));
$('#crop_y').val(Math.floor(coords.y * ratio));
$('#crop_w').val(Math.floor(coords.w * ratio));
$('#crop_h').val(Math.floor(coords.h * ratio));
}
Avatar:
<%= image_tag @user.avatar.url(:large), :id => "cropbox" %>
<% form_for @user do |f| %>
<%= f.text_field :crop_x, :id => 'crop_x' %>
<%= f.text_field :crop_y, :id => 'crop_y' %>
<%= f.text_field :crop_w, :id => 'crop_w' %>
<%= f.text_field :crop_h, :id => 'crop_h' %>
<%= f.submit "Crop!" %>
<% end %>
<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>
Show.erb file can contain
Name:
<%=h @user.name %>
Avatar:
<%= image_tag @user.avatar.url(:large) %>
<%= image_tag @user.avatar.url(:small) %>
<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>
lib\paperclip_processors should have cropper.rb with the following code
module Paperclip
class Cropper < Thumbnail def transformation_command if crop_command crop_command + super.join(' ').sub(/ -crop \S+/, '').split(' ') # super returns an array like this: ["-resize", "100x", "-crop", "100x100+0+0", "+repage"] else super end end def crop_command target = @attachment.instance if target.cropping? ["-crop", "#{target.crop_w}x#{target.crop_h}+#{target.crop_x}+#{target.crop_y}"] end end end end Important steps to remember:
Move cropper.rb to the folder config\initializers
Remember to add crop_x, crop_y, Crop_w and crop_h to the list of your accessible attributes IF you have such a list:
attr_accessible :avatar, :crop_x, :crop_y, :crop_w, :crop_h
5. Added this line to my gemfile:
gem 'paperclip'
6. bundle install
Added jquery.Jcrop.min.js, jquery-1.4.3.min.js in public\javascripts folder
9. added Jcrop.gif and jquery.Jcrop.css in public\stylesheets folder
10. Added <%= yield(:head) %> in the head section in the application.html.erb file (needed for sample above)
http://asciicasts.com/episodes/182-cropping-images - This post helps you to understand in detail for Rails 2.3.8.
Wednesday, January 12, 2011
Friday, September 17, 2010
Playing with ROR
Monday, May 25, 2009
WPF triggers
Different Types of Triggers
A trigger is a collection of Setter objects that get applied only when a given condition is true. WPF contains three main types of triggers: Trigger (also referred to as a property trigger), DataTrigger, and EventTrigger. It's also possible to respond to multiple simultaneous conditions by using the related MultiTrigger and MultiDataTrigger objects.
Style for a Button:
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.7" />
<Setter Property="TextBlock.FontWeight" Value="Bold" />
Trigger>
Style.Triggers>
Style>
A data trigger allows you to trigger off of a property on your data item by leveraging a Binding. This is most often used in the context of a DataTemplate, but don't overlook the power of data triggers in other scenarios. For example, a data trigger is very handy for triggering off of a property on another object, as shown in this example:
<DataTemplate x:Key="MyItemTemplate">
<Border x:Name="root" BorderThickness="2" CornerRadius="6">
<TextBlock Margin="4" Text="{Binding XPath=@First}" />
Border>
<DataTemplate.Triggers>
<DataTrigger Value="True" Binding="{Binding Path=IsSelected,
RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}">
<Setter TargetName="root" Property="BorderBrush" Value="Pink" />
DataTrigger>
DataTemplate.Triggers>
DataTemplate>
In this case, we are creating a DataTrigger that acts more like a property trigger by using a FindAncestor binding to get to a source object. Namely, we are triggering off of the IsSelected property on an ancestor ListBoxItem. This will allow us to draw a pink border around our template whenever it is selected. Now suppose our data item is a person and we only want a pink border when decorating a female. If the person is male, we instead want a blue border. We could achieve this by adding a second trigger, as shown in the following template:
<DataTemplate x:Key="MyItemTemplate">
<Border x:Name="root" BorderThickness="2" CornerRadius="6">
<TextBlock Margin="4" Text="{Binding XPath=@First}" />
Border>
<DataTemplate.Triggers>
<DataTrigger Value="True" Binding="{Binding Path=IsSelected,
RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}">
<Setter TargetName="root" Property="BorderBrush" Value="Pink" />
DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding XPath=@Gender}" Value="Male" />
<Condition Value="True" Binding="{Binding Path=IsSelected,
RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" />
MultiDataTrigger.Conditions>
<Setter TargetName="root" Property="BorderBrush" Value="Blue" />
MultiDataTrigger>
DataTemplate.Triggers>
DataTemplate>
There is one more type of trigger called an EventTrigger. An event trigger, as the name implies, can be used to start an action in response to an event. More specifically, an event trigger executes in response to a routedevent. Here's a kaxample of a Button that uses an event trigger to begin an opacity animation when the Button is first loaded:
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button Opacity="0" Content="My Button">
<Button.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Name="MyBeginAction">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="0:0:1" BeginTime="0:0:0.25" To="1.0" />
Storyboard>
BeginStoryboard>
EventTrigger>
Button.Triggers>
Button>
Canvas>
In this example, the event trigger is added directly to the Triggers collection of the framework element (the Button), itself. Again, the FrameworkElement.Triggers collection can only contain event triggers. If you wish to use property or data triggers, they must be within the Triggers collection of a style or template.
Note that you cannot trigger off of a standard CLR event because the mechanism for supporting event triggers depends on the WPF event routing engine, which intelligently routes events to only the elements that have registered to receive them.
With a property or data trigger, the condition that causes the trigger to be applied is based on state. As such, the condition will be true for a period of time. As long as the condition evaluates to true, the setters are applied to their target properties. When the condition later becomes false, the setters are no longer applied and the target properties fall back to their untriggered values.
There is no such concept of state with an event trigger. An event is fleeting. The event fires and then it's gone. Since the condition that invokes an event trigger is instantaneous, an EventTrigger does not contain a collection of setters. Rather, it contains actions which execute in response to the event. These actions allow you to control (start, stop, pause, resume, etc) the execution of storyboards. The example above uses a BeginStoryboard action in response to the FrameworkElement.Loaded event.
You may also want to set properties based on the firing of an event. Even though you don't have setters, you can still use an EventTrigger to set property values. You achieve this by leveraging an object animation with a DiscreteObjectKeyFrame.