Adds Data backed table screen

This commit is contained in:
David Larrabee
2014-12-19 12:18:10 -05:00
parent f6551f9a5f
commit 36dc60f717
9 changed files with 215 additions and 2 deletions

17
app/models/contributer.rb Normal file
View File

@@ -0,0 +1,17 @@
class Contributer
# TODO: when cdq is included some events are not firing correctly.
# this works like a CDQ model, but not using CDQ right now without CDQ we can
# use create the feature we are trying to build here, but we need to sort out
# the CDQ thing
attr_accessor :name
def initialize(properties)
self.name = properties[:name]
end
def self.all
@all ||= %w{twerth squidpunch GantMan shreeve chunlea markrickert}.collect do |name|
Contributer.new(name: name)
end
end
end

View File

@@ -0,0 +1,20 @@
class ContributerScreen < PM::DataTableScreen
title "RedPotion Contributers"
refreshable
stylesheet ContributerScreenStylesheet
cell model: Contributer, scope: :all, template: {
name: :name,
cell_class: ContributerCell
}
def on_load
end
def on_refresh
end
# Remove if you are only supporting portrait
def will_animate_rotate(orientation, duration)
reapply_styles
end
end

View File

@@ -17,6 +17,10 @@ class HomeScreen < PM::Screen
open MetalTableScreen.new(nav_bar: true)
end
append(UIButton, :open_data_table_button).on(:touch) do
open ContributerScreen.new(nav_bar: true)
end
append(UIButton, :open_example_controller_button).on(:touch) do
open ExampleController
end

View File

@@ -0,0 +1,21 @@
class ContributerScreenStylesheet < ApplicationStylesheet
def root_view(st)
st.background_color = color.white
end
def cell(st)
st.background_color = color.white
end
def cell_title(st)
st.frame = {t: 5, w: device_width / 2, h: 20, l: 5}
st.background_color = color.white
st.color = color.black
end
def github_button(st)
st.text = "View profile"
st.frame = {t: 5, w: device_width / 2, h: 20, fr: 5}
st.color = color.orange
end
end

View File

@@ -23,7 +23,7 @@ class HomeScreenStylesheet < ApplicationStylesheet
end
def open_table_button(st)
st.frame = {centered: :horizontal, fb: 80, w: 200, h: 20}
st.frame = {centered: :horizontal, fb: 120, w: 200, h: 20}
st.color = color.tint
st.text = "Open table screen"
end
@@ -34,6 +34,12 @@ class HomeScreenStylesheet < ApplicationStylesheet
st.text = "Open metal table screen"
end
def open_data_table_button(st)
open_table_button st
st.frame = {bp: 10}
st.text = "Open data table screen"
end
def open_example_controller_button(st)
open_table_button st
st.frame = {bp: 10}

View File

@@ -0,0 +1,19 @@
class ContributerCell < ProMotion::TableViewCell
def on_load
apply_style :cell
find(self.contentView).tap do |q|
@title = q.append!(UILabel, :cell_title)
@button = q.append!(UIButton, :github_button)
end
end
def name=(value)
@title.text = value
# TODO: this is being called twice for each cell...
@button.off.on(:tap) do
url = NSURL.URLWithString("http://www.github.com/#{value}")
UIApplication.sharedApplication.openURL(url)
end
end
end

View File

@@ -0,0 +1,66 @@
module ProMotion
#TODO ? - set_attributes is called twice - seems like this is in PM core
# this is because we call setup when we build the cell and setup when its
# about to display - this is because PM wants styling to fire in each case -
# and properties was where the styling is done in PM
#
# if we are going to wire an event when a value is set on a cell, this could
# be problematic, especially likely since cells are reused, etc
# see my new cell for example, where I have to remove and then add events
# because of the double call
class DataTableScreen < TableScreen
def self.cell(cell)
@cell = cell
end
def self.cell_properties
@cell
end
def table_data
[{
cells: cell_data
}]
end
def cell_properties
self.class.cell_properties
end
def cell_data
return [] if cell_properties.nil?
return [] if data_model.nil?
data_model.send(data_scope).collect do |c|
{
cell_class: cell_class,
properties: properties.inject({}) do |hash, element|
hash[element.first] = c.send(element.last)
hash
end
}
end
end
private
def properties
@properties ||= cell_properties[:template].reject do |k,v|
k == :cell_class
end
end
def cell_class
@cell_class ||= cell_properties[:template][:cell_class]
end
def data_model
@data_model ||= cell_properties[:model]
end
def data_scope
@data_scope ||= cell_properties[:scope] || :all
end
end
end

View File

@@ -17,5 +17,4 @@ module ProMotion
table_cell
end
end
end

View File

@@ -0,0 +1,61 @@
describe 'DataTableScreen' do
class TestModel
attr_accessor :name
def initialize(name)
self.name = name
end
def self.all
[
new('one'),
new('two')
]
end
def self.starts_with_o
[
new('one')
]
end
end
class TestCell
def on_load
find(self.contentView).tap do |q|
@title = q.append!(UILabel)
end
end
def name=(value)
@title.text = value
end
end
class TestDataTableScreen < ProMotion::DataTableScreen
cell model: TestModel, scope: :starts_with_o, template: {
name: :name,
cell_class: TestCell
}
end
it 'should set the cell_properties value when we call DataTableScreen.cell' do
TestDataTableScreen.new.cell_properties[:model].should.equal(TestModel)
TestDataTableScreen.new.cell_properties[:scope].should.equal(:starts_with_o)
TestDataTableScreen.new.cell_properties[:template][:cell_class].should.equal(TestCell)
TestDataTableScreen.new.cell_properties[:template][:name].should.equal(:name)
end
it 'should return items that can be used to build cells from cell_data' do
TestDataTableScreen.new.cell_data.count.should.equal(1)
TestDataTableScreen.new.cell_data[0][:properties][:name].should.equal('one')
end
it 'should default the scope to all, if its not included in the cell definition' do
TestDataTableScreen.cell(model: TestModel, template: {
name: :name,
cell_class: TestCell
})
TestDataTableScreen.new.cell_data.count.should.equal(2)
TestDataTableScreen.new.cell_data[0][:properties][:name].should.equal('one')
TestDataTableScreen.new.cell_data[1][:properties][:name].should.equal('two')
end
end