Forum Archive

[Share Code] TableView, idea. When you need a lot of them

Phuket2

Look, this far from finished. But I am writing a menu printing application for my friend. I will need quite a few ui.TableViews. Mostly the same, with a few variants. This example, is only a few numbers. But the idea is I will assign a dict as the data. But with subclassing I hope to make the code manageable. The ui.TableView, datasource and delegate all under one roof so to speak.
Maybe it's crap, but I am sure it will work out for me.

# coding: utf-8

import ui
import uuid

class TVHandler(object):
    def __init__(self, data ):
        self.data = data 
        self.table = None

        # setup the table, no sizes, the host sizes us
        tv = ui.TableView(name = uuid.uuid1())
        tv.data_source = self
        tv.delegate = self
        self.table = tv

    # data_source methods
    def tableview_number_of_sections(self, tableview):
        # Return the number of sections (defaults to 1)
        return 1

    def tableview_number_of_rows(self, tableview, section):
        # Return the number of rows in the section
        return len(self.data)

    def tableview_cell_for_row(self, tableview, section, row):
        # Create and return a cell for the given section/row
        return self.make_cell( tableview, section, row)

    def tableview_title_for_header(self, tableview, section):
        # Return a title for the given section.
        # If this is not implemented, no section headers will be shown.
        #return 'Some Section'
        pass

    def tableview_can_delete(self, tableview, section, row):
        # Return True if the user should be able to delete the given row.
        return True

    def tableview_can_move(self, tableview, section, row):
        # Return True if a reordering control should be shown for the given row (in editing mode).
        return True

    def tableview_delete(self, tableview, section, row):
        # Called when the user confirms deletion of the given row.
        self.user_delete(tableview, section, row)

    def tableview_move_row(self, tableview, from_section, from_row, to_section, to_row):
        # Called when the user moves a row with the reordering control (in editing mode).
        data = self.data
        data[to_row], data[from_row] = data[from_row], data[to_row]
        tableview.reload()

    #delgates
    def tableview_did_select(self, tableview, section, row):
        # Called when a row was selected.
        print row, self.data[row]
        pass

    def tableview_did_deselect(self, tableview, section, row):
        # Called when a row was de-selected (in multiple selection mode).
        pass

    def tableview_title_for_delete_button(self, tableview, section, row):
        # Return the title for the 'swipe-to-***' button.
        #return 'Slet' # danish for delete
        return 'Delete'


    # if not overriden try and give some normal
    # functionality for lists
    def user_delete(self, tableview, section, row):
        print row
        self.data.pop(row)
        tableview.reload()


    # override, otherwise just give a normal cell
    def make_cell(self, tableview, section, row):
        cell = ui.TableViewCell()
        cell.text_label.text = str(self.data[row])
        return cell

    def user_select_row(self, tableview, section, row):
        print tableview, section, row

    def edit_table(self , sender):
        self.table.editing = not self.table.editing 


class SimpleTableView(TVHandler):
    def __init__(self, data):
        super(SimpleTableView, self).__init__(data)

if __name__ == '__main__':
    data = range(20)
    stv = SimpleTableView(data)
    v = ui.View(frame = (0,0,540,576))
    btn = ui.ButtonItem(title = 'Edit')
    btn.action = stv.edit_table
    v.left_button_items = [btn]
    stv.table.width, stv.table.height = v.width * .4, v.height
    v.add_subview(stv.table)
    v.present('sheet')

beer2011

Very good!
This kind of I wanted .
Thank you.

Phuket2

@beer2011 , good to hear. Not doing much other than grouping the TableViews functionality together. I am just hoping it will help tidy up my code when I start getting quite a few tables.

omz

You might want to look at subclassing ui.ListDataSource. It gives you a lot of functionality for free, e.g. animated deletion of rows, reordering, etc.

Phuket2

@omz, thanks for the idea. I will look at that. I hadn't thought about it. That's why sometimes it's worth posting something here even it's not spectacular :)

Phuket2

@omz , I have subclassed ui.ListDataSource. It is good. But you say you get reordering for free for example. Maybe I am missing something, but when I reorder or delete , nothing is being reflected in the items. The list is correct visually, but the offsets into the list items are not correct. If I override the methods and do as I did before, it works.
Just not sure if I am missing something

class SubListDataSource(ui.ListDataSource):
    def __init__(self,  data):
        super(SubListDataSource, self).__init__(data)
        self.data = data
        self.table = None

        # setup the table, no sizes, the host sizes us
        tv = ui.TableView()
        tv.data_source = self
        tv.delegate = self
        self.table = tv

        #self.edit_action = self.tableview_move_row

        self.move_enabled = True


    def edit_table(self , sender):
        self.table.editing = not self.table.editing

    def tableview_did_select(self, tableview, section, row):
        # Called when a row was selected.
        print row, self.data[row]
    '''
    def tableview_move_row(self, tableview, from_section, from_row, to_section, to_row):
        # Called when the user moves a row with the reordering control (in editing mode).
        data = self.data
        data[to_row], data[from_row] = data[from_row], data[to_row]
        #tableview.reload()
    '''

if __name__ == '__main__':
    data = range(20)
    #stv = SimpleTableView(data)
    stv = SubListDataSource(data)
    v = ui.View(frame = (0,0,540,576))
    btn = ui.ButtonItem(title = 'Edit')
    btn.action = stv.edit_table
    v.left_button_items = [btn]
    stv.table.width, stv.table.height = v.width * .4, v.height
    v.add_subview(stv.table)
    v.present('sheet')
Phuket2

@omz , sorry it's ok. I see the error of my ways. I was not accessing self.items.

class SubListDataSource(ui.ListDataSource):
    def __init__(self,  data):
        super(SubListDataSource, self).__init__(data)
        #self.data = data
        self.table = None

        # setup the table, no sizes, the host sizes us
        tv = ui.TableView()
        tv.data_source = self
        tv.delegate = self
        self.table = tv

        #self.edit_action = self.tableview_move_row

        self.move_enabled = True


    def edit_table(self , sender):
        self.table.editing = not self.table.editing

    def tableview_did_select(self, tableview, section, row):
        # Called when a row was selected.
        print row, self.items[row]
    '''
    def tableview_move_row(self, tableview, from_section, from_row, to_section, to_row):
        # Called when the user moves a row with the reordering control (in editing mode).
        data = self.data
        data[to_row], data[from_row] = data[from_row], data[to_row]
        #tableview.reload()
    '''

if __name__ == '__main__':
    data = range(20)
    #stv = SimpleTableView(data)
    stv = SubListDataSource(data)
    v = ui.View(frame = (0,0,540,576))
    btn = ui.ButtonItem(title = 'Edit')
    btn.action = stv.edit_table
    v.left_button_items = [btn]
    stv.table.width, stv.table.height = v.width * .4, v.height
    v.add_subview(stv.table)
    v.present('sheet')
Phuket2

@beer2011 , @omz was being nice with his comments. My code is a waste of time! What he suggests about subclassing ui.ListDataSource is a lot smarter