• @Phuket2 said:

    Maybe global is ok to use in Python for example, but i would hate myself if I found I had too use it for some reason.

    Why? Sometimes it's perfectly ok to use it. There're other ways how to achieve your goal sometimes. Depends. Globals are here and I'm not fan of globals are evil and also not fan of globals are perfect, let's use them everywhere. Just be pragmatic and use the simplest way.

    The nonlocal seemed to make sense to me when I wanted to start to use closures and be able to interact with the outter scopes vars in a somewhat correct manner (but its possibly also considered spaghetti code, not sure) . But I have been cheating :) eg, i would add a runtime attr to an object to read and write because on not understanding these scope rules.

    In the end the only thing which matters is readability / maintainability. If it's clear what the code is doing, it's fine. Everyone has it's own style, patterns, ... Just don't be too clever or you (or others) will not understand your code after week, month, ...

    I find it a little funny how they say Python is one of the easiest languages to learn. I am sure its correct in some contexts. But the richness of the language makes it somewhat challenging in my mind.

    Yes, it's easy. The problem here is discipline. Python allows you to do everything and you have to maintain discipline to be a good citizen. And sometimes people don't maintain it, stuff brakes, ... Sometimes they have no clue why, because they didn't read documentation, ...

    C was hard, but it was fairly rigid.

    I don't consider C as hard, but I think it's harder compared to Python. Not because it's really hard itself, but because code can contain lot of pointer arithmetics, manual memory management, ... and it's unclear what it does when you look at it for the first time. Anyway it was one of my first languages (when I skip BASIC, ...), I like it and I still use it. Remember good old times with Watcom C, protected mode, ... fun without documentation & internet :)

  • Oh, btw. I might have even seen this before. Sometimes its a blur for me if I have worked something out for the first time, or if I have seen it before. I have looked at dialogs before, but it was a long time ago. Good chance i would not have understood what it was doing anyway. But I think its a good idea to go and re-look with fresh eyes and mind. Learn some new things

  • Ok, I did a few updates to make it more useful. Not that it is really that useful unless you need it at runtime as Pythonista has the same but better built fonts picker in in the asset picker.
    But this just shows how hoist the original Custom ui.View Class and place it in another ui.View Custom Class. There is not much happing to make this work, the bulk of the extra lines are creating the views.
    One think I would point out though is that this example is size and orientation friendly. I am finally getting my head around the flex attr from the ui Module. I still sometimes slip up, but it's actually very easy. Shame on me, to take so long to get it. It's designed very well. I just suffer old mans syndrome sometimes. I mention that, because I don't think it's obscure, my brain was just working against myself.
    Anyway, I try to write anything that is not size and orientation friendly anymore. There is no need. And the more you do it, the more natural it is.

    Anyway, below is the update. Pythonista's filter seems to be the same as what I do, but @omz hilites the substring. Also, I am copying the font name to the clipboard where as the asset picker copies the font name into the editor. It's not difficult to do, just decided to copy to the clipboard.

    Again, I am not saying the below is the best way to do things. I am still a beginner. Just saying it's one way.

    # Pythonista Forum - @Phuket2 import ui, clipboard, console from objc_util import * def get_font_list(): # updated version from @dgelessus UIFont = ObjCClass('UIFont') lst = [str(font) for family in UIFont.familyNames() for font in UIFont.fontNamesForFamilyName_(family)] lst.sort() return lst class SimpleListView(ui.View): def __init__(self, items, *args, **kwargs): super().__init__(*args, **kwargs) self.tbl = None self.value = None self.flex = 'wh' self.make_view(items) def make_view(self, items): tbl = ui.TableView(frame=self.bounds) tbl.flex = 'wh' tbl.data_source = tbl.delegate = ui.ListDataSource(items) tbl.data_source.tableview_cell_for_row =\ self.tableview_cell_for_row self.tbl = tbl self.add_subview(tbl) def tableview_cell_for_row(self, tableview, section, row): # Create and return a cell for the given section/row cell = ui.TableViewCell() data = tableview.data_source.items[row] cell.text_label.text = data cell.text_label.font = (data, 16) return cell class FontViewer(ui.View): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.data = get_font_list() self.tbl = None self.bg_color = 'darkgray' self.flex = 'wh' self.name_str = self.name if self.name else 'Fonts' self.make_view(**kwargs) self.update_name() def make_view(self, **kwargs): # make the containing view margin = kwargs.pop('margin', (0, 0)) cv = ui.View(frame=self.bounds.inset(*margin)) cv.flex = 'wh' # make the search view sv = ui.View(frame=cv.bounds) sv.height = 32 tv = ui.TextField(frame=sv.bounds) tv.placeholder = 'search' tv.clear_button_mode = 'always' tv.autocapitalization_type = ui.AUTOCAPITALIZE_NONE tv.autocorrection_type = False tv.delegate = self tv.flex = 'wh' sv.add_subview(tv) sv.flex = 'w' cv.add_subview(sv) # make the list view lv = ui.View(frame=sv.frame) lv.height = cv.height - sv.frame.max_y - 5 lv.y = sv.frame.max_y + 5 lv.corner_radius = 6 lv.flex = 'wh' cv.add_subview(lv) # create the list slv = SimpleListView(self.data, frame=f) self.tbl = slv.tbl # redirect the action to this class. self.tbl.data_source.action = self.list_action lv.add_subview(slv) self.add_subview(cv) def textfield_did_change(self, textfield): self.filter_data(textfield.text) def filter_data(self, filter_txt): # real poor mans filter. just doing an in-string search to match # but its case insensitive. for this data seems reasonable. txt = filter_txt.lower() # ui.ListDataSource updates itself when the items are changed self.tbl.data_source.items = [item for item in self.data if txt in item.lower()] self.update_name() def update_name(self): self.name = '{} - ({})'.format(self.name_str, len(self.tbl.data_source.items)) def list_action(self, sender): # when a list item is clicked self.value = sender.items[sender.selected_row] clipboard.set(self.value) console.hud_alert('{} - copied'.format(self.value)) self.close() if __name__ == '__main__': w, h = 400, 800 style = 'popover' if style == 'popover': h = ui.get_screen_size()[1] * .6 f = (0, 0, w, h) fv = FontViewer(name='The Fonts', frame=f, margin=(5, 5)) fv.present(style=style)
  • @ccc
    That's cool! I don't remember how I saw this faker module- maybe just looking at the pythonista docs as it's listed as a third party module. Sure is useful though!

  • there was a discussion about adding a custom rowheight, but the idea is the same. you swizzle the tableview class to add the extra delegate calls.

    See https://github.com/jsbain/objc_hacks

    and rowheight_example

    you will also need the swizzle.py.

  • Hmmm, well should have done
    tv.bounces = False
    Also should have also implemented def layout(self) for MyClass.
    I am sure many other things also
    But was just more to give an idea. No one said anything , I just thought I should have been more clear.

  • @Sebastian 👍, don't forget to try out the other 2 'value1' and 'value2', gives you different cell layouts

  • Well, I was a little hasty about my comment about the data does not matter. tuples can not be updated, well at least in place anyway. So my statement was wrong. It does matter. Depends on what you need to do with your data. Tail between my legs again:)

Internal error.

Oops! Looks like something went wrong!