mirror of
https://github.com/zhigang1992/RubyMotion.git
synced 2026-04-09 22:44:31 +08:00
add new sample, trollify
This commit is contained in:
2
sample/trollify/README
Normal file
2
sample/trollify/README
Normal file
@@ -0,0 +1,2 @@
|
||||
This example was contributed by Johannes Fahrenkrug, http://springenwerk.com
|
||||
The app/uiimage_extension.rb file is derived from code by Hardy Macia, Catamount Software.
|
||||
9
sample/trollify/Rakefile
Normal file
9
sample/trollify/Rakefile
Normal file
@@ -0,0 +1,9 @@
|
||||
$:.unshift("/Users/lrz/src/rubixir/lib")
|
||||
require 'motion/project'
|
||||
|
||||
Motion::Project::App.setup do |app|
|
||||
# Use `rake config' to see complete project settings.
|
||||
app.name = 'trollify'
|
||||
app.frameworks += ['QuartzCore', 'AssetsLibrary', 'MobileCoreServices']
|
||||
app.icons = ['icon.png', 'icon@2x.png']
|
||||
end
|
||||
9
sample/trollify/app/app_delegate.rb
Normal file
9
sample/trollify/app/app_delegate.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class AppDelegate
|
||||
def application(application, didFinishLaunchingWithOptions:launchOptions)
|
||||
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
|
||||
@window.rootViewController = UINavigationController.alloc.initWithRootViewController(ImageCompositionController.alloc.init)
|
||||
@window.rootViewController.wantsFullScreenLayout = true
|
||||
@window.makeKeyAndVisible
|
||||
return true
|
||||
end
|
||||
end
|
||||
193
sample/trollify/app/image_composition_controller.rb
Normal file
193
sample/trollify/app/image_composition_controller.rb
Normal file
@@ -0,0 +1,193 @@
|
||||
class ImageCompositionController < UIViewController
|
||||
def loadView
|
||||
self.view = UIImageView.alloc.init
|
||||
view.contentMode = UIViewContentModeScaleAspectFill
|
||||
view.userInteractionEnabled = true
|
||||
|
||||
view.image = UIImage.imageNamed("ballmer.jpg")
|
||||
view.addSubview(troll_image_view)
|
||||
|
||||
rotationGesture = UIRotationGestureRecognizer.alloc.initWithTarget(self, action: 'rotate_image:')
|
||||
@troll_image_view.addGestureRecognizer(rotationGesture)
|
||||
|
||||
panGesture = UIPanGestureRecognizer.alloc.initWithTarget(self, action: 'pan_image:')
|
||||
panGesture.maximumNumberOfTouches = 2
|
||||
panGesture.delegate = self
|
||||
@troll_image_view.addGestureRecognizer(panGesture)
|
||||
|
||||
pinchGesture = UIPinchGestureRecognizer.alloc.initWithTarget(self, action:'scale_image:')
|
||||
pinchGesture.delegate = self
|
||||
@troll_image_view.addGestureRecognizer(pinchGesture)
|
||||
|
||||
navigationItem.leftBarButtonItem = UIBarButtonItem.alloc.initWithTitle("Pick", style:UIBarButtonItemStylePlain, target:self, action:'show_source_sheet')
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem.alloc.initWithTitle("Save", style:UIBarButtonItemStylePlain, target:self, action:'save_image')
|
||||
end
|
||||
|
||||
def viewWillAppear(animated)
|
||||
navigationController.setNavigationBarHidden(false, animated:true)
|
||||
troll_image_view.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds))
|
||||
end
|
||||
|
||||
def troll_image_view
|
||||
@troll_image_view ||= begin
|
||||
image = UIImageView.alloc.init
|
||||
image.image = UIImage.imageNamed("trollface.png")
|
||||
image.frame = CGRectMake(0, 0, image.image.size.width, image.image.size.height)
|
||||
image.userInteractionEnabled = true
|
||||
|
||||
# Set initial scale of the trollface to a quarter.
|
||||
image.transform = CGAffineTransformMakeScale(0.25, 0.25)
|
||||
image
|
||||
end
|
||||
end
|
||||
|
||||
# Scale and rotation transforms are applied relative to the layer's anchor point.
|
||||
# This method moves a gesture recognizer's view's anchor point between the user's fingers.
|
||||
def adjust_anchor_point_for_gesture_recognizer(gestureRecognizer)
|
||||
if gestureRecognizer.state == UIGestureRecognizerStateBegan
|
||||
locationInView = gestureRecognizer.locationInView(troll_image_view)
|
||||
locationInSuperview = gestureRecognizer.locationInView(troll_image_view.superview)
|
||||
|
||||
troll_image_view.layer.anchorPoint = CGPointMake(locationInView.x / troll_image_view.bounds.size.width, locationInView.y / troll_image_view.bounds.size.height)
|
||||
troll_image_view.center = locationInSuperview
|
||||
end
|
||||
end
|
||||
|
||||
def rotate_image(gestureRecognizer)
|
||||
adjust_anchor_point_for_gesture_recognizer(gestureRecognizer)
|
||||
if gestureRecognizer.state == UIGestureRecognizerStateBegan || gestureRecognizer.state == UIGestureRecognizerStateChanged
|
||||
gestureRecognizer.view.transform = CGAffineTransformRotate(gestureRecognizer.view.transform, gestureRecognizer.rotation)
|
||||
gestureRecognizer.rotation = 0
|
||||
end
|
||||
end
|
||||
|
||||
def pan_image(gestureRecognizer)
|
||||
adjust_anchor_point_for_gesture_recognizer(gestureRecognizer)
|
||||
if gestureRecognizer.state == UIGestureRecognizerStateBegan || gestureRecognizer.state == UIGestureRecognizerStateChanged
|
||||
translation = gestureRecognizer.translationInView(troll_image_view.superview)
|
||||
troll_image_view.center = CGPointMake(troll_image_view.center.x + translation.x, troll_image_view.center.y + translation.y)
|
||||
gestureRecognizer.setTranslation(CGPointZero, inView:troll_image_view.superview)
|
||||
end
|
||||
end
|
||||
|
||||
def scale_image(gestureRecognizer)
|
||||
adjust_anchor_point_for_gesture_recognizer(gestureRecognizer)
|
||||
if gestureRecognizer.state == UIGestureRecognizerStateBegan || gestureRecognizer.state == UIGestureRecognizerStateChanged
|
||||
gestureRecognizer.view.transform = CGAffineTransformScale(gestureRecognizer.view.transform, gestureRecognizer.scale, gestureRecognizer.scale);
|
||||
gestureRecognizer.scale = 1
|
||||
end
|
||||
end
|
||||
|
||||
def gestureRecognizer(gestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer:otherGestureRecognizer)
|
||||
true
|
||||
end
|
||||
|
||||
def show_source_sheet
|
||||
popupQuery = UIActionSheet.alloc.initWithTitle("", delegate:self, cancelButtonTitle:'Cancel', destructiveButtonTitle:nil, otherButtonTitles:"Choose Existing", "Take Picture", nil)
|
||||
popupQuery.delegate = self
|
||||
popupQuery.actionSheetStyle = UIActionSheetStyleBlackOpaque
|
||||
popupQuery.showInView(view)
|
||||
end
|
||||
|
||||
def actionSheet(actionSheet, clickedButtonAtIndex:buttonIndex)
|
||||
case buttonIndex
|
||||
when 0
|
||||
pick_image
|
||||
when 1
|
||||
take_image
|
||||
when 2
|
||||
# cancelled
|
||||
end
|
||||
end
|
||||
|
||||
def pick_image
|
||||
pick_image_with_source(UIImagePickerControllerSourceTypePhotoLibrary)
|
||||
end
|
||||
|
||||
def take_image
|
||||
pick_image_with_source(UIImagePickerControllerSourceTypeCamera)
|
||||
end
|
||||
|
||||
def pick_image_with_source(source_type)
|
||||
# Create and show the image picker.
|
||||
imagePicker = UIImagePickerController.alloc.init
|
||||
imagePicker.sourceType = source_type
|
||||
imagePicker.mediaTypes = [KUTTypeImage]
|
||||
imagePicker.delegate = self
|
||||
imagePicker.allowsImageEditing = false
|
||||
presentModalViewController(imagePicker, animated:true)
|
||||
end
|
||||
|
||||
# UIImagePickerControllerDelegate methods
|
||||
|
||||
def imagePickerControllerDidCancel(picker)
|
||||
dismissModalViewControllerAnimated(true)
|
||||
end
|
||||
|
||||
def imagePickerController(picker, didFinishPickingMediaWithInfo:info)
|
||||
mediaType = info[UIImagePickerControllerMediaType]
|
||||
if mediaType == KUTTypeImage
|
||||
editedImage = info[UIImagePickerControllerEditedImage]
|
||||
originalImage = info[UIImagePickerControllerOriginalImage]
|
||||
view.image = editedImage || originalImage
|
||||
end
|
||||
dismissModalViewControllerAnimated(true)
|
||||
end
|
||||
|
||||
def save_image
|
||||
image = view.image
|
||||
|
||||
troll_image_transform = @troll_image_view.transform;
|
||||
trollfaceRotation = Math.atan2(troll_image_transform.b, troll_image_transform.a);
|
||||
trollfaceScaleX = Math.sqrt(troll_image_transform.a**2 + troll_image_transform.c**2);
|
||||
trollfaceScaleY = Math.sqrt(troll_image_transform.b**2 + troll_image_transform.d**2);
|
||||
|
||||
# We are displaying the image in AspectFill mode. This will give us the scale.
|
||||
scale = [image.size.width/view.frame.size.width, image.size.height/view.frame.size.height].min
|
||||
|
||||
targetWidth = image.size.width;
|
||||
targetHeight = image.size.height;
|
||||
|
||||
# Image Rect and Image Context in the size of the image.
|
||||
imageRect = CGRectMake(0, 0, image.size.width, image.size.height);
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(CGSizeMake(targetWidth, targetHeight), true, UIScreen.mainScreen.scale);
|
||||
c = UIGraphicsGetCurrentContext();
|
||||
image.drawInRect(imageRect)
|
||||
|
||||
# Potential landscape rotation.
|
||||
CGContextSaveGState(c)
|
||||
|
||||
# Get the (possibly rotated) image.
|
||||
trollface_image = @troll_image_view.image
|
||||
if trollfaceRotation != 0
|
||||
trollface_image = @troll_image_view.image.imageRotatedByRadians(trollfaceRotation)
|
||||
end
|
||||
|
||||
# Move the context down and left (or either or) to match where the trollface view was on the screen
|
||||
CGContextTranslateCTM(c, (image.size.width-view.frame.size.width*scale)/2, (image.size.height-view.frame.size.height*scale)/2)
|
||||
# Scale the coordinate context,
|
||||
CGContextScaleCTM(c, scale, scale)
|
||||
|
||||
# Draw the trollface image, correctly scaled.
|
||||
trollface_image.drawInRect(CGRectMake(@troll_image_view.frame.origin.x, @troll_image_view.frame.origin.y, trollface_image.size.width * trollfaceScaleX, trollface_image.size.height * trollfaceScaleY))
|
||||
|
||||
CGContextRestoreGState(c)
|
||||
|
||||
newImage = UIGraphicsGetImageFromCurrentImageContext() # UIImage returned
|
||||
|
||||
UIGraphicsEndImageContext()
|
||||
|
||||
# Save to camera roll.
|
||||
library = ALAssetsLibrary.alloc.init
|
||||
library.writeImageToSavedPhotosAlbum(newImage.CGImage, orientation:ALAssetOrientationUp, completionBlock: lambda do |assetURL, error|
|
||||
if error
|
||||
alert = UIAlertView.alloc.init
|
||||
alert.title = "Error When Saving Picture"
|
||||
alert.message = error.localizedDescription
|
||||
alert.addButtonWithTitle('OK')
|
||||
alert.show
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
27
sample/trollify/app/uiimage_extension.rb
Normal file
27
sample/trollify/app/uiimage_extension.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
class UIImage
|
||||
def imageRotatedByRadians(radians)
|
||||
# Calculate the size of the rotated view's containing box for our drawing space.
|
||||
rotatedViewBox = UIView.alloc.initWithFrame(CGRectMake(0,0,self.size.width, self.size.height))
|
||||
t = CGAffineTransformMakeRotation(radians)
|
||||
rotatedViewBox.transform = t
|
||||
rotatedSize = rotatedViewBox.frame.size
|
||||
|
||||
# Create the bitmap context.
|
||||
UIGraphicsBeginImageContext(rotatedSize)
|
||||
bitmap = UIGraphicsGetCurrentContext()
|
||||
|
||||
# Move the origin to the middle of the image so we will rotate and scale around the center.
|
||||
CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2)
|
||||
|
||||
# Rotate the image context.
|
||||
CGContextRotateCTM(bitmap, radians)
|
||||
|
||||
# Now, draw the rotated/scaled image into the context.
|
||||
CGContextScaleCTM(bitmap, 1.0, -1.0)
|
||||
CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), self.CGImage)
|
||||
|
||||
newImage = UIGraphicsGetImageFromCurrentImageContext()
|
||||
UIGraphicsEndImageContext()
|
||||
newImage
|
||||
end
|
||||
end
|
||||
BIN
sample/trollify/resources/ballmer.jpg
Normal file
BIN
sample/trollify/resources/ballmer.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
BIN
sample/trollify/resources/icon.png
Normal file
BIN
sample/trollify/resources/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.3 KiB |
BIN
sample/trollify/resources/icon@2x.png
Normal file
BIN
sample/trollify/resources/icon@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
sample/trollify/resources/trollface.png
Normal file
BIN
sample/trollify/resources/trollface.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 127 KiB |
9
sample/trollify/spec/main_spec.rb
Normal file
9
sample/trollify/spec/main_spec.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
describe "Application 'trollify'" do
|
||||
before do
|
||||
@app = UIApplication.sharedApplication
|
||||
end
|
||||
|
||||
it "has one window" do
|
||||
@app.windows.size.should == 1
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user