Skip to content

Instantly share code, notes, and snippets.

@kianwilcox
Created September 5, 2012 00:01
Show Gist options
  • Save kianwilcox/3628288 to your computer and use it in GitHub Desktop.
Save kianwilcox/3628288 to your computer and use it in GitHub Desktop.
Calculator view in RubyMotion
class Calculator < UIView
attr_accessor :entryView
attr_accessor :stepView
attr_accessor :keyboardView
attr_accessor :current_problem
attr_accessor :nextInput
attr_accessor :hint
attr_accessor :reveal
attr_accessor :explain
attr_accessor :solution
def initWithFrame(frame)
super
self.stepView=UITableView.alloc.initWithFrame(CGRectMake(0, 0, frame.size.width, 600), style:UITableViewStylePlain)
self.stepView.transform = CGAffineTransformMakeRotation(3.14159)
self.addSubview(self.stepView)
self.stepView.dataSource = self
self.stepView.delegate = self
self.keyboardView=CalcKeyboardView.alloc.initWithFrame(CGRectMake(0, 1000, frame.size.width, 400))
self.keyboardView.owner=self
self.addSubview(self.keyboardView)
self.entryView=EntryView.alloc.initWithFrame(CGRectMake(0, 600, frame.size.width, 100))
self.addSubview(self.entryView)
self.entryView.field.inputView=self.keyboardView
self.entryView.field.becomeFirstResponder()
self
end
def enter
if self.solution.equation == "" || self.solution.equation == nil || self.solution.equation == "Enter Equation Here"
self.solution.equation = self.entryView.field.text
self.entryView.renderLatex(self.solution.equation, self.entryView.display)
add
elsif self.entryView.field.text == ""
else
add
end
end
def add
self.solution.add_step(entryView.field.text) do
reload
end
end
def reload
self.entryView.field.text=""
self.stepView.reloadData
end
def solve
self.solution.solve do |solution|
reload
end
end
def buttonAction(button)
fn = entryView.buttons[button]
fn ||= ->() { self.entryView.field.text += button}
fn.call()
end
def tableView(tableView, numberOfRowsInSection:section)
self.solution.step_strings.count
end
def tableView(tableView, cellForRowAtIndexPath:indexPath)
@reuseIdentifier ||= "CELL_IDENTIFIER"
cell = tableView.dequeueReusableCellWithIdentifier(@reuseIdentifier) || begin
UITableViewCell.alloc.initWithStyle(UITableViewCellStyleDefault, reuseIdentifier:@reuseIdentifier)
end
cell.transform = CGAffineTransformMakeRotation(3.14159)
cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth
cell.backgroundColor = UIColor.clearColor
eq = self.solution.step_strings.reverse[indexPath.row]
frame = cell.contentView.frame
web = UIWebView.alloc.initWithFrame(frame)
web.scrollView.scrollEnabled = false
web.scrollView.bounces = false
web.delegate = self
cell.contentView.addSubview(web)
self.entryView.renderLatex(eq, web)
cell
end
end
class EntryView < UIView
attr_accessor :display
attr_accessor :field
attr_accessor :hint
attr_accessor :solve
attr_accessor :index
def renderLatex(latex, web)
web.loadRequest(mathJax(latex))
end
def initWithFrame(frame)
super
self.index = 0
@mathjax_path = NSBundle.mainBundle.pathForResource("MathJax", ofType:"js", inDirectory:"mathjax")
size = frame.size
self
# where the current problem will be displayed
self.display = UIWebView.alloc.initWithFrame(CGRectMake(120,20, 534, 30))
self.display.sizeToFit
self.display.layer.cornerRadius = 5;
self.display.clipsToBounds = true;
self.display.delegate = self
self.addSubview(display)
self.display.loadHTMLString("Please Enter an Equation Below", baseURL:nil)
# Entry area for the equation we are solving
self.field = CalcKeyboardInputField.alloc.initWithFrame(CGRectMake(120, 58, 534, 30))
self.field.text = ""
self.field.backgroundColor = UIColor.whiteColor
self.field.borderStyle = UITextBorderStyleRoundedRect
self.addSubview(self.field)
self
end
def buttons
self.field.buttons
end
def default_mathjax(eq)
"<html><head><meta name='viewport' content='initial-scale=1.0' />
<script type='text/javascript' src='#{@mathjax_path}?config=default.js'></script>
</head><body><div id='mathjax'>$ #{eq} $</div></body></html>"
end
def mathJax(eq)
self.index+=1
temp = NSTemporaryDirectory().stringByAppendingPathComponent("math#{index}.html")
writeStringToFile(default_mathjax(eq), temp)
url = NSURL.fileURLWithPath(temp)
NSURLRequest.alloc.initWithURL(url)
end
def writeStringToFile(string, path)
string.writeToFile(path, atomically:true, encoding:NSUTF8StringEncoding, error:nil)
end
end
class CalcKeyboardInputField < UITextField
attr_accessor :owner
attr_accessor :currentIndex
attr_accessor :buttons
def initWithFrame(frame)
super
@numerals = {}
(0..9).each do |n|
@numerals[n.to_s]= ->(){ self.text = after(self.text, n.to_s) }
end
@arithmetic = {}
['(', ')', '+', '-', '*', '/', '='].each do |op|
@arithmetic[op]= ->(){ self.text = after(self.text, op) }
end
@special = {}
['Enter', 'Hint', 'Solve', 'Explain'].each do |action|
@special[action]= ->(){ self.superview().superview().send(action.downcase) }
end
@special['<-']= ->(){ self.backspace }
@buttons = @numerals.merge(@arithmetic).merge(@special)
self
end
def viewDidLoad
super
self.owner = self.superview()
end
def buttons
@buttons
end
def after(input, newInput)
input+newInput
end
def before(input, newInput)
newInput+input
end
def between(before, middle, after)
before+middle+after
end
def backspace
self.text = self.text.slice(0, self.text.length-1)
end
end
class CalcKeyboardView < UIView
attr_accessor :owner
def initWithFrame(frame)
super
# .. do your magic
rows.each_with_index do |row, rowIndex|
row.each_with_index do |name, colIndex|
newButton = roundedButtonWith(rowIndex, colIndex)
self.addSubview(newButton)
newButton.setTitle(name, forState:UIControlStateNormal)
newButton.when(UIControlEventTouchUpInside) do
owner.buttonAction(name)
end
end
end
self
end
def rows
[
['Rad', 'Deg', 'x!', '(', ')', '', 'sqrt', '<-'],
['sin', 'cos', 'x^2', '7', '8', '9', '/', 'e'],
['sec', 'tan', 'ln', '4', '5', '6', '*', 'pi'],
['sinh', 'cosh', 'log', '1', '2', '3', '-', '=', 'Solve'],
['sech', 'tanh', 'x^y', '.', '0', 'x', '+', 'Enter', 'Hint']
]
end
def roundedButtonWith(row, col)
button = UIButton.buttonWithType UIButtonTypeRoundedRect
button.frame = CGRectMake(120+col*68, 160+row*48, 60, 40)
button
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment