Skip to content

Instantly share code, notes, and snippets.

@sbbosco
Last active May 19, 2023 14:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sbbosco/be4d1a1b63ad5f983927fa0dacce712e to your computer and use it in GitHub Desktop.
Save sbbosco/be4d1a1b63ad5f983927fa0dacce712e to your computer and use it in GitHub Desktop.
Alternate dialogs module for Pythonista 3.4
import time
from threading import current_thread
from datetime import date, datetime
from dateutil.tz import tzutc, tzlocal
from objc_util import ObjCClass
import ui
"""
Alternate dialogs module for Pythonista 3.4
modify import:
#import dialogs
from uidialogs import dialogs
"""
debuglevel = 0
def dprint(*args):
if debuglevel > 0:
print('debug: ', args)
dprint('ui dialogs')
class waitModal():
def __init__(self):
self.done = False
self.result = None
def wait(self):
waitcount = 0
for n in range(10):
try:
time.sleep(1.0)
dprint('wait -|-')
if self.done:
dprint('modal waited')
break
waitcount += 1
if waitcount == 10:
self.done = [-1, 'none', 'none']
break
except:
print("Exception ",str(sys.exc_info()))
break
dprint('modal waited')
def set_result(self, value):
self.result = value
dprint('wait result', self.result)
self.done = True
NSIndexPath = ObjCClass('NSIndexPath')
class _FormView(ui.View):
def __init__(self):
self.delegate = None
class dialogs():
def __init__(self):
pass
def form_dialog(title='', fields=[], sections=None, done_button_title='Done', frame=None, callback=None):
result = {}
form_title = title
done_title = done_button_title
if fields:
sections = [('', fields)]
xmark = ui.Image.named('iob:ios7_close_32')
class TextFieldDelegate (object):
def textfield_should_begin_editing(textfield):
result = did_begin(textfield)
return result
def textfield_did_end_editing(textfield):
result = did_edit(textfield)
return result
def close_view(sender, result=None):
wait.set_result(result)
form.close()
container.close()
time.sleep(.2)
def submit(sender):
dprint('submit')
parms = {}
f = 0
for sec in sections:
fields = sec[1]
for i in range(len(fields)):
item = fields[i]
if not fields[i].get('key', None):
fields[i]['key'] = fields[i]['title']
if item['type'] == 'switch':
parms[fields[i]['key']] = True if fld[f].value else False
elif item['type'] == 'list':
parms[fields[i]['key']] = int(fields[i]['id'])
elif item['type'] == 'date':
dateobj = fld[f].date
datestr = dateobj.strftime('%Y-%m-%d')
parms[fields[i]['key']] = datestr
elif item['type'] == 'int':
parms[fields[i]['key']] = fields[i]['value']
elif item['type'] == 'textarea':
parms[fields[i]['key']] = str(fld[f].text)
elif item['type'] == 'check':
if fldvalues[f] > 0:
parms[fields[i]['key']] = True
else:
parms[fields[i]['key']] = False
else:
if item.get('hidden', False):
parms[fields[i]['key']] = fields[i]['value']
else:
parms[fields[i]['key']] = str(fld[f].text)
f += 1
if item.get('hidden', False): continue
close_view(None, parms)
if callback:
callback(parms)
def did_begin(sender):
dprint('begin', sender.tag)
item = sections[0][1][sender.tag]
print(item)
return True
def fromutc(dt):
dt_offset = dt.utcoffset()
dt_dst = dt.dst()
delta = dt_offset - dt_dst
if delta:
dt += delta
dtdst = dt.dst()
if dtdst:
return dt + dtdst
else:
return dt
def did_edit(sender):
dprint('end')
ui.end_editing()
def list_end(result):
dprint('end', result)
def tableview_cell_for_row(tableview, section, row):
if form.data[section][row][2] == 'check':
cell = ui.TableViewCell(style='default')
cell.text_label.text = form.data[section][row][1]
if fldvalues[form.data[section][row][0]] > 0:
cell.accessory_type = 'checkmark'
else:
cell.accessory_type = 'none'
return cell
else:
cell = ui.TableViewCell(style='value1')
cell.text_label.text = form.data[section][row][1]
cell.content_view.add_subview(form.data[section][row][2])
return cell
def tableview_did_select(tableview, section, row):
if form.data[section][row][2] == 'check':
dprint('check')
if int(toggle_check(section, row)) > 0:
dprint('checked', form.data[section][row][0])
fldvalues[form.data[section][row][0]] = 1
else:
fldvalues[form.data[section][row][0]] = 0
ui.end_editing()
form.selected_row = -1
def tableview_number_of_sections(tableview):
return len(sections)
def tableview_title_for_header(tableview, section):
return sections[section][0]
def tableview_number_of_rows(tableview, section):
return secrows[section]
def toggle_check(section, row):
index_path = NSIndexPath.indexPathForRow(row, inSection=section)
cell = form.objc_instance.cellForRowAtIndexPath_(index_path)
if cell.accessoryType() == 0:
cell.setAccessoryType_(3)
else:
cell.setAccessoryType_(0)
return cell.accessoryType()
def kb_frame_will_change(f):
r = ui.convert_rect(f, to_view=container)
if r[3] > 0:
kbh = form.height - r[1]
else:
kbh = 0
update_kb_height(kbh)
def update_kb_height(h):
form.content_inset = (0, 0, h, 0)
form.scroll_indicator_insets = (0, 0, h, 0)
container = _FormView()
form = ui.TableView()
ds = ui.ListDataSource([])
form.data_source = form.delegate = ds
form.title = title
form.background_color = 'lightgray'
ds.tableview_cell_for_row = tableview_cell_for_row
ds.tableview_did_select = tableview_did_select
ds.tableview_number_of_sections = tableview_number_of_sections
ds.tableview_title_for_header = tableview_title_for_header
ds.tableview_number_of_rows = tableview_number_of_rows
container.keyboard_frame_will_change = kb_frame_will_change
tbldata = []
if frame:
x, y, w, h = frame
dprint('frame', frame)
else:
winw, winh = ui.get_window_size()
if winw < 580 or winh < 640:
x, y, w, h = (0, 0, winw, winh)
else:
x, y, w, h = (0, 0, 580, 640)
dprint('auto', frame)
i = 0
fld = []
fldvalues = []
fldidx = {}
secrows = []
dprint('len', len(sections))
for section in sections:
secdata = []
for item in section[1]:
fld.append(0)
fldvalues.append(0)
if item.get('hidden', False):
i += 1
continue
if item['type'] == 'textarea':
fld[i] = ui.TextView()
fld[i].text = item.get('value', '')
fld[i].tag = i
fld[i].font = ('Menlo', 14)
fld[i].frame = (125, 15, 250, 280)
elif item['type'] == 'switch':
fld[i] = ui.Switch()
fld[i].value = item.get('value', False)
fld[i].tag = i
#fld[i].frame = (125, 15, 100, 30)
elif item['type'] == 'date':
fld[i] = ui.DatePicker()
fld[i].mode = ui.DATE_PICKER_MODE_DATE
fld[i].date = item.get('value', datetime.today)
fld[i].tag = i
elif item['type'] == 'list':
fld[i] = ui.TextField()
fld[i].text = item.get('value', [])
fld[i].tag = i
fld[i].textfield_should_begin_editing = did_begin
elif item['type'] == 'decimal':
fld[i] = ui.TextField()
fld[i].text = item.get('value', '')
fld[i].tag = i
fld[i].keyboard_type = ui.KEYBOARD_DECIMAL_PAD
elif item['type'] == 'check':
fld[i] = 'check'
if item.get('value', None):
fldvalues[i] = 3
elif item['type'] in ('text', 'url', 'email','number', 'password'):
fld[i] = ui.TextField()
fld[i].text = item.get('value', '')
fld[i].tag = i
fld[i].clear_button_mode = 'while_editing'
if item['type'] == 'text':
fld[i].autocorrection_type = item.get('autocorrection', None)
fld[i].autocapitalization_type = item.get('autocapitalization', ui.AUTOCAPITALIZE_SENTENCES)
fld[i].spellchecking_type = item.get('spellchecking', None)
elif item['type'] == 'url':
fld[i].keyboard_type = ui.KEYBOARD_URL
fld[i].autocapitalization_type = ui.AUTOCAPITALIZE_NONE
fld[i].autocorrection_type = False
fld[i].spellchecking_type = False
elif item['type'] == 'email':
fld[i].keyboard_type = ui.KEYBOARD_EMAIL
fld[i].autocapitalization_type = ui.AUTOCAPITALIZE_NONE
fld[i].autocorrection_type = False
fld[i].spellchecking_type = False
elif item['type'] == 'number':
#fld[i].keyboard_type = ui.KEYBOARD_NUMBERS
fld[i].keyboard_type = ui.KEYBOARD_NUMBER_PAD
fld[i].autocapitalization_type = ui.AUTOCAPITALIZE_NONE
fld[i].autocorrection_type = False
fld[i].spellchecking_type = False
elif item['type'] == 'password':
fld[i].secure = True
if not item['type'] in ('check', 'textarea'):
if len(item['title']) > 24:
fld[i].frame = (260, 6, w - 275, 32)
elif len(item['title']) > 5:
fld[i].frame = (140, 6, w - 155 , 32)
else:
fld[i].frame = (120, 6, w - 135 , 32)
secdata.append([i, item['title'], fld[i]])
i += 1
tbldata.append(secdata)
secrows.append(len(secdata))
form.data = tbldata
ds.items = tbldata
form.name = form_title
container.left_button_items = [ui.ButtonItem(image=xmark, action=close_view)]
container.right_button_items = [ui.ButtonItem(title=done_title, action=submit)]
form.frame = (0, 0, w, h)
form.flex = 'WH'
container.frame = (0, 0, w, h)
container.flex = 'WH'
container.add_subview(form)
container.present('sheet', hide_close_button=True)
dprint('present')
dprint(current_thread().name)
wait = waitModal()
form.wait_modal()
return wait.result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment