omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Text display help

    Pythonista
    4
    24
    7183
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Bumbo Cactoni
      Bumbo Cactoni last edited by

      Never mind. I found what to edit

      stephen 1 Reply Last reply Reply Quote 0
      • stephen
        stephen @Bumbo Cactoni last edited by

        @Bumbo-Cactoni said:

        Never mind. I found what to edit

        what happened?

        1 Reply Last reply Reply Quote 0
        • Bumbo Cactoni
          Bumbo Cactoni last edited by

          I couldn’t find what variable to edit to get to the right file, but now I have

          stephen 1 Reply Last reply Reply Quote 0
          • stephen
            stephen @Bumbo Cactoni last edited by

            @Bumbo-Cactoni oh ok i meant to Make note of where that was originally..

            i think i saw younsay somthing about it slowing down when you typed?

            1 Reply Last reply Reply Quote 0
            • Bumbo Cactoni
              Bumbo Cactoni last edited by Bumbo Cactoni

              @stephen
              I don’t know exactly why, but the longer I type for, the slower the program gets. It’s not a big issue, as I can just close the text editor and reopen it.

              mikael 1 Reply Last reply Reply Quote 0
              • mikael
                mikael @Bumbo Cactoni last edited by mikael

                @Bumbo-Cactoni, I am sure this was just a quick prototype, as there is a lot happening every time you type a single letter. @stephen, maybe as a quick fix, remove all the history stuff as it is not necessary here? Also, consider saving to file in a background thread, and only whenever there is e.g. a 500 ms break in the typing action.

                ... Sorry, disregard the second point, as I see the saving only happens when closing.

                1 Reply Last reply Reply Quote 2
                • Bumbo Cactoni
                  Bumbo Cactoni last edited by

                  @stephen
                  I agree with mikael. His point is valid: I don’t really need the history stuff, and just in case I do, I can put all the history stuff in a separate text file, so I can put it in if needed.

                  1 Reply Last reply Reply Quote 0
                  • Bumbo Cactoni
                    Bumbo Cactoni last edited by Bumbo Cactoni

                    Alright. I have figured out how to make it work faster, without deleting the code. Just make all the update_history, undo, and redo into comments:

                    import ui
                    
                    def new_button(frame, title, action):
                        btn=ui.Button()
                        btn.frame=frame
                        btn.background_color='#686868'
                        btn.tint_color='#000000'
                        btn.title=title
                        btn.action=action
                        return btn
                    
                    class Text_Editor:
                        def __init__(self, main, tv, text_file, *args, **kwargs):
                            # undo/redo View
                            self.main=main
                            self.text_file=text_file
                            self.active_file=None
                            self.history_view = ui.TextView(
                                    text='UNDO HISTORY',
                                    frame=(250, 275, 300, 400),
                                    editable=False,
                                    border_width=5,
                                    background_color='#dedede')
                    
                            # Undo Button
                    #        undo_btn=new_button(frame=(25, 2, 100, 46), title='undo', action=self.undo)
                    #        main.add_subview(undo_btn)
                    
                            # Redo Button
                    #        redo_btn=new_button(frame=(127, 2, 100, 46), title='redo', action=self.redo)
                    #        main.add_subview(redo_btn)
                            
                            # Close Button
                            close_btn=new_button(frame=(525, 2, 100, 46), title='close', action=self.close)
                            main.add_subview(close_btn)
                            
                            self.history=[]
                            self.current_index=len(self.history)
                            self.textview=tv
                            self.textview_should_begin_editing(self.textview)
                    
                        def append(self, text):
                            self.main.remove_subview(self.history_view)
                            if self.current_index < len(self.history):
                                self.history=self.history[:self.current_index]
                            self.current_index=len(self.history)
                            self.history.append(text)
                            self.current_index+=1
                    
                    #        self.update_history(self.current_index)
                    
                    #    def update_history(self, index):
                    #        self.history_view.text=''
                    #        for i, x in enumerate(self.history):
                    #            if i == index:
                    #                self.history_view.text+=str(i)+' '+x+' <--'+'\n'
                    #            elif x == self.history[-1] and index == len(self.history):
                    #                self.history_view.text+=str(i)+' '+x+' <--'+'\n'
                    #            else:
                    #                self.history_view.text+=str(i)+' '+x+'\n'
                                
                        def close(self, sender):
                            with open(self.text_file, 'w') as f:
                                f.writelines(self.textview.text.splitlines(keepends=True))
                            sender.superview.close()
                            
                            
                        
                    #    def redo(self, sender):
                    #        if self.current_index == len(self.history):
                    #            return
                    #        if self.current_index < len(self.history):
                    #            self.current_index+=1
                    #            self.textview.text = self.history[self.current_index-1]
                    #        self.update_history(self.current_index-1)
                    
                    #    def undo(self, sender):
                    #        if self.current_index == 0:
                    #            return
                    #        self.main.add_subview(self.history_view)
                            
                    #        self.current_index-=1
                    #        self.textview.text = self.history[self.current_index-1]
                    #        self.update_history(self.current_index-1)
                    
                            
                        def textview_should_begin_editing(self, textview):
                            if textview.text=='' and self.active_file ==None:
                                if self.text_file:
                                    with open(self.text_file, 'r') as f:
                                        self.active_file=f
                                        for line in f:
                                            textview.text+=line
                            self.textview=textview
                            return True
                    
                        def textview_did_change(self, textview):
                            self.append(textview.text)
                    #        self.update_history(self.current_index)
                            pass
                    
                    class Main(ui.View):
                        def __init__(self, *args, **kwargs):
                            
                            
                            """THIS IS WHERE YOU EDIT THE FILE!"""
                            
                            text_file='./file.txt'
                            
                            
                            # Main Window
                            self.width = 650
                            self.height = 1000
                            self.background_color="#8b8b8b"
                            self.update_interval=1
                    
                            # Text Input Window
                            self.tv = ui.TextView(
                                    text='',
                                    frame=(25, 50, 600, 875),
                                    background_color='#dedede')
                            self.add_subview(self.tv)
                            self.tv.delegate=Text_Editor(self, self.tv, text_file)
                        
                    
                    
                    if __name__ == '__main__':
                        Main().present('sheet', hide_title_bar=True) ```
                    stephen 1 Reply Last reply Reply Quote 0
                    • stephen
                      stephen @Bumbo Cactoni last edited by

                      @Bumbo-Cactoni im not 100% on understanding exactly what you are going for so ive just beenthrowin stuff together to help ya out. ive been running under the assumption of a text editor lol thats why i included the undo funtionality, and currently playing around with a custom file picker.

                      as for your workaroud, @mikael was correct about history update. but you only needed to remove the history_view stuff you can keep the undo-redo stuff if you like. and i would suggest not storing history in a file unless yourvwanting to keep a log of changes. i say this because history is just the ontainer holding the diferent states of your text for undo-redo. and changes often and you wouldnt want to open and close a file lot to keep it updated.

                      1 Reply Last reply Reply Quote 1
                      • Bumbo Cactoni
                        Bumbo Cactoni last edited by Bumbo Cactoni

                        @stephen
                        Ok, thanks! Also, yes, I was aiming for a text editor! If you figure out the custom file picker, let me know! I think that would be awesome to have in a text editor!

                        mikael stephen 2 Replies Last reply Reply Quote 1
                        • mikael
                          mikael @Bumbo Cactoni last edited by

                          @Bumbo-Cactoni, we still do not know why you need this type of a text editor, and do not just use Pythonista’s editor.

                          Use google or other search engine to search for ”omz forum file picker dialog”, and you will find something, I am sure.

                          1 Reply Last reply Reply Quote 1
                          • stephen
                            stephen @Bumbo Cactoni last edited by

                            @Bumbo-Cactoni said:

                            @stephen
                            Ok, thanks! Also, yes, I was aiming for a text editor! If you figure out the custom file picker, let me know! I think that would be awesome to have in a text editor!

                            here is the text editor with the file picker added at the start. this was a fun one so i may contenu to add onto this myself. Though i do agree with @mikael.. Im not picturing why you want this unless just for learning? or is this meant for some type of note taking mecanic to a game or app?

                            import ui
                            import os
                            from objc_util import ObjCInstance, ObjCClass
                            from operator import attrgetter
                            import time
                            import threading
                            import functools
                            import ftplib
                            import re
                            
                            # http://stackoverflow.com/a/6547474
                            def human_size(size_bytes):
                                '''Helper function for formatting human-readable file sizes'''
                                if size_bytes == 1:
                                    return "1 byte"
                                suffixes_table = [('bytes',0),('KB',0),('MB',1),('GB',2),('TB',2), ('PB',2)]
                                num = float(size_bytes)
                                for suffix, precision in suffixes_table:
                                    if num < 1024.0:
                                        break
                                    num /= 1024.0
                                if precision == 0:
                                    formatted_size = "%d" % num
                                else:
                                    formatted_size = str(round(num, ndigits=precision))
                                return "%s %s" % (formatted_size, suffix)
                            
                            class TreeNode (object):
                                def __init__(self):
                                    self.expanded = False
                                    self.children = None
                                    self.leaf = True
                                    self.title = ''
                                    self.subtitle = ''
                                    self.icon_name = None
                                    self.level = 0
                                    self.enabled = True
                            
                                def expand_children(self):
                                    self.expanded = True
                                    self.children = []
                            
                                def collapse_children(self):
                                    self.expanded = False
                            
                                def __repr__(self):
                                    return '<TreeNode: "%s"%s>' % (self.title, ' (expanded)' if self.expanded else '')
                            
                            class FileTreeNode (TreeNode):
                                def __init__(self, path, show_size=True, select_dirs=True,
                                       file_pattern=None):
                                    TreeNode.__init__(self)
                                    self.path = path
                                    self.title = os.path.split(path)[1]
                                    self.select_dirs = select_dirs
                                    self.file_pattern = file_pattern
                                    is_dir = os.path.isdir(path)
                                    self.leaf = not is_dir
                                    ext = os.path.splitext(path)[1].lower()
                                    if is_dir:
                                        self.icon_name = 'iob:filing_24'
                                    elif ext == '.py':
                                        self.icon_name = 'iob:code_24'
                                    elif ext == '.pyui':
                                        self.icon_name = 'UI File'
                                    elif ext in ('.png', '.jpg', '.jpeg', '.gif'):
                                        self.icon_name = 'iob:image_24'
                                    elif ext == '.txt':
                                        self.icon_name = 'iob:compose_24'
                                    elif ext == '.md':
                                        self.icon_name = 'iob:ios7_bookmarks_outline_24'
                                    elif ext == '.html':
                                        self.icon_name = 'iob:leaf_24'
                                    elif ext == '.css':
                                        self.icon_name = 'CSS File'
                                    else:
                                        self.icon_name = 'FileOther'
                                    self.show_size = show_size
                                    if not is_dir and show_size:
                                        self.subtitle = human_size((os.stat(self.path).st_size))
                                    if is_dir and not select_dirs:
                                        self.enabled = False
                                    elif not is_dir:
                                        filename = os.path.split(path)[1]
                                        for x in file_pattern:
                                            if x in filename:
                                                self.enabled = True
                                                break
                                                
                            
                                @property
                                def cmp_title(self):
                                    return self.title
                            
                                def expand_children(self):
                                    if self.children is not None:
                                        self.expanded = True
                                        return
                                    files = os.listdir(self.path)
                                    children = []
                                    for filename in files:
                                        if filename.startswith('.'):
                                            continue
                                        full_path = os.path.join(self.path, filename)
                                        node = FileTreeNode(full_path, self.show_size, self.select_dirs, self.file_pattern)
                                        node.level = self.level + 1
                                        children.append(node)
                                    self.expanded = True
                                    self.children = sorted(children, key=attrgetter('leaf', 'cmp_title'))
                            
                            
                            class TreeDialogController (object):
                                def __init__(self, main, root_node, x, y, allow_multi=False, async_mode=False):
                                    self.main=main
                                    self.async_mode = async_mode
                                    self.allow_multi = allow_multi
                                    self.selected_entries = None
                                    self.table_view = ui.TableView()
                                    self.table_view.frame = (0, 0, 500, 500)
                                    self.table_view.data_source = self
                                    self.table_view.delegate = self
                                    self.table_view.flex = 'WH'
                                    self.table_view.border_width=5
                                    self.table_view.corner_radius=8.0
                                    self.table_view.allows_multiple_selection = False
                                    self.table_view.background_color='#daba8b'
                                    self.table_view.tint_color = '#ff00d1'
                                    self.view = ui.View(frame=(x, y, 500, 500))
                                    self.view.add_subview(self.table_view)
                                    self.view.name = root_node.title
                                    self.busy_view = ui.View(frame=self.view.bounds, flex='WH', background_color=(0, 0, 0, 0.35))
                                    hud = ui.View(frame=(self.view.center.x - 50, self.view.center.y - 50, 100, 100))
                                    hud.background_color = (0, 0, 0, 0.7)
                                    hud.corner_radius = 8.0
                                    hud.flex = 'TLRB'
                                    spinner = ui.ActivityIndicator()
                                    spinner.style = ui.ACTIVITY_INDICATOR_STYLE_WHITE_LARGE
                                    spinner.center = (50, 50)
                                    spinner.start_animating()
                                    hud.add_subview(spinner)
                                    self.busy_view.add_subview(hud)
                                    self.busy_view.alpha = 0.0
                                    self.view.add_subview(self.busy_view)
                                    self.done_btn = ui.ButtonItem(title='Done', action=self.done_action)
                                    if self.allow_multi:
                                        self.view.right_button_items = [self.done_btn]
                                    self.done_btn.enabled = False
                                    self.root_node = root_node
                                    self.entries = []
                                    self.flat_entries = []
                                    if self.async_mode:
                                        self.set_busy(True)
                                        t = threading.Thread(target=self.expand_root)
                                        t.start()
                                    else:
                                        self.expand_root()
                            
                                def expand_root(self):
                                    self.root_node.expand_children()
                                    self.set_busy(False)
                                    self.entries = self.root_node.children
                                    self.flat_entries = self.entries
                                    self.table_view.reload()
                            
                                def flatten_entries(self, entries, dest=None):
                                    if dest is None:
                                        dest = []
                                    for entry in entries:
                                        dest.append(entry)
                                        if not entry.leaf and entry.expanded:
                                            self.flatten_entries(entry.children, dest)
                                    return dest
                            
                                def rebuild_flat_entries(self):
                                    self.flat_entries = self.flatten_entries(self.entries)
                            
                                def tableview_number_of_rows(self, tv, section):
                                    return len(self.flat_entries)
                            
                                def tableview_cell_for_row(self, tv, section, row):
                                    cell = ui.TableViewCell()
                                    cell.background_color='#daba8b'
                                    entry = self.flat_entries[row]
                                    level = entry.level - 1
                                    image_view = ui.ImageView(frame=(44 + 20*level, 5, 34, 34))
                                    label_x = 44+34+8+20*level
                                    label_w = cell.content_view.bounds.w - label_x - 8
                                    if entry.subtitle:
                                        label_frame = (label_x, 0, label_w, 26)
                                        sub_label = ui.Label(frame=(label_x, 26, label_w, 14))
                                        sub_label.font = ('<System>', 12)
                                        sub_label.text = entry.subtitle
                                        sub_label.text_color = '#2a8a99'
                                        cell.content_view.add_subview(sub_label)
                                    else:
                                        label_frame = (label_x, 0, label_w, 44)
                                    label = ui.Label(frame=label_frame)
                                    if entry.subtitle:
                                        label.font = ('<System>', 15)
                                    else:
                                        label.font = ('<System>', 18)
                                    label.text = entry.title
                                    label.flex = 'W'
                                    cell.content_view.add_subview(label)
                                    if entry.leaf and not entry.enabled:
                                        label.text_color = '#66006b'
                                    cell.content_view.add_subview(image_view)
                                    if not entry.leaf:
                                        has_children = entry.expanded
                                        btn = ui.Button(image=ui.Image.named('iob:minus_round_24' if has_children else 'iob:plus_round_24'))
                                        btn.frame = (20*level, 0, 44, 44)
                                        btn.action = self.expand_dir_action
                                        cell.content_view.add_subview(btn)
                                    if entry.icon_name:
                                        image_view.image = ui.Image.named(entry.icon_name)
                                    else:
                                        image_view.image = None
                                    cell.selectable = entry.enabled
                                    return cell
                            
                                def row_for_view(self, sender):
                                    '''Helper to find the row index for an 'expand' button'''
                                    cell = ObjCInstance(sender)
                                    while not cell.isKindOfClass_(ObjCClass('UITableViewCell')):
                                        cell = cell.superview()
                                    return ObjCInstance(self.table_view).indexPathForCell_(cell).row()
                            
                                def expand_dir_action(self, sender):
                                    '''Invoked by 'expand' button'''
                                    row = self.row_for_view(sender)
                                    entry = self.flat_entries[row]
                                    if entry.expanded:
                                        sender.image = ui.Image.named('iob:plus_round_24')
                                    else:
                                        sender.image = ui.Image.named('iob:minus_round_24')
                                    self.toggle_dir(row)
                                    self.update_done_btn()
                            
                                def toggle_dir(self, row):
                                    '''Expand or collapse a folder node'''
                                    entry = self.flat_entries[row]
                                    if entry.expanded:
                                        entry.collapse_children()
                                        old_len = len(self.flat_entries)
                                        self.rebuild_flat_entries()
                                        num_deleted = old_len - len(self.flat_entries)
                                        deleted_rows = range(row + 1, row + num_deleted + 1)
                                        self.table_view.delete_rows(deleted_rows)
                                    else:
                                        if self.async_mode:
                                            self.set_busy(True)
                                            expand = functools.partial(self.do_expand, entry, row)
                                            t = threading.Thread(target=expand)
                                            t.start()
                                        else:
                                            self.do_expand(entry, row)
                            
                                def do_expand(self, entry, row):
                                    '''Actual folder expansion (called on background thread if async_mode is enabled)'''
                                    entry.expand_children()
                                    self.set_busy(False)
                                    old_len = len(self.flat_entries)
                                    self.rebuild_flat_entries()
                                    num_inserted = len(self.flat_entries) - old_len
                                    inserted_rows = range(row + 1, row + num_inserted + 1)
                                    self.table_view.insert_rows(inserted_rows)
                            
                                def tableview_did_select(self, tv, section, row):
                                    
                                    self.update_done_btn()
                            
                                def tableview_did_deselect(self, tv, section, row):
                                    self.update_done_btn()
                            
                                def update_done_btn(self):
                                    '''Deactivate the done button when nothing is selected'''
                                    selected = [self.flat_entries[i[1]] for i in self.table_view.selected_rows if self.flat_entries[i[1]].enabled]
                            #        print(selected)
                                    if selected and not self.allow_multi:
                                        self.done_action(None)
                                    else:
                                        self.done_btn.enabled = len(selected) > 0
                            
                                def set_busy(self, flag):
                                    '''Show/hide spinner overlay'''
                                    def anim():
                                        self.busy_view.alpha = 1.0 if flag else 0.0
                                    ui.animate(anim)
                            
                                def done_action(self, sender):
                                    self.selected_entries = [self.flat_entries[i[1]] for i in self.table_view.selected_rows if self.flat_entries[i[1]].enabled]
                                    self.main.open_file(self, self.selected_entries[0].path)
                                    
                            
                            def file_picker_dialog(parent, x, y, title=None, root_dir=None, multiple=False,
                                                   select_dirs=False, file_pattern=None, show_size=True):
                                if root_dir is None:
                                    root_dir = os.path.expanduser('..')
                                if title is None:
                                    title = os.path.split(root_dir)[1]
                                root_node = FileTreeNode(root_dir, show_size, select_dirs, file_pattern)
                                root_node.title = title or ''
                                picker = TreeDialogController(parent, root_node, x, y, allow_multi=multiple)
                                parent.add_subview(picker.view)
                                picker.view.wait_modal()
                                if picker.selected_entries is None:
                                    return None
                                paths = [e.path for e in picker.selected_entries]
                                if multiple:
                                    return paths
                                else:
                                    return paths[0]
                            
                            
                            def new_button(frame, title, action):
                                btn=ui.Button()
                                btn.frame=frame
                                btn.background_color='#686868'
                                btn.tint_color='#000000'
                                btn.title=title
                                btn.action=action
                                return btn
                            
                            
                                
                                    
                            class Text_Editor:
                                def __init__(self, main, tv, text_file, *args, **kwargs):
                                    # undo/redo View
                                    self.main=main
                                    self.text_file=text_file
                                    self.active_file=None
                                    
                                    # Undo Button
                                    undo_btn=new_button(frame=(25, 2, 100, 46), title='undo', action=self.undo)
                                    main.add_subview(undo_btn)
                            
                                    # Redo Button
                                    redo_btn=new_button(frame=(127, 2, 100, 46), title='redo', action=self.redo)
                                    main.add_subview(redo_btn)
                                    
                                    # Close Button
                                    close_btn=new_button(frame=(525, 2, 100, 46), title='close', action=self.close)
                                    main.add_subview(close_btn)
                                    
                                    self.history=[]
                                    self.current_index=len(self.history)
                                    self.textview=tv
                                    self.textview_should_begin_editing(self.textview)
                            
                                def append(self, text):
                                    if self.current_index < len(self.history):
                                        self.history=self.history[:self.current_index]
                                    self.current_index=len(self.history)
                                    self.history.append(text)
                                    self.current_index+=1
                                        
                                def close(self, sender):
                                    with open(self.text_file, 'w') as f:
                                        f.writelines(self.textview.text.splitlines(keepends=True))
                                    sender.superview.close()
                                
                                def redo(self, sender):
                                    if self.current_index == len(self.history):
                                        return
                                    if self.current_index < len(self.history):
                                        self.current_index+=1
                                        self.textview.text = self.history[self.current_index-1]
                                    
                            
                                def undo(self, sender):
                                    if self.current_index == 0:
                                        return
                                    self.current_index-=1
                                    self.textview.text = self.history[self.current_index-1]
                                    
                                def textview_should_begin_editing(self, textview):
                                    return True
                            
                                def textview_did_change(self, textview):
                                    self.append(textview.text)
                            
                            class Main(ui.View):
                                def __init__(self, *args, **kwargs):
                                    text_file=None
                                    
                                    # Main Window
                                    self.width = 650
                                    self.height = 1000
                                    self.background_color="#a18967"
                                    self.update_interval=1
                            
                                    self.tv = ui.TextView(
                                        frame=(25, 50, 600, 875), background_color='#daba8b')
                                    
                                    self.file_picker=file_picker_dialog(
                                        self, x=self.width/2-250, y=self.height/2-250,
                                        file_pattern=['.txt', '.md', '.py'])
                                
                                def file_view(self):
                                    self.add_subview(
                                        FilePicker(frame=(50,100, self.width-100, self.height-200)))
                                
                                def open_file(self, child_view,  file):
                                    
                                    
                                    self.add_subview(self.tv)
                                    self.tv.delegate=Text_Editor(self, self.tv, file)
                                    with open(file, 'r') as f:
                                        for line in f:
                                            self.tv.text+=line
                            
                            if __name__ == '__main__':
                                Main().present('sheet', hide_title_bar=True)
                                                                   
                            
                            1 Reply Last reply Reply Quote 0
                            • Bumbo Cactoni
                              Bumbo Cactoni last edited by

                              @stephen
                              Yes, I am going to attempt to implement it in an app I am going to try to make.

                              stephen 1 Reply Last reply Reply Quote 0
                              • stephen
                                stephen @Bumbo Cactoni last edited by

                                @Bumbo-Cactoni said:

                                @stephen
                                Yes, I am going to attempt to implement it in an app I am going to try to make.

                                since ill probably play with it a little bit we can co-op a bit on it if you like

                                1 Reply Last reply Reply Quote 0
                                • Bumbo Cactoni
                                  Bumbo Cactoni last edited by

                                  @stephen
                                  Yes, I would like that. Right now is not a super great time, though, as I still have to finish my school year. When I am done with that (in about 10 days), I would love to co-op on it.

                                  However, I do have a question. How would I create a pushable button in Pythonista? I know tkinter doesn’t work, since it is designed for computer displays. Tkinter is really the only way I know how to create a button, so I may require some assistance.

                                  stephen mikael 3 Replies Last reply Reply Quote 0
                                  • stephen
                                    stephen @Bumbo Cactoni last edited by

                                    @Bumbo-Cactoni said:

                                    @stephen
                                    Yes, I would like that. Right now is not a super great time, though, as I still have to finish my school year. When I am done with that (in about 10 days), I would love to co-op on it.

                                    However, I do have a question. How would I create a pushable button in Pythonista? I know tkinter doesn’t work, since it is designed for computer displays. Tkinter is really the only way I know how to create a button, so I may require some assistance.

                                    do you mean creating a button within Pythonista's Editor View itself or one in a CustomView fom ui or in a scene.Node? iether way i can help you out im sure. ui has a built-in ui.Button, For Pythonista's Editor UIView we would use objc_util im sure and for scene ive alredy created own ButtonNode class that i have in my "cook book"

                                    1 Reply Last reply Reply Quote 0
                                    • mikael
                                      mikael @Bumbo Cactoni last edited by

                                      @Bumbo-Cactoni:

                                      
                                      import ui
                                      
                                      v = ui.View()
                                      
                                      btn = ui.Button(
                                          title="Push",
                                          flex='RTLB',
                                          background_color='grey',
                                          tint_color='black'
                                      )
                                      
                                      def action(sender):
                                          sender.title = 'Pushed'
                                          
                                      btn.action = action
                                      btn.width = 200
                                      btn.height = 40
                                      btn.center = (50, 50)
                                          
                                      v.add_subview(btn)
                                      v.present('fullscreen')
                                      
                                      
                                      1 Reply Last reply Reply Quote 1
                                      • mikael
                                        mikael @Bumbo Cactoni last edited by mikael

                                        @Bumbo-Cactoni, to explain the obscure part:

                                        • View v is by default initially sized at 100 x 100 pixels
                                        • So placing the button center at (50, 50) means it is in the center of the view at this point
                                        • Then, because the flex is set to ”Right Top Left Bottom”, i.e. all sides, they will scale with the view, effectively keeping the button in center when the view is presented and scaled to fill the screen
                                        • And it will continue to stay in the center if you e.g. rotate the device

                                        I think the initial size 100 x 100 was chosen at least partly so that if you want, you can think the locations of subviews as percentages.

                                        1 Reply Last reply Reply Quote 0
                                        • First post
                                          Last post
                                        Powered by NodeBB Forums | Contributors