Skip to content

Instantly share code, notes, and snippets.

@lsloan
Forked from ltddev/HelloWorldImplementation.py
Last active November 13, 2015 20:41
Show Gist options
  • Save lsloan/d66c9ff2a88496fbcbde to your computer and use it in GitHub Desktop.
Save lsloan/d66c9ff2a88496fbcbde to your computer and use it in GitHub Desktop.
# Very simple class just to represent some business logic implementation
# which has nothing to do with the UI or any caller that uses this class.
class HelloWorldImpl():
def __init__(self):
pass
def sayHelloWorld(self):
print 'Hello World from Sheldon Wosnick'
def sayGoodbyeWorld(self):
print 'Goodbye World from Sheldon Wosnick'
def add(self, num1,num2):
return num1 + num2
def multiply(self, num1, num2):
return num1 * num2
# coding: utf-8
'''
HelloWorld - an app that tries to use a best practice to load and use ui.
It features many of the less complex ui elements and leaves more complex
ones for another exercise. it domonstrates business logic in some other
class in some other .py file. It uses a ui built in the internal ui editor
which is loaded from a controller that also doubles as a delegate for some
ui elements that support a delegate or helper class to listen for exposed
events and to handle them. This is all an exercise in my learning the
specifics of constructing fairly complex native UIs for interfacing to
as-yet-to-be-determined utility apps to run on my iPad. For utility apps
that turn out to be really useful I will build them in Xcode and produce
a standalone .ipa file that can be installed on a jailbroken ios device.
'''
import ui
# Using the console for debugging print statements.
import console
from HelloWorldImplementation import HelloWorldImpl
'''
This uses .pyui file for all ui and an object whose methods implement actions for the controls and DOES set the action method name in the .pyui file.
This is the cleanest OO way to code for Pythonista while keeping benefit
of usin th UI editor which gives even better incapsulation.
Uses an OO-style of method rather than a loose function, which also uses a
single button handler for all button taps. could extend to a greater number
of widgets and differentiate actions based on who and what the sender is for
any set of widget types where a single tap has a similar purpose. In the .pyui
file the action attribute is set to self.buttonTapped and works because the
handler class instance that handles the action implemenation is used to
LOAD THE UI. Currently this is the only way to set the action attribute in
the pyui file and handle action in a class method(s). As per omz in a
comment to me on the forum.
'''
class HelloWorldViewController():
# When this flag is true additional printing to standard out is enabled.
debugFlag = True
# For Button control
def __init__(self):
'''
If the .pyui file has the same name minus extention no need to
explicitly pass its path and name (without extention); if it has a
different name (which is completely allowed) then must explicitely
specify it.
In order to specify an action attrbute in the UI editor for a class
method name rather than a loose function name, you need to have
the (view controller) CLASS load the ui as is being done here which
loads the view and keeps a local reference to it (self.view) which
is the used to navigate subviews (widgets or controls) in a dictionary
fashion(self.mainview['subview or widget name']).
Also note that this is the way to create a class variable in Python
itself -- that is, you just declare it like any other kind of variable
except that prefixing with self says it belongs only to this class.
'''
self.mainview = ui.load_view()
# Since cant't set action in ui editor for this control set in code.
# -->> Get any subview or widget control instance in main view like this.
self.mainview['segmentedControl'].action = self.segmentedControlSelected
# Since ui editor no place to set delegate for a Textfied must set in code.
# NOTE: This class itself is the designated delegate hence '= self'
self.mainview['textfield'].delegate = self
#Since no place in ui editor to set delegate for a TextView set in code.
self.mainview['textview'].delegate = self
#Since no place in ui editor to set ScrollView delegate set in code here.
self.mainview['scrollview'].delegate = self
def buttonTapped(self,sender):
# How to have same action for multiple button and differentiate senders.
if sender.name == 'helloButton':
if self.debugFlag: print 'Hello button was tapped'
self.mainview["messageLabel"].text = "Hello"
'''
Now perform some business logic here stored in another class and file.
Note that like C/C++ but unlike Java filename and classname can differ.
The filename is 'HelloWorldImplementation.py but classname
is actually 'HelloWorldimpl'.
'''
hw = HelloWorldImpl()
hw.sayHelloWorld()
sum = hw.add(15,10)
print 'Sum of 15 and 10 is', sum
product = hw.multiply(10,15)
print 'Product of 10 and 15 is', product
elif sender.name == 'goodbyeButton':
if self.debugFlag: print 'Goodbye button was tapped'
self.mainview["messageLabel"].text = "Goodbye"
# Now perform some business logic here stored in another class.
hw = HelloWorldImpl()
hw.sayGoodbyeWorld()
else:
if self.debugFlag:print 'unknown Button/subview tapped'
# For slider control
def sliderMoved(self, sender):
if self.debugFlag: print 'Slider value:', sender.value
self.mainview['sliderLabel'].text = str(sender.value)
# For switch control
def switchChangedValue(self,sender):
if self.debugFlag: print 'Switch changed', sender.value
self.mainview['switchLabel'].text = str(sender.value)
def segmentedControlSelected(self,sender):
if self.debugFlag: print'SegmentedControl delected'
index = sender.selected_index
label = self.mainview['segmentedControlLabel']
if index == 0:
if self.debugFlag: print 'Hello tab selected'
label.text = 'Hello'
elif index == 1:
if self.debugFlag: print 'World tab selelected'
label.text = 'World'
elif index == 2:
if self.debugFlag: print 'To tab selected'
label.text = 'To'
elif index == 3:
if self.debugFlag: print'You tab selected'
label.text = 'You'
else:
if self.debugFlag: print 'Unkown tab selected'
def datepickerChanged(self,sender):
if self.debugFlag: print 'datepicker control changed'
if self.debugFlag: print sender.date
self.mainview['datepickerLabel'].text = str(sender.date)
'''The following methods are implemented because this class, in addition to
handling actions makes similar sense to be a delegate to the more complex
ui elements such as TextField. Above in the init method delegates are mapped
to this class itself, so 'self' was used.
'''
# TextField delegate method stubs
def textfield_should_begin_editing(self, textfield):
return True
def textfield_did_begin_editing(self, textfield):
if self.debugFlag: print 'textfied did begin editing'
def textfield_did_end_editing(self, textfield):
if self.debugFlag: print 'textfied did end editing'
def textfield_should_return(self, textfield):
textfield.end_editing()
return True
def textfield_should_change(self, textfield, range, replacement):
return True
def textfield_did_change(self, textfield):
if self.debugFlag: print 'textfied did change'
# TextView delegate method stubs
def textview_should_begin_editing(self, textview):
return True
def textview_did_begin_editing(self, textview):
if self.debugFlag: print 'Did begin editing'
#pass
def textview_did_end_editing(self, textview):
if self.debugFlag: print 'Did end editing'
#pass
def textview_should_change(self, textview, range, replacement):
return True
def textview_did_change(self, textview):
if self.debugFlag: print 'Did change edting'
#pass
def textview_did_change_selection(self, textview):
if self.debugFlag: print 'Did change selection'
self.mainview['textview'].keyboard_type = ui.KEYBOARD_NUMBER_PAD
#pass
#ScrollView delegate method stub
def scrollview_did_scroll(self, scrollview):
if self.debugFlag: print 'ScrollView being scrolled'
# Clear console from any previous output.
console.clear()
hw = HelloWorldViewController()
hw.mainview.present('sheet')
[{"class":"View","attributes":{"name":"Hello World!","tint_color":"RGBA(0.000000,0.478000,1.000000,1.000000)","background_color":"RGBA(1.000000,1.000000,1.000000,1.000000)","enabled":true,"border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","flex":""},"frame":"{{0, 0}, {612, 907}}","nodes":[{"class":"Button","attributes":{"font_size":15,"enabled":true,"flex":"","font_bold":false,"name":"helloButton","uuid":"D4CADD4D-F099-42E7-AD04-17E7F02DB559","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","action":"self.buttonTapped","border_width":1,"title":"Hello"},"frame":"{{101, 6}, {112, 45.5}}","nodes":[]},{"class":"Label","attributes":{"font_size":17,"enabled":true,"text":"","flex":"","name":"messageLabel","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","text_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","alignment":"left","uuid":"EEBA64F6-E353-425E-8F87-3B428054AA6C"},"frame":"{{227, 12}, {112, 32}}","nodes":[]},{"class":"Button","attributes":{"font_size":15,"enabled":true,"flex":"","font_bold":false,"name":"goodbyeButton","uuid":"0069BF2A-1AED-4E18-A377-BF6AB1809D61","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","action":"self.buttonTapped","border_width":1,"title":"Goodbye"},"frame":"{{357, 6}, {110, 45.5}}","nodes":[]},{"class":"Slider","attributes":{"enabled":true,"flex":"W","name":"slider","continuous":true,"value":0.5000000000000001,"action":"self.sliderMoved","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","uuid":"396810BE-E163-4D09-8434-A7D3B485343F"},"frame":"{{49, 69}, {207, 34}}","nodes":[]},{"class":"Label","attributes":{"font_size":17,"enabled":true,"text":"","flex":"","name":"sliderLabel","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","text_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","alignment":"left","uuid":"40079D72-7663-46D7-BFF2-B4F28541898E"},"frame":"{{269, 69}, {165, 32}}","nodes":[]},{"class":"Switch","attributes":{"enabled":true,"flex":"","name":"switch","value":true,"action":"self.switchChangedValue","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","uuid":"D43A8A7C-B7A5-4CE6-8A24-8FBCE445EED9"},"frame":"{{51.5, 123}, {51, 31}}","nodes":[]},{"class":"Label","attributes":{"font_size":17,"enabled":true,"text":"","flex":"","name":"switchLabel","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","text_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","alignment":"left","uuid":"05DF78C0-D9E5-4E59-9CF1-BAB4640BC866"},"frame":"{{110.5, 123}, {102.5, 28}}","nodes":[]},{"class":"SegmentedControl","attributes":{"name":"segmentedControl","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","uuid":"8E3A5E5A-2461-47A7-85A1-EDBCA6F73FB9","enabled":true,"segments":"Hello|World|To|You","flex":"LR"},"frame":"{{227, 124}, {243.5, 29}}","nodes":[]},{"class":"DatePicker","attributes":{"enabled":true,"flex":"","name":"datepicker","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","action":"self.datepickerChanged","mode":2,"uuid":"CFC37489-B6B0-4D8A-937D-8E3612C46982"},"frame":"{{51.5, 170.5}, {300, 216}}","nodes":[]},{"class":"Label","attributes":{"font_size":17,"enabled":true,"text":"","flex":"","name":"datepickerLabel","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","text_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","alignment":"left","uuid":"CB67F46C-0C7C-4477-8289-39FE2B0AC027"},"frame":"{{74.5, 394.5}, {223.5, 32}}","nodes":[]},{"class":"Label","attributes":{"font_size":17,"enabled":true,"text":"","flex":"","name":"segmentedControlLabel","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","text_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","alignment":"left","uuid":"5EE1E7EA-9562-4604-B7DC-FFF2B6C08DA4"},"frame":"{{478.5, 124}, {105, 32}}","nodes":[]},{"class":"TextField","attributes":{"font_size":17,"enabled":true,"text":"","flex":"","name":"textfield","border_style":3,"text_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","alignment":"left","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","placeholder":"enter text here","uuid":"63CE9D06-2EA2-42BE-9013-E0610F3207D2"},"frame":"{{359.5, 183}, {171.5, 32}}","nodes":[]},{"class":"TextView","attributes":{"font_size":17,"enabled":true,"flex":"","name":"textview","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","text_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","alignment":"left","editable":true,"border_width":1,"uuid":"F382E55C-8E87-4BF6-A966-850929AE73D0"},"frame":"{{372, 233.5}, {159, 153}}","nodes":[]},{"class":"ScrollView","attributes":{"tint_color":"RGBA(0.717143,1.000000,0.357143,1.000000)","enabled":true,"flex":"","content_width":320,"name":"scrollview","content_height":320,"border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","uuid":"D97B5E67-1B69-4F15-9435-34945082388E"},"frame":"{{62, 445}, {180, 93.5}}","nodes":[{"class":"TextField","attributes":{"font_size":17,"enabled":true,"flex":"","name":"textfield1","border_style":3,"text_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","alignment":"left","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","uuid":"40D2E40F-0210-4DCE-8D3C-CE5BA35334BB"},"frame":"{{60, 44.5}, {200, 32}}","nodes":[]},{"class":"Switch","attributes":{"name":"switch1","value":true,"uuid":"18E47A43-CC53-4FC2-BF6E-F7AF0A6A16C5","enabled":true,"border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","flex":""},"frame":"{{134, 144}, {51, 31}}","nodes":[]},{"class":"TableView","attributes":{"enabled":true,"data_source_font_size":18,"data_source_number_of_lines":1,"flex":"WH","name":"tableview1","data_source_delete_enabled":true,"row_height":44,"border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","data_source_items":"Row 1\nRow 2 >\nRow 3 (i)","background_color":"RGBA(1.000000,1.000000,1.000000,1.000000)","uuid":"4A72CB47-8C93-410F-8C55-D39584B6E02A"},"frame":"{{34.5, 84.5}, {320, 320}}","nodes":[]},{"class":"Button","attributes":{"font_size":15,"enabled":true,"flex":"","font_bold":false,"name":"button1","uuid":"6E737CB4-3DEF-4A63-982F-DC05E4CE286A","border_color":"RGBA(0.000000,0.000000,0.000000,1.000000)","title":"Button"},"frame":"{{0, 288}, {80, 32}}","nodes":[]}]}]}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment