From 542a84c6565e5dd48d1a87890fb23e6ada72b7f8 Mon Sep 17 00:00:00 2001 From: atanasster Date: Sat, 30 Nov 2013 19:35:51 -0500 Subject: [PATCH 01/55] added support for shape (currently rounded rectangle) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit usage : local button = widgetExt:newButton( { x = xButton, y = yButton, width = buttonsWidth, height = buttonsHeight, labelAlign = “center”, labelAlignY = “center”, shape = { cornerRadius = 10, strokeWidth = 2, strokeColor = {default = {0.5,0.5,0.5,1}, over = {0,0,0,1}}, fillColor = {default = {0.8,0.9,0.8,1}, over = {0.6,0.7,0.6,1}}, }, labelColor = { default=myApp.textButtonColor, over= myApp.textOverColor }, onRelease = onRelease, label = btn.caption, font = myApp.font; fontSize = fontSizeButtons, onRelease = onRelease, }); --- widgetLibrary/widget_button.lua | 128 ++++++++++++++++++++++++++------ widgetLibrary/widgetext.lua | 57 ++++++++++++++ 2 files changed, 163 insertions(+), 22 deletions(-) create mode 100644 widgetLibrary/widgetext.lua diff --git a/widgetLibrary/widget_button.lua b/widgetLibrary/widget_button.lua index 3711eb9..8e10438 100755 --- a/widgetLibrary/widget_button.lua +++ b/widgetLibrary/widget_button.lua @@ -46,6 +46,20 @@ else buttonDefault = { default = { 0, 0, 0 }, over = { 1, 1, 1 } } end +local shapeStrokeDefault; +if isGraphicsV1 then + shapeStrokeDefault = { default = { 0, 0, 0 }, over = { 0, 0, 0 } } +else + shapeStrokeDefault = { default = { 0, 0, 0 }, over = { 0, 0, 0 } } +end + +local shapeFillDefault; +if isGraphicsV1 then + shapeFillDefault = { default = { 204, 204, 204 }, over = { 153, 153, 153} } +else + shapeFillDefault = { default = { 0.8, 0.8, 0.8 }, over = { 0.6, 0.6, 0.6 } } +end + -- Function to handle touches on a widget button, function is common to all widget button creation types (ie image files, imagesheet, and 9 slice button creation) local function manageButtonTouch( view, event ) local phase = event.phase @@ -139,30 +153,68 @@ end -- Text only button ------------------------------------------------------------------------ local function createUsingText( button, options ) + -- Create a local reference to our options table local opt = options -- Forward references local view - + + local rect = nil; + local shape = opt.shape; + if shape then + + rect = display.newRoundedRect( button, button.x, button.y, opt.width , opt.height , shape.cornerRadius); + rect.strokeWidth = shape.strokeWidth or 1; + rect:setStrokeColor(unpack(shape.strokeColor.default)); + rect:setFillColor(unpack(shape.fillColor.default)); + end + local viewLabel; + -- Create the label (either embossed or standard) if opt.embossedLabel then - view = display.newEmbossedText( button, opt.label, 0, 0, opt.font, opt.fontSize ) + viewLabel = display.newEmbossedText( button, opt.label, 0, 0, opt.font, opt.fontSize ) else - view = display.newText( button, opt.label, 0, 0, opt.font, opt.fontSize ) + viewLabel = display.newText( button, opt.label, 0, 0, opt.font, opt.fontSize ) end + if rect then + view = rect; + view._shapeColor = shape.fillColor; + view._strokeColor = shape.strokeColor; + view._label = viewLabel; + + else + view = viewLabel; + end -- Set the view's color - view:setFillColor( unpack( opt.labelColor.default ) ) + viewLabel:setFillColor( unpack( opt.labelColor.default ) ) view._labelColor = opt.labelColor ---------------------------------- -- Positioning ---------------------------------- - -- The view - view.x = button.x + ( view.contentWidth * 0.5 ) - view.y = button.y + ( view.contentHeight * 0.5 ) + -- Labels position + if "center" == opt.labelAlign then + viewLabel.x = view.x + opt.labelXOffset + elseif "left" == opt.labelAlign then + viewLabel.x = view.x - ( view.contentWidth * 0.5 ) + ( viewLabel.contentWidth * 0.5 ) + opt.labelXOffset + elseif "right" == opt.labelAlign then + viewLabel.x = view.x + ( view.contentWidth * 0.5 ) - ( viewLabel.contentWidth * 0.5 ) + opt.labelXOffset + end + + + if "center" == opt.labelAlignY then + viewLabel.y = view.y + opt.labelYOffset + elseif "top" == opt.labelAlignY then + viewLabel.y = view.y - ( view.contentHeight * 0.5 ) + ( viewLabel.contentHeight * 0.5 ) + opt.labelYOffset + elseif "bottom" == opt.labelAlignY then + + viewLabel.y = view.y + ( view.contentHeight * 0.5 ) - ( viewLabel.contentHeight * 0.5 ) + opt.labelYOffset + end + + ------------------------------------------------------- -- Assign properties/objects to the view @@ -170,8 +222,8 @@ local function createUsingText( button, options ) view._isEnabled = opt.isEnabled view._pressedState = "default" - view._fontSize = opt.fontSize - view._labelColor = view._labelColor + viewLabel._fontSize = opt.fontSize + viewLabel._labelColor = view._labelColor -- Methods view._onPress = opt.onPress @@ -191,7 +243,11 @@ local function createUsingText( button, options ) -- Function to set the buttons text color function button:setFillColor( ... ) - self._view:setFillColor( ... ) + if self._label then + self._view._label:setFillColor( ... ) + else + self._view:setFillColor( ... ) + end; end -- Function to set the button's label @@ -219,9 +275,11 @@ local function createUsingText( button, options ) return true end + + view:addEventListener( "touch" ) - + ---------------------------------------------------------- -- PRIVATE METHODS ---------------------------------------------------------- @@ -229,8 +287,12 @@ local function createUsingText( button, options ) -- Function to set the button's label function view:_setLabel( newLabel ) -- Update the label's text - if "function" == type( self.setText ) then - self:setText( newLabel ) + if "function" == type( self.setText ) or self._label then + if self._label then + self._label:setText( newLabel ) + else + self:setText( newLabel ) + end else self.text = newLabel end @@ -238,17 +300,22 @@ local function createUsingText( button, options ) -- Function to get the button's label function view:_getLabel() - return self._label.text + return self._label.text end -- Function to set the buttons current state function view:_setState( state ) local newState = state - - if "over" == newState then + if "over" == newState then -- Set the label to it's over color if "table" == type( self ) then - self:setFillColor( unpack( self._labelColor.over ) ) + if self._label then + self:setFillColor( unpack( self._shapeColor.over ) ); + self:setStrokeColor(unpack( self._strokeColor.over ) ); + self._label:setFillColor( unpack( self._labelColor.over ) ) + else + self:setFillColor( unpack( self._labelColor.over ) ) + end end -- The pressedState is now "over" @@ -256,8 +323,15 @@ local function createUsingText( button, options ) elseif "default" == newState then -- Set the label back to it's default color + if "table" == type( self ) then - self:setFillColor( unpack( self._labelColor.default ) ) + if self._label then + self:setFillColor( unpack( self._shapeColor.default ) ) + self:setStrokeColor(unpack( self._strokeColor.default ) ); + self._label:setFillColor( unpack( self._labelColor.default ) ) + else + self:setFillColor( unpack( self._labelColor.default ) ) + end end -- The pressedState is now "default" @@ -1248,12 +1322,23 @@ function M.new( options, theme ) end opt.labelAlign = customOptions.labelAlign or "center" + opt.labelAlignY = customOptions.labelAlignY or "center" + opt.labelXOffset = customOptions.labelXOffset or 0 opt.labelYOffset = customOptions.labelYOffset or 0 opt.embossedLabel = customOptions.emboss or themeOptions.emboss or false opt.isEnabled = customOptions.isEnabled + opt.textOnlyButton = customOptions.textOnly or false - + opt.shape = customOptions.shape or nil; + if opt.shape then + + opt.shape.cornerRadius = opt.shape.cornerRadius or 0; + opt.shape.strokeWidth = opt.shape.strokeWidth or 1; + opt.shape.strokeColor = opt.shape.strokeColor or shapeStrokeDefault; + opt.shape.fillColor = opt.shape.fillColor or shapeFillDefault; + end; + -- If the user didn't pass in a isEnabled flag, set it to true if nil == opt.isEnabled then opt.isEnabled = true @@ -1306,7 +1391,7 @@ function M.new( options, theme ) opt.bottomMiddleOverFrame = customOptions.bottomMiddleOverFrame or _widget._getFrameIndex( themeOptions, themeOptions.bottomMiddleOverFrame ) -- Are we using a nine piece button? - local using9PieceButton = not opt.defaultFrame and not opt.overFrame and not opt.defaultFile and not opt.overFile and not opt.textOnlyButton and opt.topLeftFrame and opt.topLeftOverFrame and opt.middleLeftFrame and opt.middleLeftOverFrame and opt.bottomLeftFrame and opt.bottomLeftOverFrame and + local using9PieceButton = not opt.defaultFrame and not opt.overFrame and not opt.defaultFile and not opt.overFile and not opt.textOnlyButton and not opt.shape and opt.topLeftFrame and opt.topLeftOverFrame and opt.middleLeftFrame and opt.middleLeftOverFrame and opt.bottomLeftFrame and opt.bottomLeftOverFrame and opt.topRightFrame and opt.topRightOverFrame and opt.middleRightFrame and opt.middleRightOverFrame and opt.bottomRightFrame and opt.bottomRightOverFrame and opt.topMiddleFrame and opt.topMiddleOverFrame and opt.middleFrame and opt.middleOverFrame and opt.bottomMiddleFrame and opt.bottomMiddleOverFrame @@ -1383,7 +1468,6 @@ function M.new( options, theme ) baseDir = opt.baseDir, widgetType = "button", } - -- Create the button if using9PieceButton then -- If we are using a 9 piece button @@ -1400,7 +1484,7 @@ function M.new( options, theme ) end -- Text only button - if opt.textOnlyButton then + if opt.textOnlyButton or opt.shape then createUsingText( button, opt ) end end diff --git a/widgetLibrary/widgetext.lua b/widgetLibrary/widgetext.lua new file mode 100644 index 0000000..8a565fb --- /dev/null +++ b/widgetLibrary/widgetext.lua @@ -0,0 +1,57 @@ +local widget = require("widget"); +local widgetExt = {}; + +-- Function to retrieve a widget's theme settings +local function _getTheme( widgetTheme, options ) +local widgetExt = {}; + + local theme = nil + + -- If a theme has been set + if widget.theme then + theme = widget.theme[widgetTheme] + end + + -- If a theme exists + if theme then + -- Style parameter optionally set by user + if options and options.style then + local style = theme[options.style] + + -- For themes that support various "styles" per widget + if style then + theme = style + end + end + end + + return theme +end + + +function widgetExt:newPanel( options ) + local theme = _getTheme( "panel", options ); + if theme == nil then + --if the current theme does not have a panel, revert to button + theme = _getTheme( "button", options ) + end; + local _panel = require( "widgets.widget_panel" ) + return _panel.new( options, theme ) +end + + +function widgetExt:newButton( options ) + local theme = _getTheme( "button", options ) + + local _button = require( "widgets.widget_button" ) + return _button.new( options, theme ) +end + +function widgetExt:newPageSlider( options ) + local theme = _getTheme( "pageslider", options ) + + local _pageslider = require( "widgets.widget_pageslider" ) + return _pageslider.new( options, theme ) +end + +return widgetExt; From fe2c88709dad819d88ab8cbad985e1942bad2a5a Mon Sep 17 00:00:00 2001 From: atanasster Date: Mon, 2 Dec 2013 19:48:14 -0500 Subject: [PATCH 02/55] added public newSegmentedControl:setDefaultSegment(segNum) allow user to change the default segment after the control has been constructed :setDefaultSegment() --- widgetLibrary/widget_segmentedControl.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) mode change 100644 => 100755 widgetLibrary/widget_segmentedControl.lua diff --git a/widgetLibrary/widget_segmentedControl.lua b/widgetLibrary/widget_segmentedControl.lua old mode 100644 new mode 100755 index 8360add..fd5b183 --- a/widgetLibrary/widget_segmentedControl.lua +++ b/widgetLibrary/widget_segmentedControl.lua @@ -420,14 +420,15 @@ local function initWithImage( segmentedControl, options ) end -- Set the intial segment to active - local function setDefaultSegment( segmentNum ) + function segmentedControl:setDefaultSegment( segmentNum ) if 1 == segmentNum then view:setLeftSegmentActive() elseif #segments == segmentNum then view:setRightSegmentActive() else - view:setMiddleSegmentActive( view._segmentNumber ) + view:setMiddleSegmentActive( segmentNum ) end + view._segmentNumber = segmentNum; end -- Finalize function for the segmentedControl @@ -440,7 +441,7 @@ local function initWithImage( segmentedControl, options ) end -- Set the default segment - setDefaultSegment( view._segmentNumber ) + segmentedControl:setDefaultSegment( view._segmentNumber ) return segmentedControl end From 58d63546a5065945351aa7b6fe72878860011449 Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 4 Dec 2013 03:26:11 -0500 Subject: [PATCH 03/55] Embossed Label shows for all custom themes An embossed label is displayed for all themes except ios7. This change ads an option labelNotEmbossed to prevent this --- widgetLibrary/widget_segmentedControl.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/widgetLibrary/widget_segmentedControl.lua b/widgetLibrary/widget_segmentedControl.lua index fd5b183..9baff2b 100755 --- a/widgetLibrary/widget_segmentedControl.lua +++ b/widgetLibrary/widget_segmentedControl.lua @@ -67,9 +67,11 @@ local function initWithImage( segmentedControl, options ) -- The view is the segmentedControl (group) view = segmentedControl + + view._segmentWidth = M.segmentWidth view._labelColor = opt.labelColor - + -- Create the sequenceData table local leftSegmentOptions = { @@ -174,7 +176,7 @@ local function initWithImage( segmentedControl, options ) for i = 1, #segments do -- Create the labels local label - if _widget.isSeven() then + if (opt.labelNotEmbossed == true) or _widget.isSeven() then label = display.newText( segmentedControl, segments[i], 0, 0, opt.labelFont, opt.labelSize ) if view._segmentNumber == i or opt.defaultSegment == i then label:setFillColor( unpack( view._labelColor.over ) ) @@ -479,6 +481,7 @@ function M.new( options, theme ) opt.defaultSegment = customOptions.defaultSegment or 1 opt.labelSize = customOptions.labelSize or 12 opt.labelFont = customOptions.labelFont or native.systemFont + opt.labelNotEmbossed = customOptions.labelNotEmbossed or false; -- TODO: document this in the API opt.labelColor = customOptions.labelColor or themeOptions.labelColor or buttonDefault @@ -526,12 +529,13 @@ function M.new( options, theme ) end local x, y = opt.x, opt.y - if not opt.x or not opt.y then + if (not opt.x) or (not opt.y) then x = opt.left + segmentedControl.contentWidth * 0.5 y = opt.top + segmentedControl.contentHeight * 0.5 end segmentedControl.x, segmentedControl.y = x, y - + + return segmentedControl end From 09cec0fb3477e8b882c6ce40f9967caa8ad5da87 Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 4 Dec 2013 05:08:13 -0500 Subject: [PATCH 04/55] Custom themes for the segmented control id not honor the label color if the control is created with a custom theme, when the touch event is processed, it checks for the current theme (if its ios7). The problem was with the default and over colors - if the current theme is not ios7, the control did not change the label colors. If it was ios7, it always changed the over color to white --- widgetLibrary/widget_segmentedControl.lua | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/widgetLibrary/widget_segmentedControl.lua b/widgetLibrary/widget_segmentedControl.lua index 9baff2b..c76c220 100755 --- a/widgetLibrary/widget_segmentedControl.lua +++ b/widgetLibrary/widget_segmentedControl.lua @@ -71,6 +71,8 @@ local function initWithImage( segmentedControl, options ) view._segmentWidth = M.segmentWidth view._labelColor = opt.labelColor + view._isSeven = _widget.isSeven() + view._labelNotEmbossed = opt.labelNotEmbossed -- Create the sequenceData table local leftSegmentOptions = @@ -176,7 +178,7 @@ local function initWithImage( segmentedControl, options ) for i = 1, #segments do -- Create the labels local label - if (opt.labelNotEmbossed == true) or _widget.isSeven() then + if (view._labelNotEmbossed == true) or view._isSeven then label = display.newText( segmentedControl, segments[i], 0, 0, opt.labelFont, opt.labelSize ) if view._segmentNumber == i or opt.defaultSegment == i then label:setFillColor( unpack( view._labelColor.over ) ) @@ -349,13 +351,13 @@ local function initWithImage( segmentedControl, options ) self._segmentNumber = 1 -- Reset the colors if ios7 - if _widget.isSeven() then + if self._labelNotEmbossed == true or self._isSeven then for i = 1, #view._segmentLabels do local currentSegment = view._segmentLabels[ i ] - currentSegment:setFillColor( unpack( view._labelColor.default ) ) + currentSegment:setFillColor( unpack( self._labelColor.default ) ) end - view._segmentLabels[1]:setFillColor( unpack( whiteColor ) ) + view._segmentLabels[1]:setFillColor( unpack( self._labelColor.over ) ) end @@ -379,13 +381,13 @@ local function initWithImage( segmentedControl, options ) self._segmentNumber = self._totalSegments -- Reset the colors if ios7 - if _widget.isSeven() then + if self._labelNotEmbossed == true or self._isSeven then for i = 1, #view._segmentLabels do local currentSegment = view._segmentLabels[ i ] - currentSegment:setFillColor( unpack( view._labelColor.default ) ) + currentSegment:setFillColor( unpack( self._labelColor.default ) ) end - view._segmentLabels[ #view._segmentLabels ]:setFillColor( unpack( whiteColor ) ) + view._segmentLabels[ #view._segmentLabels ]:setFillColor( unpack( self._labelColor.over ) ) end @@ -409,13 +411,13 @@ local function initWithImage( segmentedControl, options ) self._segmentNumber = segmentNum -- Reset the colors if ios7 - if _widget.isSeven() then + if self._labelNotEmbossed == true or self._isSeven then for i = 1, #view._segmentLabels do local currentSegment = view._segmentLabels[ i ] - currentSegment:setFillColor( unpack( view._labelColor.default ) ) + currentSegment:setFillColor( unpack( self._labelColor.default ) ) end - view._segmentLabels[ segmentNum ]:setFillColor( unpack( whiteColor ) ) + view._segmentLabels[ segmentNum ]:setFillColor( unpack( self._labelColor.over ) ) end From aa14082c0b124cd228baaeac64fe9accc2f6ab2a Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 18 Dec 2013 14:31:52 -0500 Subject: [PATCH 05/55] pickerwheel columnColor default --- widgetLibrary/widget_pickerWheel.lua | 9 +- widgetLibrary/widgetext.lua | 179 +++++++++++++++++++-------- 2 files changed, 131 insertions(+), 57 deletions(-) diff --git a/widgetLibrary/widget_pickerWheel.lua b/widgetLibrary/widget_pickerWheel.lua index 75dcb4e..928fadd 100644 --- a/widgetLibrary/widget_pickerWheel.lua +++ b/widgetLibrary/widget_pickerWheel.lua @@ -249,13 +249,14 @@ local function createPickerWheel( pickerWheel, options ) for j = 1, #opt.columnData[i].labels do viewColumns[i]:insertRow { - rowHeight = 40, + rowHeight = opt.rowHeight, rowColor = { - default = defaultRowColor, - over = defaultRowColor, + default = opt.columnColor, + over = opt.columnColor, }, label = opt.columnData[i].labels[j], - id = i + id = i, + lineColor = opt.columnColor, } end diff --git a/widgetLibrary/widgetext.lua b/widgetLibrary/widgetext.lua index 8a565fb..1e8dd56 100644 --- a/widgetLibrary/widgetext.lua +++ b/widgetLibrary/widgetext.lua @@ -1,57 +1,130 @@ local widget = require("widget"); -local widgetExt = {}; -- Function to retrieve a widget's theme settings local function _getTheme( widgetTheme, options ) -local widgetExt = {}; - - local theme = nil - - -- If a theme has been set - if widget.theme then - theme = widget.theme[widgetTheme] - end - - -- If a theme exists - if theme then - -- Style parameter optionally set by user - if options and options.style then - local style = theme[options.style] - - -- For themes that support various "styles" per widget - if style then - theme = style - end - end - end - - return theme -end - - -function widgetExt:newPanel( options ) - local theme = _getTheme( "panel", options ); - if theme == nil then - --if the current theme does not have a panel, revert to button - theme = _getTheme( "button", options ) - end; - local _panel = require( "widgets.widget_panel" ) - return _panel.new( options, theme ) -end - - -function widgetExt:newButton( options ) - local theme = _getTheme( "button", options ) - - local _button = require( "widgets.widget_button" ) - return _button.new( options, theme ) -end - -function widgetExt:newPageSlider( options ) - local theme = _getTheme( "pageslider", options ) - - local _pageslider = require( "widgets.widget_pageslider" ) - return _pageslider.new( options, theme ) -end - -return widgetExt; + local theme = nil + + -- If a theme has been set + if widget.theme then + theme = widget.theme[widgetTheme] + end + + -- If a theme exists + if theme then + -- Style parameter optionally set by user + if options and options.style then + local style = theme[options.style] + + -- For themes that support various "styles" per widget + if style then + theme = style + end + end + end + + return theme +end + + +-- Check if the theme is ios7 +local function isSeven() + return widget.themeName ~= "widget_theme_android" and + widget.themeName ~= "widget_theme_ios"; +end + +--widget.isSeven = isSeven; + +local function newPanel( options ) + local theme = _getTheme( "panel", options ); + if theme == nil then + --if the current theme does not have a panel, revert to button + theme = _getTheme( "button", options ) + end; + local _panel = require( "widgets.widget_panel" ) + return _panel.new( options, theme ) +end + +widget.newPanel = newPanel; + +local function newButton( options ) + local theme = _getTheme( "button", options ) + + local _button = require( "widgets.widget_button" ) + return _button.new( options, theme ) +end + +widget.newButton = newButton; + + +local function newPageSlider( options ) + local theme = _getTheme( "pageslider", options ) + + local _pageslider = require( "widgets.widget_pageslider" ) + return _pageslider.new( options, theme ) +end + +widget.newPageSlider = newPageSlider; + +local function newEditField( options ) + local theme = _getTheme( "editField", options ); + if theme == nil then + --if the current theme does not have a editfield, revert to searchfield + theme = _getTheme( "searchField", options ) + end; + local _editField = require( "widgets.widget_editfield" ) + return _editField.new( options, theme ) +end + +widget.newEditField = newEditField; + +local function newSegmentedControl( options ) + local theme = _getTheme( "segmentedControl", options ) + local _segmentedControl = require( "widgets.widget_segmentedControl" ) + return _segmentedControl.new( options, theme ) +end + +widget.newSegmentedControl = newSegmentedControl; + + +----------------------------------------------------------------------------------------- +-- newTableView widget +----------------------------------------------------------------------------------------- +local old_newTableView = nil; +local function newTableView( options ) + local _tableView = require( "widgets.widget_tableviewext" ) + return _tableView.new(old_newTableView, options ) +end + +if old_newTableView ~= widget.newTableView then + old_newTableView = widget.newTableView; +end +widget.newTableView = newTableView; + + +local old_newScrollView = nil; +local function newScrollView( options ) + local _scrollView = require( "widgets.widget_scrollviewext" ) + return _scrollView.new(old_newScrollView, options ) +end + +if old_newScrollView ~= widget.newScrollView then + old_newScrollView = widget.newScrollView; +end +widget.newScrollView = newScrollView; + + +local function newSwitch( options ) + local theme = _getTheme( "switch", options ) + local _switch = require( "widgets.widget_switch" ) + return _switch.new( options , theme) +end +widget.newSwitch = newSwitch; + + +function newPickerWheel( options ) + local theme = _getTheme( "pickerWheel", options ) + local _pickerWheel = require( "widgets.widget_pickerWheel" ) + return _pickerWheel.new( options, theme ) +end +widget.newPickerWheel = newPickerWheel; + From 5fdcfa5adfbe6ce4ebcc6d31ab1e851cc4aff08e Mon Sep 17 00:00:00 2001 From: atanasster Date: Thu, 19 Dec 2013 08:30:45 -0500 Subject: [PATCH 06/55] added onScroll event onScroll event added to pickerWheel so user can track changes in the selection and update screen in real time --- widgetLibrary/widget_pickerWheel.lua | 856 ++++++++++++++------------- 1 file changed, 433 insertions(+), 423 deletions(-) diff --git a/widgetLibrary/widget_pickerWheel.lua b/widgetLibrary/widget_pickerWheel.lua index 928fadd..a79e5fa 100644 --- a/widgetLibrary/widget_pickerWheel.lua +++ b/widgetLibrary/widget_pickerWheel.lua @@ -28,8 +28,8 @@ local M = { - _options = {}, - _widgetName = "widget.newPickerWheel", + _options = {}, + _widgetName = "widget.newPickerWheel", } -- Require needed widget files @@ -42,437 +42,447 @@ local defaultRowColor = { 1 } local blackColor = { 0 } if isGraphicsV1 then - _widget._convertColorToV1( labelColor ) - _widget._convertColorToV1( defaultRowColor ) - _widget._convertColorToV1( blackColor ) + _widget._convertColorToV1( labelColor ) + _widget._convertColorToV1( defaultRowColor ) + _widget._convertColorToV1( blackColor ) end -- Creates a new pickerWheel local function createPickerWheel( pickerWheel, options ) - -- Create a local reference to our options table - local opt = options + -- Create a local reference to our options table + local opt = options + + -- Forward references + local imageSheet, view, viewBackground, viewOverlay, viewColumns + + -- Create the imageSheet + if opt.sheet then + imageSheet = opt.sheet + else + local themeData = require( opt.themeData ) + imageSheet = graphics.newImageSheet( opt.themeSheetFile, themeData:getSheet() ) + end + + -- Create the view + view = display.newGroup() + + -- The view's background + viewOverlay = display.newImageRect( pickerWheel, imageSheet, opt.overlayFrame, opt.overlayFrameWidth, opt.overlayFrameHeight ) + + ---------------------------------- + -- Properties + ---------------------------------- + + -- The table which holds our pickerWheel columns + viewColumns = {} + + ------------------------------------------------------- + -- Assign properties to the view + ------------------------------------------------------- + + -- Assign properties to our view + view._width = opt.overlayFrameWidth + view._height = opt.overlayFrameHeight + view._top = opt.top + view._yPosition = pickerWheel.y + ( view._height * 0.5 ) + + -- Assign objects to our view + view._overlay = viewOverlay + view._background = viewBackground + view._columns = viewColumns + view._didTap = false + if "function" == type(opt.onScroll) then + view._onScroll = opt.onScroll; + end; + + ------------------------------------------------------- + -- Assign properties/objects to the pickerWheel + ------------------------------------------------------- + + -- Assign objects to the pickerWheel + pickerWheel._imageSheet = imageSheet + pickerWheel._view = view + pickerWheel:insert( view ) + + -- Function to render the pickerWheels columns + local function _renderColumns( event ) + local phase = event.phase + local row = event.row + local fontSize = event.target._fontSize + local alignment = event.target._align + + -- Create the column's title text + local rowTitle = display.newText( row, row._label, 0, 0, opt.font, fontSize ) + rowTitle.y = row.contentHeight * 0.5 + + if _widget.isSeven() and row.index == pickerWheel._view._columns[row.id]._values.index then + rowTitle:setFillColor( 0 ) + else + rowTitle:setFillColor( unpack( opt.fontColor ) ) + end + + row.value = rowTitle.text + + -- check if the text is greater than the actual column size + local availableWidth = viewOverlay.width - 28 + local columnWidth = view._columns[ row.id ].width or availableWidth / #view._columns + local textWidth = rowTitle.contentWidth + if textWidth > columnWidth - 1 then + --cap the text + local pixelsPerChar = 23 -- aproximate median value + local numChars = columnWidth / pixelsPerChar + row._label = row._label:sub(1, numChars) + rowTitle.text = row._label + + end + + -- Align the text as requested + if "center" == alignment then + + local rowTitleX + if isGraphicsV1 then + rowTitleX = row.x + else + rowTitleX = row.x + columnWidth * 0.5 + end + rowTitle.x = rowTitleX + + elseif "left" == alignment then + + local rowTitleX + if isGraphicsV1 then + rowTitleX = ( rowTitle.contentWidth * 0.5 ) + 6 + else + rowTitleX = row.x + 6 + rowTitle.anchorX = 0 + end + rowTitle.x = rowTitleX + + elseif "right" == alignment then + + local rowTitleX + if isGraphicsV1 then + rowTitleX = row.x + ( row.contentWidth * 0.5 ) - ( rowTitle.contentWidth * 0.5 ) - 6 + else + rowTitleX = row.x + columnWidth - 6 + rowTitle.anchorX = 1 + end + rowTitle.x = rowTitleX + + end + + + end + + -- Create a background to sit behind the pickerWheel + viewBackground = display.newImageRect( view, imageSheet, opt.backgroundFrame, opt.overlayFrameWidth, opt.overlayFrameHeight ) + viewBackground.x = viewOverlay.x + viewBackground.y = viewOverlay.y + + -- Function to create the column seperator + function view:_createSeperator( x ) + local seperator = display.newImageRect( self, imageSheet, opt.seperatorFrame, opt.seperatorFrameWidth + 4, opt.backgroundFrameHeight ) + seperator.x = x + + return seperator + end + + -- The available width for the whole pickerWheel (to fit columns) + local availableWidth = viewOverlay.width - 28 + + -- local method that handles scrolling to the tapped / touched index + local function didTapValue( event ) + local phase = event.phase + local row = event.target + if "tap" == phase or "release" == phase then + view._columns[ row.id ]:scrollToIndex( row.index ) + view._didTap = true + end + end + + -- Create the pickerWheel Columns (which are tableView's) + local topPadding = 84 + local bottomPadding = 96 + if isGraphicsV1 then + topPadding = 90 + bottomPadding = 92 + end + + local initialX = 0 + local initialPos = - 144 + + for i = 1, #opt.columnData do + + if i > 1 then + initialPos = viewColumns[i-1].x + viewColumns[i-1]._view._width * 0.5 + end + + viewColumns[i] = _widget.newTableView + { + left = initialPos, + top = -110, + width = opt.columnData[i].width or availableWidth / #opt.columnData, + height = opt.overlayFrameHeight - 1, + topPadding = topPadding, + bottomPadding = bottomPadding, + noLines = true, + hideBackground = true, + hideScrollBar = true, + friction = 0.92, + rowColor = opt.columnColor, + onRowRender = _renderColumns, + maskFile = opt.maskFile, + listener = nil, + onRowTouch = didTapValue + } + viewColumns[i]._view._isUsedInPickerWheel = true + + -- Column properties + viewColumns[i]._align = opt.columnData[i].align + viewColumns[i]._fontSize = opt.fontSize + + -- Set the volumns initial values + viewColumns[i]._values = + { + index = opt.columnData[i].startIndex, + value = opt.columnData[i].labels[opt.columnData[i].startIndex], + } + + -- Create the columns row's + for j = 1, #opt.columnData[i].labels do + viewColumns[i]:insertRow + { + rowHeight = opt.rowHeight, + rowColor = { + default = opt.columnColor, + over = opt.columnColor, + }, + label = opt.columnData[i].labels[j], + id = i, + lineColor = opt.columnColor, + } + end + + -- Insert the pickerWheel column into the view + view:insert( viewColumns[i] ) - -- Forward references - local imageSheet, view, viewBackground, viewOverlay, viewColumns - - -- Create the imageSheet - if opt.sheet then - imageSheet = opt.sheet - else - local themeData = require( opt.themeData ) - imageSheet = graphics.newImageSheet( opt.themeSheetFile, themeData:getSheet() ) - end - - -- Create the view - view = display.newGroup() - - -- The view's background - viewOverlay = display.newImageRect( pickerWheel, imageSheet, opt.overlayFrame, opt.overlayFrameWidth, opt.overlayFrameHeight ) - - ---------------------------------- - -- Properties - ---------------------------------- - - -- The table which holds our pickerWheel columns - viewColumns = {} - - ------------------------------------------------------- - -- Assign properties to the view - ------------------------------------------------------- - - -- Assign properties to our view - view._width = opt.overlayFrameWidth - view._height = opt.overlayFrameHeight - view._top = opt.top - view._yPosition = pickerWheel.y + ( view._height * 0.5 ) - - -- Assign objects to our view - view._overlay = viewOverlay - view._background = viewBackground - view._columns = viewColumns - view._didTap = false - - ------------------------------------------------------- - -- Assign properties/objects to the pickerWheel - ------------------------------------------------------- - - -- Assign objects to the pickerWheel - pickerWheel._imageSheet = imageSheet - pickerWheel._view = view - pickerWheel:insert( view ) - - -- Function to render the pickerWheels columns - local function _renderColumns( event ) - local phase = event.phase - local row = event.row - local fontSize = event.target._fontSize - local alignment = event.target._align - - -- Create the column's title text - local rowTitle = display.newText( row, row._label, 0, 0, opt.font, fontSize ) - rowTitle.y = row.contentHeight * 0.5 - - if _widget.isSeven() and row.index == pickerWheel._view._columns[row.id]._values.index then - rowTitle:setFillColor( 0 ) - else - rowTitle:setFillColor( unpack( opt.fontColor ) ) - end - - row.value = rowTitle.text - - -- check if the text is greater than the actual column size - local availableWidth = viewOverlay.width - 28 - local columnWidth = view._columns[ row.id ].width or availableWidth / #view._columns - local textWidth = rowTitle.contentWidth - if textWidth > columnWidth - 1 then - --cap the text - local pixelsPerChar = 23 -- aproximate median value - local numChars = columnWidth / pixelsPerChar - row._label = row._label:sub(1, numChars) - rowTitle.text = row._label - - end - - -- Align the text as requested - if "center" == alignment then - - local rowTitleX - if isGraphicsV1 then - rowTitleX = row.x - else - rowTitleX = row.x + columnWidth * 0.5 - end - rowTitle.x = rowTitleX - - elseif "left" == alignment then - - local rowTitleX - if isGraphicsV1 then - rowTitleX = ( rowTitle.contentWidth * 0.5 ) + 6 - else - rowTitleX = row.x + 6 - rowTitle.anchorX = 0 - end - rowTitle.x = rowTitleX - - elseif "right" == alignment then - - local rowTitleX - if isGraphicsV1 then - rowTitleX = row.x + ( row.contentWidth * 0.5 ) - ( rowTitle.contentWidth * 0.5 ) - 6 - else - rowTitleX = row.x + columnWidth - 6 - rowTitle.anchorX = 1 - end - rowTitle.x = rowTitleX - - end - - - end - - -- Create a background to sit behind the pickerWheel - viewBackground = display.newImageRect( view, imageSheet, opt.backgroundFrame, opt.overlayFrameWidth, opt.overlayFrameHeight ) - viewBackground.x = viewOverlay.x - viewBackground.y = viewOverlay.y - - -- Function to create the column seperator - function view:_createSeperator( x ) - local seperator = display.newImageRect( self, imageSheet, opt.seperatorFrame, opt.seperatorFrameWidth + 4, opt.backgroundFrameHeight ) - seperator.x = x - - return seperator - end - - -- The available width for the whole pickerWheel (to fit columns) - local availableWidth = viewOverlay.width - 28 - - -- local method that handles scrolling to the tapped / touched index - function didTapValue( event ) - local phase = event.phase - local row = event.target - if "tap" == phase or "release" == phase then - view._columns[ row.id ]:scrollToIndex( row.index ) - view._didTap = true - end - end - - -- Create the pickerWheel Columns (which are tableView's) - local topPadding = 84 - local bottomPadding = 96 - if isGraphicsV1 then - topPadding = 90 - bottomPadding = 92 - end - - local initialX = 0 - local initialPos = - 144 - - for i = 1, #opt.columnData do - - if i > 1 then - initialPos = viewColumns[i-1].x + viewColumns[i-1]._view._width * 0.5 - end - - viewColumns[i] = _widget.newTableView - { - left = initialPos, - top = -110, - width = opt.columnData[i].width or availableWidth / #opt.columnData, - height = opt.overlayFrameHeight - 1, - topPadding = topPadding, - bottomPadding = bottomPadding, - noLines = true, - hideBackground = true, - hideScrollBar = true, - friction = 0.92, - rowColor = opt.columnColor, - onRowRender = _renderColumns, - maskFile = opt.maskFile, - listener = nil, - onRowTouch = didTapValue - } - viewColumns[i]._view._isUsedInPickerWheel = true - - -- Column properties - viewColumns[i]._align = opt.columnData[i].align - viewColumns[i]._fontSize = opt.fontSize - - -- Set the volumns initial values - viewColumns[i]._values = - { - index = opt.columnData[i].startIndex, - value = opt.columnData[i].labels[opt.columnData[i].startIndex], - } - - -- Create the columns row's - for j = 1, #opt.columnData[i].labels do - viewColumns[i]:insertRow - { - rowHeight = opt.rowHeight, - rowColor = { - default = opt.columnColor, - over = opt.columnColor, - }, - label = opt.columnData[i].labels[j], - id = i, - lineColor = opt.columnColor, - } - end - - -- Insert the pickerWheel column into the view - view:insert( viewColumns[i] ) - - -- Scroll to the defined index -- TODO needs failsafe - viewColumns[i]:scrollToIndex( opt.columnData[i].startIndex, 0 ) - end - - -- Create the column seperators - for i = 1, #opt.columnData - 1 do - view:_createSeperator( viewColumns[i].x + viewColumns[i]._view._width * 0.5 ) - end - - -- Push the view's background to the front. - viewOverlay:toFront() - - ---------------------------------------------------------- - -- PUBLIC METHODS - ---------------------------------------------------------- - - -- Function to retrieve the column values - function pickerWheel:getValues() - return self._view:_getValues() - end - - -- Function to scroll to a specific pickerWheel column row - function pickerWheel:scrollToIndex( ... ) - local arg = { ... } - - local column = nil - - -- If the first arg is a number, set the column to that - if "number" == type( arg[1] ) then - column = arg[1] - - -- We have retrieved the column, now set arg1 to arg2 (which is the index to scroll to) so scrollTo index gets called as expected - arg[1] = arg[2] - end - - arg[4] = self._view:_getValues() - - -- Scroll to the specified column index - return self._view._columns[column]:scrollToIndex( unpack( arg ) ) - end - - ---------------------------------------------------------- - -- PRIVATE METHODS - ---------------------------------------------------------- - - -- Override scale function as pickerWheels don't support it - function pickerWheel:scale() - print( M._widgetName, "Does not support scaling" ) - end - - -- EnterFrame listener for our pickerWheel - function view:enterFrame( event ) - local _pickerWheel = self.parent - - -- Update the y position - self._yPosition = _pickerWheel.y + ( self._height * 0.5 ) - - - - -- Manage the Picker Wheels columns - for i = 1, #self._columns do - - if "ended" == self._columns[i]._view._phase and not self._columns[i]._view._updateRuntime then - if not self._didTap then - local calculatePosition = self._yPosition - self.parent.contentHeight * 0.5 - if isGraphicsV1 then - calculatePosition = self._yPosition - end - self._columns[i]._values = self._columns[i]._view:_getRowAtPosition( calculatePosition ) - else - self._columns[i]._values = self._columns[i]._view:_getRowAtIndex( self._columns[ i ]._view._lastRowIndex ) - self._didTap = false - end - self._columns[i]._view._phase = "none" - - -- update the actual values, by rerendering row - if _widget.isSeven() and nil ~= self._columns[i]._values then - self._columns[i]._view._rows[self._columns[i]._values.index]._view[ 2 ]:setFillColor( 0 ) - end - end - end - - -- Constrain x/y scale values to 1.0 - if _pickerWheel.xScale ~= 1.0 then - _pickerWheel.xScale = 1.0 - print( M._widgetName, "Does not support scaling" ) - end - - if _pickerWheel.yScale ~= 1.0 then - _pickerWheel.yScale = 1.0 - print( M._widgetName, "Does not support scaling" ) - end - - return true - end - - Runtime:addEventListener( "enterFrame", view ) - - -- Function to retrieve the column values - function view:_getValues() - local values = {} - - -- Loop through all the columns and retrieve the values - for i = 1, #self._columns do - values[i] = self._columns[i]._values - end - - return values - end - - -- Finalize function for the pickerWheel - function pickerWheel:_finalize() - -- Remove the event listener - Runtime:removeEventListener( "enterFrame", self._view ) - - -- Set the ImageSheet to nil - self._imageSheet = nil - end - - return pickerWheel + -- Scroll to the defined index -- TODO needs failsafe + viewColumns[i]:scrollToIndex( opt.columnData[i].startIndex, 0 ) + end + + -- Create the column seperators + for i = 1, #opt.columnData - 1 do + view:_createSeperator( viewColumns[i].x + viewColumns[i]._view._width * 0.5 ) + end + + -- Push the view's background to the front. + viewOverlay:toFront() + + ---------------------------------------------------------- + -- PUBLIC METHODS + ---------------------------------------------------------- + + -- Function to retrieve the column values + function pickerWheel:getValues() + return self._view:_getValues() + end + + -- Function to scroll to a specific pickerWheel column row + function pickerWheel:scrollToIndex( ... ) + local arg = { ... } + + local column = nil + + -- If the first arg is a number, set the column to that + if "number" == type( arg[1] ) then + column = arg[1] + + -- We have retrieved the column, now set arg1 to arg2 (which is the index to scroll to) so scrollTo index gets called as expected + arg[1] = arg[2] + end + + arg[4] = self._view:_getValues() + + -- Scroll to the specified column index + return self._view._columns[column]:scrollToIndex( unpack( arg ) ) + end + + ---------------------------------------------------------- + -- PRIVATE METHODS + ---------------------------------------------------------- + + -- Override scale function as pickerWheels don't support it + function pickerWheel:scale() + print( M._widgetName, "Does not support scaling" ) + end + + -- EnterFrame listener for our pickerWheel + function view:enterFrame( event ) + local _pickerWheel = self.parent + + -- Update the y position + self._yPosition = _pickerWheel.y + ( self._height * 0.5 ) + + + + -- Manage the Picker Wheels columns + for i = 1, #self._columns do + + if "ended" == self._columns[i]._view._phase and not self._columns[i]._view._updateRuntime then + if not self._didTap then + local calculatePosition = self._yPosition - self.parent.contentHeight * 0.5 + if isGraphicsV1 then + calculatePosition = self._yPosition + end + self._columns[i]._values = self._columns[i]._view:_getRowAtPosition( calculatePosition ) + else + self._columns[i]._values = self._columns[i]._view:_getRowAtIndex( self._columns[ i ]._view._lastRowIndex ) + self._didTap = false + end + if view._onScroll then + local event = + {column = i, + value = self._columns[i]._values + } + view._onScroll(event) + end + self._columns[i]._view._phase = "none" + + -- update the actual values, by rerendering row + if _widget.isSeven() and nil ~= self._columns[i]._values then + self._columns[i]._view._rows[self._columns[i]._values.index]._view[ 2 ]:setFillColor( 0 ) + end + end + end + + -- Constrain x/y scale values to 1.0 + if _pickerWheel.xScale ~= 1.0 then + _pickerWheel.xScale = 1.0 + print( M._widgetName, "Does not support scaling" ) + end + + if _pickerWheel.yScale ~= 1.0 then + _pickerWheel.yScale = 1.0 + print( M._widgetName, "Does not support scaling" ) + end + + return true + end + + Runtime:addEventListener( "enterFrame", view ) + + -- Function to retrieve the column values + function view:_getValues() + local values = {} + + -- Loop through all the columns and retrieve the values + for i = 1, #self._columns do + values[i] = self._columns[i]._values + end + + return values + end + + -- Finalize function for the pickerWheel + function pickerWheel:_finalize() + -- Remove the event listener + Runtime:removeEventListener( "enterFrame", self._view ) + + -- Set the ImageSheet to nil + self._imageSheet = nil + end + + return pickerWheel end -- Function to create a new pickerWheel object ( widget.newPickerWheel ) function M.new( options, theme ) - local customOptions = options or {} - local themeOptions = theme or {} - - -- Create a local reference to our options table - local opt = M._options - - -- Check if the requirements for creating a widget has been met (throws an error if not) - _widget._checkRequirements( customOptions, themeOptions, M._widgetName ) - - ------------------------------------------------------- - -- Properties - ------------------------------------------------------- - - -- Positioning & properties - opt.left = customOptions.left or 0 - opt.top = customOptions.top or 0 - opt.x = customOptions.x or nil - opt.y = customOptions.y or nil - if customOptions.x and customOptions.y then - opt.left = 0 - opt.top = 0 - end - opt.id = customOptions.id - opt.baseDir = customOptions.baseDir or system.ResourceDirectory - opt.maskFile = customOptions.maskFile or themeOptions.maskFile - opt.font = customOptions.font or native.systemFontBold - opt.fontSize = customOptions.fontSize or 22 - opt.fontColor = customOptions.fontColor or blackColor - opt.columnColor = customOptions.columnColor or defaultRowColor - - if _widget.isSeven() then - opt.font = customOptions.font or themeOptions.font or "HelveticaNeue-Medium" - opt.fontSize = customOptions.fontSize or themeOptions.fontSize or 20 - opt.fontColor = labelColor - end - - -- Properties - opt.rowHeight = customOptions.rowHeight or 40 - opt.columnData = customOptions.columns - - -- Frames & images - opt.sheet = customOptions.sheet - opt.themeSheetFile = themeOptions.sheet - opt.themeData = themeOptions.data - - opt.backgroundFrame = customOptions.backgroundFrame or _widget._getFrameIndex( themeOptions, themeOptions.backgroundFrame ) - opt.backgroundFrameWidth = customOptions.backgroundFrameWidth or themeOptions.backgroundFrameWidth - opt.backgroundFrameHeight = customOptions.backgroundFrameHeight or themeOptions.backgroundFrameHeight - - opt.overlayFrame = customOptions.overlayFrame or _widget._getFrameIndex( themeOptions, themeOptions.overlayFrame ) - opt.overlayFrameWidth = customOptions.overlayFrameWidth or themeOptions.overlayFrameWidth - opt.overlayFrameHeight = customOptions.overlayFrameHeight or themeOptions.overlayFrameHeight - - opt.seperatorFrame = customOptions.seperatorFrame or _widget._getFrameIndex( themeOptions, themeOptions.seperatorFrame ) - opt.seperatorFrameWidth = customOptions.seperatorFrameWidth or themeOptions.seperatorFrameWidth - opt.seperatorFrameHeight = customOptions.seperatorFrameHeight or themeOptions.seperatorFrameHeight - - ------------------------------------------------------- - -- Create the pickerWheel - ------------------------------------------------------- - - -- Create the pickerWheel object - local pickerWheel = _widget._new - { - left = opt.left, - top = opt.top, - id = opt.id or "widget_pickerWheel", - baseDir = opt.baseDir, - } - - -- Create the pickerWheel - createPickerWheel( pickerWheel, opt ) - - local x, y = opt.x, opt.y - if not opt.x or not opt.y then - x = opt.left + pickerWheel.contentWidth * 0.5 - y = opt.top + pickerWheel.contentHeight * 0.5 - end - pickerWheel.x, pickerWheel.y = x, y - - if isGraphicsV1 then - pickerWheel:setReferencePoint( display.TopLeftReferencePoint ) - end - - return pickerWheel + local customOptions = options or {} + local themeOptions = theme or {} + + -- Create a local reference to our options table + local opt = M._options + + -- Check if the requirements for creating a widget has been met (throws an error if not) + _widget._checkRequirements( customOptions, themeOptions, M._widgetName ) + + ------------------------------------------------------- + -- Properties + ------------------------------------------------------- + + -- Positioning & properties + opt.left = customOptions.left or 0 + opt.top = customOptions.top or 0 + opt.x = customOptions.x or nil + opt.y = customOptions.y or nil + if customOptions.x and customOptions.y then + opt.left = 0 + opt.top = 0 + end + opt.id = customOptions.id + opt.baseDir = customOptions.baseDir or system.ResourceDirectory + opt.maskFile = customOptions.maskFile or themeOptions.maskFile + opt.font = customOptions.font or native.systemFontBold + opt.fontSize = customOptions.fontSize or 22 + opt.fontColor = customOptions.fontColor or blackColor + opt.columnColor = customOptions.columnColor or defaultRowColor + + if _widget.isSeven() then + opt.font = customOptions.font or themeOptions.font or "HelveticaNeue-Medium" + opt.fontSize = customOptions.fontSize or themeOptions.fontSize or 20 + opt.fontColor = labelColor + end + + -- Properties + opt.rowHeight = customOptions.rowHeight or 40 + opt.columnData = customOptions.columns + opt.onScroll = customOptions.onScroll + -- Frames & images + opt.sheet = customOptions.sheet + opt.themeSheetFile = themeOptions.sheet + opt.themeData = themeOptions.data + + opt.backgroundFrame = customOptions.backgroundFrame or _widget._getFrameIndex( themeOptions, themeOptions.backgroundFrame ) + opt.backgroundFrameWidth = customOptions.backgroundFrameWidth or themeOptions.backgroundFrameWidth + opt.backgroundFrameHeight = customOptions.backgroundFrameHeight or themeOptions.backgroundFrameHeight + + opt.overlayFrame = customOptions.overlayFrame or _widget._getFrameIndex( themeOptions, themeOptions.overlayFrame ) + opt.overlayFrameWidth = customOptions.overlayFrameWidth or themeOptions.overlayFrameWidth + opt.overlayFrameHeight = customOptions.overlayFrameHeight or themeOptions.overlayFrameHeight + + opt.seperatorFrame = customOptions.seperatorFrame or _widget._getFrameIndex( themeOptions, themeOptions.seperatorFrame ) + opt.seperatorFrameWidth = customOptions.seperatorFrameWidth or themeOptions.seperatorFrameWidth + opt.seperatorFrameHeight = customOptions.seperatorFrameHeight or themeOptions.seperatorFrameHeight + + ------------------------------------------------------- + -- Create the pickerWheel + ------------------------------------------------------- + + -- Create the pickerWheel object + local pickerWheel = _widget._new + { + left = opt.left, + top = opt.top, + id = opt.id or "widget_pickerWheel", + baseDir = opt.baseDir, + } + + -- Create the pickerWheel + createPickerWheel( pickerWheel, opt ) + + local x, y = opt.x, opt.y + if not opt.x or not opt.y then + x = opt.left + pickerWheel.contentWidth * 0.5 + y = opt.top + pickerWheel.contentHeight * 0.5 + end + pickerWheel.x, pickerWheel.y = x, y + + if isGraphicsV1 then + pickerWheel:setReferencePoint( display.TopLeftReferencePoint ) + end + + return pickerWheel end return M From de2370bd04a14a477a4ceb5f2af0a8f7444a6330 Mon Sep 17 00:00:00 2001 From: atanasster Date: Sat, 21 Dec 2013 01:03:51 -0500 Subject: [PATCH 07/55] Fix parent screen coordinate calc, fixed onPress target set --- widgetLibrary/widget_segmentedControl.lua | 35 +++++++++++------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/widgetLibrary/widget_segmentedControl.lua b/widgetLibrary/widget_segmentedControl.lua index c76c220..f044886 100755 --- a/widgetLibrary/widget_segmentedControl.lua +++ b/widgetLibrary/widget_segmentedControl.lua @@ -262,12 +262,12 @@ local function initWithImage( segmentedControl, options ) -- Touch listener for our segmented control function view:touch( event ) local phase = event.phase - local _segmentedControl = self.parent - event.target = _segmentedControl + local _segmentedControl = self local firstSegment = 1 local lastSegment = self._totalSegments if "began" == phase then + native.setKeyboardFocus(nil) -- Loop through the segments for i = 1, self._totalSegments do local segmentedControlXPosition = self.x - ( self.contentWidth * 0.5 ) @@ -275,23 +275,12 @@ local function initWithImage( segmentedControl, options ) local currentSegment = i local segmentWidth = self._segmentWidth - -- Work out the current segments position - - local parentOffsetX = 0 - - -- First, we check if the widget is in a group - if nil ~= self.parent and nil ~= self.parent.x then - parentOffsetX = self.parent.x - end - - --local currentSegmentLeftEdge = ( segmentedControlXPosition * 0.5 ) * currentSegment + parentOffsetX - --local currentSegmentRightEdge = segmentedControlXPosition + ( segmentWidth * currentSegment ) + parentOffsetX - - local currentSegmentLeftEdge = segmentedControlXPosition + ( segmentWidth * currentSegment ) - segmentWidth + parentOffsetX - local currentSegmentRightEdge = segmentedControlXPosition + ( segmentWidth * currentSegment ) + parentOffsetX + local x,y = view:contentToLocal(event.x, event.y); + local currentSegmentLeftEdge = ( segmentWidth * currentSegment ) - segmentWidth + local currentSegmentRightEdge = ( segmentWidth * currentSegment ) -- If the touch is within the segments range - if event.x >= currentSegmentLeftEdge and event.x <= currentSegmentRightEdge then + if x >= currentSegmentLeftEdge and x <= currentSegmentRightEdge then -- First segment (Near left) if firstSegment == i then self:setLeftSegmentActive() @@ -311,6 +300,7 @@ local function initWithImage( segmentedControl, options ) -- Execute onPress listener if self._onPress and "function" == type( self._onPress ) then + event.target = _segmentedControl self._onPress( event ) end @@ -422,7 +412,16 @@ local function initWithImage( segmentedControl, options ) end end - + + function segmentedControl:getDefaultSegment( ) + return self._view._segmentNumber; + end + function segmentedControl:getValue( ) + return self._view._segmentNumber; + end + function segmentedControl:setValue( segmentNum ) + self:setDefaultSegment( segmentNum ) + end -- Set the intial segment to active function segmentedControl:setDefaultSegment( segmentNum ) if 1 == segmentNum then From 1ce5d1780f66feb0bf90e84f7e98307a6d0f0cd5 Mon Sep 17 00:00:00 2001 From: atanasster Date: Sat, 21 Dec 2013 01:11:23 -0500 Subject: [PATCH 08/55] Changed to use self instead of view for consistency --- widgetLibrary/widget_segmentedControl.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgetLibrary/widget_segmentedControl.lua b/widgetLibrary/widget_segmentedControl.lua index f044886..be5b104 100755 --- a/widgetLibrary/widget_segmentedControl.lua +++ b/widgetLibrary/widget_segmentedControl.lua @@ -275,7 +275,7 @@ local function initWithImage( segmentedControl, options ) local currentSegment = i local segmentWidth = self._segmentWidth - local x,y = view:contentToLocal(event.x, event.y); + local x,y = self:contentToLocal(event.x, event.y); local currentSegmentLeftEdge = ( segmentWidth * currentSegment ) - segmentWidth local currentSegmentRightEdge = ( segmentWidth * currentSegment ) From 99bf16edaa65088ed784994fd5f971f213e886ae Mon Sep 17 00:00:00 2001 From: atanasster Date: Sat, 21 Dec 2013 01:32:21 -0500 Subject: [PATCH 09/55] tableviewext adds ability to slide out a row. in the tableView constructor, pass the distance that we would like to slide ex slideDistance = 160, then in onRowRender add hidden widgets to row.hiddenGroup : row.hiddenGroup:insert(btnDelete); --- widgetLibrary/widget_tableviewext.lua | 238 ++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 widgetLibrary/widget_tableviewext.lua diff --git a/widgetLibrary/widget_tableviewext.lua b/widgetLibrary/widget_tableviewext.lua new file mode 100644 index 0000000..6e158f1 --- /dev/null +++ b/widgetLibrary/widget_tableviewext.lua @@ -0,0 +1,238 @@ +local _widget = require("widget") + +local fastSwipeTime = 400; +local fastSwipeDistance = 50; + +local M = {} + +function M.new(old_newTableView, options) + local tableview + + local function onTransitionComplete(event) + tableview._transition = nil; + end + + +local function tableViewListener(event) + local row = event.target; + if event.phase == "began" then + if tableview._beganPhase then + event.phase = "moved" + + else + tableview._beganPhase = true; + tableview._slideStarted = false; + if tableview._slideDistance > 0 then + if tableview._targetRow and (tableview._targetRow ~= row) and (tableview._targetRow.x ~= 0) then + tableview:cancelSlide(tableview._targetRow) + elseif tableview._slideDistance > 0 and row.hiddenGroup then + if tableview._transition then + transition.cancel(tableview._transition); + tableview._targetRow.x = tableview._targetX; + tableview._transition = nil + end + display.getCurrentStage():setFocus(tableview.view); + tableview._sliding = true; + tableview._startX = event.x; + tableview._startGroupX = row.x; + tableview._startTime = event.time; + if row.hiddenGroup.isVisible == false then + row.hiddenGroup.x = row.x; + row.hiddenGroup.y = row.y; + row.hiddenGroup.isVisible = true; + end; + end; + end; + + + end + end + if event.phase == "moved" and tableview._sliding then + + local totalDistance = event.x - tableview._startX; + if math.abs(totalDistance ) > 10 then + tableview._slideStarted = true; + end + if tableview._slideStarted then + if tableview._startGroupX == 0 then + if (totalDistance < 0 ) and math.abs(totalDistance) <= tableview._slideDistance then + row.x = tableview._startGroupX + totalDistance; + end + else + if (totalDistance > 0 ) and totalDistance <= tableview._slideDistance then + row.x = tableview._startGroupX + totalDistance; + end + end + end; + end + if (event.phase == "ended" or event.phase == "cancelled") then + tableview._beganPhase = false; + if tableview._sliding then + display.getCurrentStage():setFocus(nil); + + tableview._sliding = false; + --display.getCurrentStage():setFocus(nil); + local totalSwipeTime = system.getTimer() - tableview._startTime + local totalDistance = event.x - tableview._startX ; + local absDistance = math.abs(totalDistance); + local targetX; + if (event.phase == "ended") then + if ((totalSwipeTime <= fastSwipeTime and absDistance >= fastSwipeDistance) or + (absDistance > tableview._slideDistance /2 )) then + if totalDistance < 0 then + if tableview._startGroupX == 0 then + targetX = tableview._startGroupX - tableview._slideDistance; + else + targetX = tableview._startGroupX; + end + else + targetX = 0; + end + else + targetX = tableview._startGroupX; + end + + else + targetX = tableview._startGroupX; + end + tableview:slideTo(row, targetX, 300) + end + end + + if tableview._listener then + tableview._listener (event) + end + end + + + local function tableViewRowRender(event) + local row = event.row; + local hiddenGroup = tableview.hiddenRows[row.index]; + if hiddenGroup then + display.remove(hiddenGroup); + end + row.hiddenGroup = display.newGroup() + tableview.hiddenRows[row.index] = row.hiddenGroup; + + --row:insert(row.hiddenGroup); + tableview._view:insert(row.hiddenGroup) + row.hiddenGroup.x = row.x; + row.hiddenGroup.y = row.y; + row.hiddenGroup:toBack() + + if tableview._onRowRender then + tableview._onRowRender (event) + end + end + --install hooks only if the table needs to be sliding + local _listener, _onRowRender = nil, nil; + if options.slideDistance then + + if options.listener and "function" == type(options.listener) then + _listener = options.listener; + end; + options.listener = tableViewListener; + + + if options.onRowRender and "function" == type(options.onRowRender) then + _onRowRender = options.onRowRender; + end; + + options.onRowRender = tableViewRowRender; + end + tableview = old_newTableView(options) + --tableview = require("widgets.widget_tableview").new(options) + if options.slideDistance then + tableview._listener = _listener; + tableview.hiddenRows = {}; + tableview._onRowRender = _onRowRender; + end; + tableview._slideDistance = options.slideDistance; + + + + + function tableview:slideTo(row, targetX, transitionTime) + if row then + if self._transition then + transition.cancel(self._transition) + if self._targetRow then + self._targetRow.x = self._targetX; + end + self._transition = nil; + end + if transitionTime and transitionTime > 0 then + self._targetRow = row + self._targetX = targetX; + local currentX = row.x; + local speed = math.abs(targetX - currentX) / self._slideDistance; + self._transition = transition.to(row, + { x = targetX, + time = transitionTime * speed, + transition = easing.outQuad, + onComplete = onTransitionComplete}) + else + row.x = targetX; + end + end + + end + + function tableview:deleteRow( rowIndex ) + local row = self._view:_getRowAtIndex( rowIndex ) + if row.hiddenGroup then + if self._targetRow == row then + self._targetRow = nil; + end + display.remove(row.hiddenGroup) + tableview.hiddenRows[rowIndex] = nil; + row.hiddenGroup = nil; + end + local retVal = self._view:_deleteRow( rowIndex ) + for i = rowIndex , table.maxn(self._view._rows) do + row = self._view._rows[i]; + -- If the row is within the visible view + if row and "table" == type(row._view ) then + if row and row._view.hiddenGroup then + row._view.hiddenGroup.isVisible = false; + --row._view.hiddenGroup.x = row._view.x; + --row._view.hiddenGroup.y = row._view.y; + end + end; + end + return retVal; + end + + function tableview:deleteAllRows() + for i = 1 , table.maxn(self._view._rows) do + row = self._view._rows[i]; + -- If the row is within the visible view + if row and "table" == type(row._view ) then + if row and row._view.hiddenGroup then + display.remove(row._view.hiddenGroup) + row._view.hiddenGroup = nil; + end + end; + end + self.hiddenRows = {}; + return self._view:_deleteAllRows() + end + + function tableview:cancelSlide(row) + if row then + self:slideTo(row, 0, 0) + elseif self._targetRow then + self:cancelSlide(tableview._targetRow) + end + + end + + function tableview:takeFocus(event) + self._view:touch(event) + end + + return tableview; +end + + +return M; From 9ef780e68245947dfef709ef9d866f3eb1c24756 Mon Sep 17 00:00:00 2001 From: atanasster Date: Sun, 22 Dec 2013 03:57:29 -0500 Subject: [PATCH 10/55] newEditField beta NewEditField beta - - Replaces the newTextField with a label when not in focus - uses a 3-frame slice for theming - ability to place icons or buttons around the field - ability to place a lebel in front of the field - ability to make the field non-editable for usage like a combobox with a list for selection --- widgetLibrary/widget_editfield.lua | 495 +++++++++++++++++++++++++++++ 1 file changed, 495 insertions(+) create mode 100644 widgetLibrary/widget_editfield.lua diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua new file mode 100644 index 0000000..3d8d74d --- /dev/null +++ b/widgetLibrary/widget_editfield.lua @@ -0,0 +1,495 @@ +local M = +{ + _options = {}, + _widgetName = "widget.newEditField", +} + + +local labelDefault = { 0, 0, 0 } + + +-- Require needed widget files +local _widget = require( "widget" ) +local _focusedField = nil; +-- Creates a new edit field from an image +local function initWithImage( editField, options ) + + local opt = options + + -- Forward references + local imageSheet, view, viewLeft, viewRight, viewMiddle, fieldDescription, viewTextField + + local themeData = require( opt.themeData ) + -- Create the imageSheet + if opt.sheet then + imageSheet = opt.sheet + else + imageSheet = graphics.newImageSheet( opt.themeSheetFile, themeData:getSheet() ) + end + + -- Create the view + view = editField + + if ( opt.x ) then + view.x = opt.x + elseif ( opt.left ) then + view.x = opt.left + opt.width * 0.5 + end + if ( opt.y ) then + view.y = opt.y + elseif ( opt.top ) then + view.y = opt.top + opt.height * 0.5 + end + -- The left edge + viewLeft = display.newImageRect( editField, imageSheet, opt.leftFrame, opt.edgeWidth, opt.edgeHeight ) + viewLeft.anchorX = 0; + viewLeft.x = view.x ; + viewLeft.y = view.y + ( view.contentHeight * 0.5 ) + + -- The right edge + viewRight = display.newImageRect( editField, imageSheet, opt.rightFrame, opt.edgeWidth, opt.edgeHeight ) + viewRight.anchorX = 0; + + -- The middle fill + viewMiddle = display.newImageRect( editField, imageSheet, opt.middleFrame, opt.edgeWidth, opt.edgeHeight ) + viewMiddle.anchorX = 0; + viewMiddle.width = opt.width - viewLeft.contentWidth - viewRight.contentWidth; + viewMiddle.x = viewLeft.x + viewLeft.contentWidth + viewMiddle.y = viewLeft.y + + viewRight.x = viewMiddle.x + viewMiddle.width; + viewRight.y = viewLeft.y + + + --add the widgets + local widgetsWidthLeft = 0; + local widgetsWidthRight = 0; + local widgets = opt.widgets; + for i = 1,#widgets do + local widget = widgets[i] + if widget.imageFrame or widget.style or widget.defaultFile then + local wgt = nil; + if widget.kind == "icon" then + if widget.defaultFile then + wgt = display.newImage(widget.defaultFile) + else + wgt = display.newImage(widget.imageSheet or imageSheet, + widget.defaultFrame or themeData:getFrameIndex( opt.themeOptions[ widget.style] )) + end + else + wgt = _widget.newButton( + {sheet = widget.imageSheet or imageSheet, + defaultFrame = widget.defaultFrame or themeData:getFrameIndex( opt.themeOptions[ widget.style] ), + overFrame = widget.overFrame or themeData:getFrameIndex( opt.themeOptions[tostring( widget.style).."_over"] ), + defaultFile = widget.defaultFile, + overFile = widget.overFile, + onPress = widget.onPress, + onRelease = widget.onRelease + } + ) + end + editField:insert(wgt) + if widget.style == "clear" then + view._clearButton = wgt; + wgt.isVisible = false; + + end + wgt.y = viewLeft.y + opt.buttonYOffset + if widget.align == "left" then + wgt.x = viewLeft.x + viewLeft.contentWidth+ widgetsWidthLeft + ( wgt.contentWidth * 0.5 )+ + opt.spacing + opt.buttonXOffset + widgetsWidthLeft = opt.spacing + wgt.contentWidth + widgetsWidthLeft; + + else + --by default buttons are right aligned + wgt.x = viewRight.x - widgetsWidthRight - opt.spacing - + ( wgt.contentWidth * 0.5 ) + opt.buttonXOffset + widgetsWidthRight = opt.spacing + wgt.contentWidth + widgetsWidthRight; + + end + end + + end + + -- create the label if needed + local textLabelWidth = 0; + local textLabelX = viewLeft.x + viewLeft.contentWidth; + editField.label = opt.label; + editField.placeholder = opt.placeholder; + -- The label for the field + if opt.label and opt.hideLabel == false then + fieldDescription = display.newText( editField, opt.label, 0,0, opt.labelFont, opt.labelFontSize ); + fieldDescription:setFillColor(unpack(opt.labelColor)); + fieldDescription.anchorX = 0; + fieldDescription.x = viewLeft.x + viewLeft.contentWidth + widgetsWidthLeft ; + fieldDescription.y = viewLeft.y + textLabelX = fieldDescription.x; + textLabelWidth = fieldDescription.contentWidth + end; + + -- Create the textbox (that is contained within the editField) + local textFieldWidth = opt.textFieldWidth; + if textFieldWidth == 0 then + textFieldWidth = opt.width - widgetsWidthLeft - widgetsWidthRight -opt.textFieldXOffset + - textLabelWidth - 2* opt.spacing - viewRight.contentWidth; + end + local textFieldHeight = (opt.height - 8) --* fontScale; + local tHeight = textFieldHeight; + if "Android" == system.getInfo("platformName") then + tHeight = tHeight + 10; + end + viewTextField = native.newTextField( -1000, -1000, textFieldWidth,tHeight ) + viewTextField.anchorX = 0; + editField:insert(viewTextField); + + viewTextField.anchorX = 0; + viewTextField.isEditable = true + viewTextField.hasBackground = false + viewTextField.align = "left" + viewTextField.inputType = opt.inputType; + viewTextField.isSecure = opt.isSecure; + viewTextField:setReturnKey(opt.returnKey); + + view._yOriginal = viewLeft.y + opt.textFieldYOffset + view._xOriginal = textLabelX + textLabelWidth + opt.textFieldXOffset + widgetsWidthLeft + local deviceScale = ( display.pixelWidth / display.contentWidth ) * 0.5 + viewTextField.font = native.newFont( opt.editFont ) + viewTextField.size = opt.editFontSize * deviceScale + + viewTextField:setTextColor(opt.editFontColor[1]*255, opt.editFontColor[2]*255, + opt.editFontColor[3]*255, opt.editFontColor[4]*255); + + local fakeTextField = display.newText(editField, "", 0, 0, textFieldWidth-2*opt.fakeLabelShiftX, + textFieldHeight - 2* opt.fakeLabelShiftY , opt.editFont, opt.editFontSize) + fakeTextField.anchorX = 0; + fakeTextField.x = textLabelX + textLabelWidth + widgetsWidthLeft + opt.fakeLabelShiftX ; + fakeTextField.y = viewLeft.y + opt.fakeLabelShiftY; + fakeTextField:setFillColor(unpack(opt.editFontColor)); + fakeTextField._viewTextField = viewTextField; + fakeTextField._placeholder = opt.placeholder; + view._fakeTextField = fakeTextField; + fakeTextField._view = view; + viewTextField._view = view; + + if ( opt.listener and type(opt.listener) == "function" ) then + viewTextField._listener = opt.listener + end + if ( opt.onSubmit and type(opt.onSubmit) == "function" ) then + view._onSubmit = opt.onSubmit + end + + + + view._originalX = viewLeft.x + view._originalY = viewLeft.y + view._textField = viewTextField + view._textLabelX = textLabelX + view._textLabelWidth = textLabelWidth + view._submitOnClear = opt.submitOnClear; + view._maxChars = opt.maxChars; + + if "function" == type(opt.onClick) then + view._onClick = opt.onClick; + end; + + ------------------------------------------------------- + -- Assign properties/objects to the editField + ------------------------------------------------------- + + editField._view = view + + local function onClearTap(event) + local function onClearClicked(event) + view._clearButton.isVisible = false; + view:updateFakeContent() + view._clearClicked = false; + event.target = editField; + if view._submitOnClear and view._onSubmit then + view._onSubmit(event); + end + + + end + view._clearClicked = true; + view._textField.text = ""; + --android async handling of events + timer.performWithDelay(5, onClearClicked, 1) + + return true; + end + + if view._clearButton then + view._clearButton:addEventListener( "tap" , onClearTap ) + end + ---------------------------------------------------------- + -- PUBLIC METHODS + ---------------------------------------------------------- + function view:updateFakeContent() + if self._fakingIt then + local fakeTextField = self._fakeTextField; + local viewTextField = self._textField; + local text = viewTextField.text; + if text:len() > 0 then + fakeTextField:setFillColor(unpack(opt.editFontColor)); + fakeTextField.text = viewTextField.text; + else + fakeTextField:setFillColor(unpack(opt.editHintColor)); + fakeTextField.text = fakeTextField._placeholder; + end + end; + end + + function view:_swapFakeField( fakeIt ) + + local fakeTextField = self._fakeTextField; + local viewTextField = self._textField; + if fakeIt then + if not self._fakingIt then + self._fakingIt = true; + self:updateFakeContent() + fakeTextField.isVisible = true; + display.getCurrentStage():insert(viewTextField) + viewTextField.x = -1000; + viewTextField.y = -1000; + + + end + if false and self._clearButton and self._clearButton.isVisible then + self._clearButton.isVisible = false + end + else + + _focusedField = viewTextField; + self:insert(viewTextField) + viewTextField.x = self._xOriginal; + viewTextField.y = self._yOriginal; + native.setKeyboardFocus( viewTextField ) + fakeTextField.isVisible = false; + self._fakingIt = false; + if self._clearButton then + if viewTextField.text:len() > 0 then + self._clearButton.isVisible = true + else + self._clearButton.isVisible = false + end + end; + + end + + end + + function fakeTextField:touch(event) + if "began" == event.phase then + if self._view._onClick == nil then + self._view:_swapFakeField( false ) + else + self._view._onClick(event) + end + end; + return true + end + + + fakeTextField:addEventListener( "touch" ) + view._fakingIt = false; + view:_swapFakeField( true ) + + + -- Function to listen for textbox events + function viewTextField:_inputListener( event ) + local function onHideField(event) + + end + + local phase = event.phase + local view = self._view; + if "editing" == phase then + -- If there is one or more characters in the textField show the cancel button, if not hide it + local sText = view._textField.text; + if view._maxChars > 0 then + if sText:len() > view._maxChars then + view._textField.text = string.sub(sText, 1, view._maxChars) + end + end + if view._clearButton then + if sText:len() > 0 then + view._clearButton.isVisible = true + else + view._clearButton.isVisible = false + end + end; + + elseif "submitted" == phase or + "ended" == phase then + -- Hide keyboard + if _focusedField == nil or _focusedField == self then + native.setKeyboardFocus( nil ) + end; + _focusedField = nil; + view:_swapFakeField( true ) + if view._onSubmit and (view._clearButton == nil or phase == "submitted") then + event.target = editField; + view._onSubmit(event); + end + end + + -- If there is a listener defined, execute it + if self._listener then + event.target = editField; + self._listener( event ) + end + return true; + end + + viewTextField.userInput = viewTextField._inputListener + viewTextField:addEventListener( "userInput" ) + + ---------------------------------------------------------- + -- PRIVATE METHODS + ---------------------------------------------------------- + + function editField:setText(value) + self._view._textField.text = value + self._view:updateFakeContent() + end + + function editField:getText() + return self._view._textField.text + end + + + -- Finalize function + function editField:_finalize() + -- Remove the textField + display.remove( self._view._textField ) + + self._view._textField._view = nil; + self._view._textField = nil + self._view._fakeTextField._view = nil; + self._view._fakeTextField = nil; + self._view._cancelButton = nil + + + + self._view = nil + + + end + + return editField +end + + +-- Function to create a new editfield object ( widget.newEditField) +function M.new( options, theme ) + local customOptions = options or {} + local themeOptions = theme or {} + + -- Create a local reference to our options table + local opt = M._options + + -- Check if the requirements for creating a widget has been met (throws an error if not) + _widget._checkRequirements( customOptions, themeOptions, M._widgetName ) + + ------------------------------------------------------- + -- Properties + ------------------------------------------------------- + -- Positioning & properties + opt.left = customOptions.left or 0 + opt.top = customOptions.top or 0 + opt.x = customOptions.x or nil + opt.y = customOptions.y or nil + if customOptions.x and customOptions.y then + opt.left = 0 + opt.top = 0 + else + opt.x = opt.left + opt.y = opt.top + end + opt.width = customOptions.width or 150 + opt.height = customOptions.height or 29 + opt.id = customOptions.id + opt.baseDir = customOptions.baseDir or system.ResourceDirectory + opt.placeholder = customOptions.placeholder or ""; + opt.inputType = customOptions.inputType or "default" + opt.isSecure = customOptions.isSecure or false; + opt.returnKey = customOptions.returnKey or "done"; + opt.onClick = customOptions.onClick; + + if "Android" == system.getInfo("platformName") then + opt.textFieldYOffset = customOptions.textFieldYOffset or 4 + opt.textFieldXOffset = customOptions.textFieldXOffset or -5 + opt.fakeLabelShiftY = customOptions.fakeLabelShiftY or 0; + opt.fakeLabelShiftX = customOptions.fakeLabelShiftX or 4; + else + opt.textFieldYOffset = customOptions.textFieldYOffset or -2 + opt.textFieldXOffset = customOptions.textFieldXOffset or 0 + opt.fakeLabelShiftX = customOptions.fakeLabelShiftX or 2; + opt.fakeLabelShiftY = customOptions.fakeLabelShiftY or 1; + end + + opt.textFieldWidth = customOptions.textFieldWidth or 0; + opt.listener = customOptions.listener + opt.onSubmit = customOptions.onSubmit + opt.submitOnClear = customOptions.submitOnClear or false; + opt.editFontColor = customOptions.editFontColor or themeOptions.editTextColor or {0,0,0,1} + opt.editHintColor = customOptions.editHintColor or {0.5,0.5,0.5,1} + + + -- Frames & Images + opt.sheet = customOptions.sheet + opt.themeSheetFile = themeOptions.sheet + opt.themeData = themeOptions.data + opt.themeOptions = themeOptions + opt.label = customOptions.label + opt.hideLabel = customOptions.hideLabel or false; + opt.labelColor = customOptions.labelColor or labelDefault + opt.labelFont = customOptions.labelFont or themeOptions.font or native.systemFont + opt.labelFontSize = customOptions.labelFontSize or themeOptions.fontSize or 14 + opt.spacing = customOptions.spacing or 5; + opt.widgets = customOptions.widgets or {}; + opt.listButton = customOptions.listButton or false; + opt.maxChars = customOptions.maxChars or 0; + opt.buttonXOffset = customOptions.buttonXOffset or 0 + opt.buttonYOffset = customOptions.buttonYOffset or 0 + + opt.editFont = customOptions.editFont or opt.labelFont + opt.editFontSize = customOptions.editFontSize or opt.labelFontSize + opt.hasIcon = customOptions.hasIcon or false; + + opt.leftFrame = customOptions.leftFrame or _widget._getFrameIndex( themeOptions, themeOptions.leftFrame ) + opt.rightFrame = customOptions.rightFrame or _widget._getFrameIndex( themeOptions, themeOptions.rightFrame ) + opt.middleFrame = customOptions.middleFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleFrame ) + opt.edgeWidth = customOptions.edgeWidth or themeOptions.edgeWidth or error( "ERROR: " .. M._widgetName .. ": edgeFrameWidth expected, got nil", 3 ) + opt.edgeHeight = customOptions.edgeHeight or themeOptions.edgeHeight or error( "ERROR: " .. M._widgetName .. ": edgeFrameHeight expected, got nil", 3 ) + + ------------------------------------------------------- + -- Create the editField + ------------------------------------------------------- + + -- Create the editField object + local editField = _widget._new + { + left = opt.left, + top = opt.top, + id = opt.id or "widget_editField", + baseDir = opt.baseDir, + } + + + initWithImage( editField, opt ) + + -- Set the editField's position ( set the reference point to center, just to be sure ) + + local x, y = opt.x, opt.y + if not opt.x or not opt.y then + x = opt.left + editField.contentWidth * 0.5 + y = opt.top + editField.contentHeight * 0.5 + end + editField.x, editField.y = x, y + + return editField +end + + +return M From 563f9281212c49576697981ae58aababa0e9452b Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 25 Dec 2013 14:42:27 -0500 Subject: [PATCH 11/55] newEdit Field support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit — A roundedRect frame — Validation support (if you supply an Error Frame) if you set required = true in the field constructor — a 9-slice frame to support custom size edit controls — support for theme specified in the constructor — Support for larger height editFields — Initial support to slide up the edit field when keyboard pops up (by providing a slideGroup property) — support in storyboard to maintain a list of the edit fields on the current scene — support in storyboard scene to validate() all the edit fields on the current screen — published setters/getters for isSecure, returnKey and keyboardType --- widgetLibrary/storyboardext.lua | 57 +++ widgetLibrary/widget_editfield.lua | 586 +++++++++++++++++++++-------- 2 files changed, 486 insertions(+), 157 deletions(-) create mode 100644 widgetLibrary/storyboardext.lua diff --git a/widgetLibrary/storyboardext.lua b/widgetLibrary/storyboardext.lua new file mode 100644 index 0000000..d205e6b --- /dev/null +++ b/widgetLibrary/storyboardext.lua @@ -0,0 +1,57 @@ +local storyboard = require("storyboard") + +function storyboard.getCurrentScene() + local sceneName = storyboard.getCurrentSceneName() + if sceneName and string.len(sceneName) > 0 then + return storyboard.getScene(sceneName) + else + return nil + end +end + + +local oldNewScene = nil; +local function newScene() + local scene = oldNewScene() + scene._editFields = {} + + function onExitScene( event ) + native.setKeyboardFocus(nil) + end + + function onEnterScene( event ) + native.setKeyboardFocus(nil) + end + + function onCreateScene( event ) + native.setKeyboardFocus(nil) + end + + function scene.addEditField(field) + scene._editFields [field] = field; + end + + function scene.removeEditField(field) + scene._editFields [field] = nil; + end + + function scene.validateEditFields() + local retVal = false + for i,v in pairs(scene._editFields) do + retVal = i:validate() or retVal; + end + return retVal + + end + + scene:addEventListener( "exitScene", onExitScene ) + scene:addEventListener( "enterScene", onEnterScene ) + scene:addEventListener( "createScene", onCreateScene ) + return scene; +end +if oldNewScene ~= newScene then + oldNewScene = storyboard.newScene +end + +storyboard.newScene = newScene; + diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 3d8d74d..7526e19 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -1,3 +1,5 @@ +local _storyboard = require("storyboard") + local M = { _options = {}, @@ -5,61 +7,246 @@ local M = } + +local isGraphicsV1 = ( 1 == display.getDefault( "graphicsCompatibility" ) ) + local labelDefault = { 0, 0, 0 } +local frameStrokeDefault; +if isGraphicsV1 then + frameStrokeDefault = { 0, 0, 0 } +else + frameStrokeDefault = { 0, 0, 0 } +end + + +local frameFillDefault; +if isGraphicsV1 then + frameFillDefault = { 255, 255, 255} +else + frameFillDefault = { 1, 1, 1 } +end + +local frameErrorStrokeDefault; +if isGraphicsV1 then + frameErrorStrokeDefault = { .9, 0, 0 } +else + frameErrorStrokeDefault = { 240, 0, 0 } +end + +local frameErrorFillDefault; +if isGraphicsV1 then + frameErrorFillDefault = { 0, 0, 0, 0 } +else + frameErrorFillDefault = { 0, 0, 0, 0 } +end + + -- Require needed widget files local _widget = require( "widget" ) local _focusedField = nil; + +local function getKeyboardHeight() + local function isLandscape() + return system.orientation == "landscapeLeft" or + system.orientation == "landscapeRight" + end + + if system.getInfo("model") == "iPad" then + if isLandscape() then + return 352 + else + return 264 + end + elseif system.getInfo("model") == "iPhone" or + system.getInfo("model") == "iPod" then + if isLandscape() then + return 162 + else + return 216 + end + + else + --dear android + return 350; + end +end -- Creates a new edit field from an image -local function initWithImage( editField, options ) +local function initEditField( editField, options ) local opt = options - -- Forward references - local imageSheet, view, viewLeft, viewRight, viewMiddle, fieldDescription, viewTextField - local themeData = require( opt.themeData ) - -- Create the imageSheet - if opt.sheet then - imageSheet = opt.sheet - else - imageSheet = graphics.newImageSheet( opt.themeSheetFile, themeData:getSheet() ) - end - -- Create the view - view = editField + local themeData = require( opt.themeData ) - if ( opt.x ) then - view.x = opt.x - elseif ( opt.left ) then - view.x = opt.left + opt.width * 0.5 - end - if ( opt.y ) then - view.y = opt.y - elseif ( opt.top ) then - view.y = opt.top + opt.height * 0.5 + local yCenter = opt.height / 2 + + --default values for start, end + local xStart = 0; + local xEnd = opt.width + local height, width = opt.height, opt.width + local function create9SliceFrame() + local viewTopLeft, viewMiddleLeft, viewBottomLeft + local viewTopMiddle, viewMiddle, viewBottomMiddle + local viewTopRight, viewMiddleRight, viewBottomRight + local imageSheet,sheet + + + local themeData = require( opt.themeData ) + sheet = themeData:getSheet() + imageSheet = graphics.newImageSheet( opt.themeSheetFile, sheet ) + + --top left + local index = themeData:getFrameIndex(opt.themeOptions.topLeftFrame) + local frame = sheet.frames[index] + viewTopLeft = display.newImageRect( editField, imageSheet, index, frame.width, frame.height ) + viewTopLeft.x = frame.width / 2 + viewTopLeft.y = frame.height / 2 + + --middle left + local index = themeData:getFrameIndex(opt.themeOptions.middleLeftFrame) + local frame = sheet.frames[index] + viewMiddleLeft = display.newImageRect( editField, imageSheet, index, frame.width, frame.height ) + viewMiddleLeft.x = frame.width / 2 + viewMiddleLeft.y = opt.height / 2 + + --bottom left + local index = themeData:getFrameIndex(opt.themeOptions.bottomLeftFrame) + local frame = sheet.frames[index] + viewBottomLeft = display.newImageRect( editField, imageSheet, index, frame.width, frame.height ) + viewBottomLeft.x = frame.width / 2 + viewBottomLeft.y = opt.height - frame.height / 2 + viewMiddleLeft.height = viewBottomLeft.y - viewBottomLeft.height / 2 - (viewTopLeft.y + viewTopLeft.height / 2) + + --top middle + local index = themeData:getFrameIndex(opt.themeOptions.topMiddleFrame) + local frame = sheet.frames[index] + viewTopMiddle = display.newImageRect( editField, imageSheet, index, frame.width, frame.height ) + viewTopMiddle.x = opt.width / 2 + viewTopMiddle.y = frame.height / 2 + + --top right + local index = themeData:getFrameIndex(opt.themeOptions.topRightFrame) + local frame = sheet.frames[index] + viewTopRight = display.newImageRect( editField, imageSheet, index, frame.width, frame.height ) + viewTopRight.x = opt.width - frame.width / 2 + viewTopRight.y = frame.height / 2 + viewTopMiddle.width = viewTopRight.x - viewTopRight.width / 2 - (viewTopLeft.x + viewTopLeft.width / 2) + + --middle right + local index = themeData:getFrameIndex(opt.themeOptions.middleRightFrame) + local frame = sheet.frames[index] + viewMiddleRight = display.newImageRect( editField, imageSheet, index, frame.width, frame.height ) + viewMiddleRight.x = opt.width - frame.width / 2 + viewMiddleRight.y = opt.height / 2 + + --bottom right + local index = themeData:getFrameIndex(opt.themeOptions.bottomRightFrame) + local frame = sheet.frames[index] + viewBottomRight = display.newImageRect( editField, imageSheet, index, frame.width, frame.height ) + viewBottomRight.x = opt.width - frame.width / 2 + viewBottomRight.y = opt.height - frame.height / 2 + viewMiddleRight.height = viewBottomRight.y - viewBottomRight.height / 2 - (viewTopRight.y + viewTopRight.height / 2) + + --bottom middle + local index = themeData:getFrameIndex(opt.themeOptions.bottomMiddleFrame) + local frame = sheet.frames[index] + viewBottomMiddle = display.newImageRect( editField, imageSheet, index, frame.width, frame.height ) + viewBottomMiddle.x = opt.width / 2 + viewBottomMiddle.y = opt.height - frame.height / 2 + viewBottomMiddle.width = viewBottomRight.x - viewBottomRight.width / 2 - (viewBottomLeft.x + viewBottomLeft.width / 2) + + --middle + local index = themeData:getFrameIndex(opt.themeOptions.middleFrame) + local frame = sheet.frames[index] + viewMiddle = display.newImageRect( editField, imageSheet, index, frame.width, frame.height ) + viewMiddle.x = opt.width / 2 + viewMiddle.y = opt.height / 2 + viewMiddle.width = viewMiddleRight.x - viewMiddleRight.width / 2 - (viewBottomLeft.x + viewBottomLeft.width / 2) + viewMiddle.height = viewBottomMiddle.y - viewBottomMiddle.height / 2 - (viewTopMiddle.y + viewTopMiddle.height / 2) + + xStart = viewMiddleLeft.contentWidth ; + xEnd = opt.width - viewMiddleRight.contentWidth ; + end - -- The left edge - viewLeft = display.newImageRect( editField, imageSheet, opt.leftFrame, opt.edgeWidth, opt.edgeHeight ) - viewLeft.anchorX = 0; - viewLeft.x = view.x ; - viewLeft.y = view.y + ( view.contentHeight * 0.5 ) - -- The right edge - viewRight = display.newImageRect( editField, imageSheet, opt.rightFrame, opt.edgeWidth, opt.edgeHeight ) - viewRight.anchorX = 0; + local function create3SliceFrame() + local imageSheet + -- Create the imageSheet + if opt.sheet then + imageSheet = opt.sheet + else + imageSheet = graphics.newImageSheet( opt.themeSheetFile, themeData:getSheet() ) + + end + local viewLeft, viewRight, viewMiddle + -- The left edge + viewLeft = display.newImageRect( editField, imageSheet, opt.leftFrame, opt.edgeWidth, opt.edgeHeight ) + viewLeft.x = opt.edgeWidth / 2 + viewLeft.y = yCenter + + -- The right edge + viewRight = display.newImageRect( editField, imageSheet, opt.rightFrame, opt.edgeWidth, opt.edgeHeight ) + + + -- The middle fill + viewMiddle = display.newImageRect( editField, imageSheet, opt.middleFrame, opt.edgeWidth, opt.edgeHeight ) + viewMiddle.width = width - viewLeft.contentWidth - viewRight.contentWidth; + + viewMiddle.x = viewLeft.x + viewLeft.contentWidth * 0.5 + ( viewMiddle.width * 0.5 ) + viewMiddle.y = yCenter + + viewRight.x = viewMiddle.x + ( viewMiddle.width * 0.5 ) + viewRight.width * 0.5 + viewRight.y = yCenter + + xStart = viewLeft.x + viewLeft.contentWidth / 2 ; + xEnd = viewRight.x - viewRight.contentWidth / 2 ; + end - -- The middle fill - viewMiddle = display.newImageRect( editField, imageSheet, opt.middleFrame, opt.edgeWidth, opt.edgeHeight ) - viewMiddle.anchorX = 0; - viewMiddle.width = opt.width - viewLeft.contentWidth - viewRight.contentWidth; - viewMiddle.x = viewLeft.x + viewLeft.contentWidth - viewMiddle.y = viewLeft.y + local function createErrorFrame() + local frame = opt.errorFrame; + local rect = display.newRoundedRect(editField, width / 2 , height / 2 , width+2 * frame.offset, height + 2 * frame.offset, frame.cornerRadius) + editField._errorFrame = rect + rect.strokeWidth = frame.strokeWidth ; + rect:setStrokeColor(unpack(frame.strokeColor)); + rect:setFillColor(unpack(frameErrorFillDefault)); + xStart = 0; + xEnd = opt.width; + + rect.isVisible = false; + end - viewRight.x = viewMiddle.x + viewMiddle.width; - viewRight.y = viewLeft.y + local function createRectFrame() + local frame = opt.frame; + local rect = display.newRoundedRect(editField, opt.width / 2, opt.height / 2, opt.width, opt.height, frame.cornerRadius) + rect.strokeWidth = frame.strokeWidth ; + rect:setStrokeColor(unpack(frame.strokeColor)); + rect:setFillColor(unpack(frame.fillColor)); + xStart = math.max(frame.strokeWidth, frame.cornerRadius); + xEnd = opt.width - math.max(frame.strokeWidth, frame.cornerRadius); + + end + --if there is an "validation error" frame, create it and subtract from height/width + if opt.errorFrame then + createErrorFrame() + end + --create with a rectangle frame or slice frame + if opt.frame then + createRectFrame() + else + if opt.topLeftFrame and opt.middleLeftFrame and opt.bottomLeftFrame and + opt.topRightFrame and opt.middleRightFrame and opt.bottomRightFrame and + opt.topMiddleFrame and opt.middleFrame and opt.bottomMiddleFrame then + + create9SliceFrame() + else + create3SliceFrame() + end + end + local fieldDescription, viewTextField --add the widgets local widgetsWidthLeft = 0; @@ -69,13 +256,18 @@ local function initWithImage( editField, options ) local widget = widgets[i] if widget.imageFrame or widget.style or widget.defaultFile then local wgt = nil; - if widget.kind == "icon" then + if (widget.kind == "icon") or (widget.kind == "clear") then if widget.defaultFile then wgt = display.newImage(widget.defaultFile) else wgt = display.newImage(widget.imageSheet or imageSheet, widget.defaultFrame or themeData:getFrameIndex( opt.themeOptions[ widget.style] )) end + if widget.kind == "clear" then + editField._clearButton = wgt; + wgt.isVisible = false; + + end else wgt = _widget.newButton( {sheet = widget.imageSheet or imageSheet, @@ -88,32 +280,28 @@ local function initWithImage( editField, options ) } ) end - editField:insert(wgt) - if widget.style == "clear" then - view._clearButton = wgt; - wgt.isVisible = false; - - end - wgt.y = viewLeft.y + opt.buttonYOffset - if widget.align == "left" then - wgt.x = viewLeft.x + viewLeft.contentWidth+ widgetsWidthLeft + ( wgt.contentWidth * 0.5 )+ - opt.spacing + opt.buttonXOffset - widgetsWidthLeft = opt.spacing + wgt.contentWidth + widgetsWidthLeft; - - else - --by default buttons are right aligned - wgt.x = viewRight.x - widgetsWidthRight - opt.spacing - - ( wgt.contentWidth * 0.5 ) + opt.buttonXOffset - widgetsWidthRight = opt.spacing + wgt.contentWidth + widgetsWidthRight; - - end + if wgt then + editField:insert(wgt) + wgt.y = yCenter + opt.buttonYOffset + if widget.align == "left" then + wgt.x = xStart + widgetsWidthLeft + ( wgt.contentWidth * 0.5 )+ + opt.spacing + opt.buttonXOffset + widgetsWidthLeft = opt.spacing + wgt.contentWidth + widgetsWidthLeft; + + else + --by default buttons are right aligned + wgt.x = xEnd - widgetsWidthRight - opt.spacing - + ( wgt.contentWidth * 0.5 ) + opt.buttonXOffset + widgetsWidthRight = opt.spacing + wgt.contentWidth + widgetsWidthRight; + + end + end; end end - -- create the label if needed local textLabelWidth = 0; - local textLabelX = viewLeft.x + viewLeft.contentWidth; + local textLabelX = xStart; editField.label = opt.label; editField.placeholder = opt.placeholder; -- The label for the field @@ -121,17 +309,16 @@ local function initWithImage( editField, options ) fieldDescription = display.newText( editField, opt.label, 0,0, opt.labelFont, opt.labelFontSize ); fieldDescription:setFillColor(unpack(opt.labelColor)); fieldDescription.anchorX = 0; - fieldDescription.x = viewLeft.x + viewLeft.contentWidth + widgetsWidthLeft ; - fieldDescription.y = viewLeft.y + fieldDescription.x = xStart + widgetsWidthLeft + opt.spacing ; + fieldDescription.y = yCenter textLabelX = fieldDescription.x; textLabelWidth = fieldDescription.contentWidth end; - -- Create the textbox (that is contained within the editField) local textFieldWidth = opt.textFieldWidth; if textFieldWidth == 0 then - textFieldWidth = opt.width - widgetsWidthLeft - widgetsWidthRight -opt.textFieldXOffset - - textLabelWidth - 2* opt.spacing - viewRight.contentWidth; + textFieldWidth = (xEnd - xStart) - widgetsWidthLeft - widgetsWidthRight -opt.textFieldXOffset + - textLabelWidth - 2* opt.spacing; end local textFieldHeight = (opt.height - 8) --* fontScale; local tHeight = textFieldHeight; @@ -147,84 +334,89 @@ local function initWithImage( editField, options ) viewTextField.hasBackground = false viewTextField.align = "left" viewTextField.inputType = opt.inputType; + editField.inputType = opt.inputType; + viewTextField.isSecure = opt.isSecure; + editField.isSecure = opt.isSecure; + viewTextField:setReturnKey(opt.returnKey); + editField.returnKey = opt.returnKey; + + editField.required = opt.required; + + editField.slideGroup = opt.slideGroup - view._yOriginal = viewLeft.y + opt.textFieldYOffset - view._xOriginal = textLabelX + textLabelWidth + opt.textFieldXOffset + widgetsWidthLeft + editField._yOriginal = yCenter + opt.textFieldYOffset + editField._xOriginal = textLabelX + textLabelWidth + opt.textFieldXOffset + widgetsWidthLeft local deviceScale = ( display.pixelWidth / display.contentWidth ) * 0.5 viewTextField.font = native.newFont( opt.editFont ) viewTextField.size = opt.editFontSize * deviceScale viewTextField:setTextColor(opt.editFontColor[1]*255, opt.editFontColor[2]*255, opt.editFontColor[3]*255, opt.editFontColor[4]*255); - local fakeTextField = display.newText(editField, "", 0, 0, textFieldWidth-2*opt.fakeLabelShiftX, textFieldHeight - 2* opt.fakeLabelShiftY , opt.editFont, opt.editFontSize) fakeTextField.anchorX = 0; fakeTextField.x = textLabelX + textLabelWidth + widgetsWidthLeft + opt.fakeLabelShiftX ; - fakeTextField.y = viewLeft.y + opt.fakeLabelShiftY; + fakeTextField.y = yCenter + opt.fakeLabelShiftY; fakeTextField:setFillColor(unpack(opt.editFontColor)); fakeTextField._viewTextField = viewTextField; fakeTextField._placeholder = opt.placeholder; - view._fakeTextField = fakeTextField; - fakeTextField._view = view; - viewTextField._view = view; - + editField._fakeTextField = fakeTextField; if ( opt.listener and type(opt.listener) == "function" ) then viewTextField._listener = opt.listener end if ( opt.onSubmit and type(opt.onSubmit) == "function" ) then - view._onSubmit = opt.onSubmit + editField._onSubmit = opt.onSubmit end - - - view._originalX = viewLeft.x - view._originalY = viewLeft.y - view._textField = viewTextField - view._textLabelX = textLabelX - view._textLabelWidth = textLabelWidth - view._submitOnClear = opt.submitOnClear; - view._maxChars = opt.maxChars; + editField._textField = viewTextField + editField._textLabelX = textLabelX + editField._textLabelWidth = textLabelWidth + editField.submitOnClear = opt.submitOnClear; + editField.maxChars = opt.maxChars; if "function" == type(opt.onClick) then - view._onClick = opt.onClick; + editField._onClick = opt.onClick; end; - ------------------------------------------------------- - -- Assign properties/objects to the editField - ------------------------------------------------------- - - editField._view = view + --add to storyboard list of editFields + if _storyboard.getCurrentScene then + local scene = _storyboard.getCurrentScene() + if scene.addEditField then + scene.addEditField(editField) + editField._scene = scene; + end + + end local function onClearTap(event) local function onClearClicked(event) - view._clearButton.isVisible = false; - view:updateFakeContent() - view._clearClicked = false; + editField._clearButton.isVisible = false; + editField:updateFakeContent() + editField._clearClicked = false; event.target = editField; - if view._submitOnClear and view._onSubmit then - view._onSubmit(event); + if editField._submitOnClear and editField._onSubmit then + editField._onSubmit(event); end end - view._clearClicked = true; - view._textField.text = ""; + editField._clearClicked = true; + editField._textField.text = ""; --android async handling of events timer.performWithDelay(5, onClearClicked, 1) return true; end - if view._clearButton then - view._clearButton:addEventListener( "tap" , onClearTap ) + if editField._clearButton then + editField._clearButton:addEventListener( "tap" , onClearTap ) end ---------------------------------------------------------- -- PUBLIC METHODS ---------------------------------------------------------- - function view:updateFakeContent() + function editField:updateFakeContent() if self._fakingIt then local fakeTextField = self._fakeTextField; local viewTextField = self._textField; @@ -239,24 +431,25 @@ local function initWithImage( editField, options ) end; end - function view:_swapFakeField( fakeIt ) - + function editField:_swapFakeField( fakeIt ) + local function onTransition(event) + self._slideTrans = nil; + end local fakeTextField = self._fakeTextField; local viewTextField = self._textField; if fakeIt then if not self._fakingIt then self._fakingIt = true; self:updateFakeContent() + if self._originalSlideY and self.slideGroup then + transition.to(self.slideGroup,{y = self._originalSlideY,time=300, onComplete = onTransition}) + self._originalSlideY = nil; + end fakeTextField.isVisible = true; display.getCurrentStage():insert(viewTextField) viewTextField.x = -1000; viewTextField.y = -1000; - - end - if false and self._clearButton and self._clearButton.isVisible then - self._clearButton.isVisible = false - end else _focusedField = viewTextField; @@ -267,23 +460,35 @@ local function initWithImage( editField, options ) fakeTextField.isVisible = false; self._fakingIt = false; if self._clearButton then - if viewTextField.text:len() > 0 then - self._clearButton.isVisible = true - else - self._clearButton.isVisible = false - end + self._clearButton.isVisible = string.len(viewTextField.text) == 0 end; - + --check if we need to slide + if self.slideGroup and self._originalSlideY == nil then + local y = self.y; + local parent = self.parent; + while parent and parent.y do + y = y + parent.y; + parent = parent.parent + end + local top = y - self.contentHeight / 2; + local kbHeight = getKeyboardHeight(); + local desiredTop = display.contentHeight - kbHeight - self.contentHeight; + if top > desiredTop then + self._originalSlideY = self.slideGroup.y; + transition.to(self.slideGroup,{y = self.slideGroup.y - (top - desiredTop),time=300}) + end + end end end function fakeTextField:touch(event) + local editField = self.parent; if "began" == event.phase then - if self._view._onClick == nil then - self._view:_swapFakeField( false ) + if editField._onClick == nil then + editField:_swapFakeField( false ) else - self._view._onClick(event) + editField._onClick(event) end end; return true @@ -291,8 +496,8 @@ local function initWithImage( editField, options ) fakeTextField:addEventListener( "touch" ) - view._fakingIt = false; - view:_swapFakeField( true ) + editField._fakingIt = false; + editField:_swapFakeField( true ) -- Function to listen for textbox events @@ -302,22 +507,22 @@ local function initWithImage( editField, options ) end local phase = event.phase - local view = self._view; + local editField = self.parent; if "editing" == phase then -- If there is one or more characters in the textField show the cancel button, if not hide it - local sText = view._textField.text; - if view._maxChars > 0 then - if sText:len() > view._maxChars then - view._textField.text = string.sub(sText, 1, view._maxChars) + local sText = editField._textField.text; + local textLen = string.len(sText); + if editField.maxChars > 0 then + if textLen > editField.maxChars then + self.text = string.sub(sText, 1, editField.maxChars) end end - if view._clearButton then - if sText:len() > 0 then - view._clearButton.isVisible = true - else - view._clearButton.isVisible = false - end - end; + if editField._clearButton then + editField._clearButton.isVisible = textLen > 0 + end + if editField._errorFrame and editField.validating then + editField._errorFrame.isVisible = editField.required and textLen == 0; + end elseif "submitted" == phase or "ended" == phase then @@ -326,10 +531,10 @@ local function initWithImage( editField, options ) native.setKeyboardFocus( nil ) end; _focusedField = nil; - view:_swapFakeField( true ) - if view._onSubmit and (view._clearButton == nil or phase == "submitted") then + editField:_swapFakeField( true ) + if editField._onSubmit and (editField._clearButton == nil or phase == "submitted") then event.target = editField; - view._onSubmit(event); + editField._onSubmit(event); end end @@ -349,30 +554,64 @@ local function initWithImage( editField, options ) ---------------------------------------------------------- function editField:setText(value) - self._view._textField.text = value - self._view:updateFakeContent() + self._textField.text = value + self:updateFakeContent() end function editField:getText() - return self._view._textField.text + return self._textField.text end + function editField:setReturnKey(value) + self.returnKey = value; + self._textField:setReturnKey(self.returnKey); + + end; + + function editField:setInputType(value) + self.inputType = value; + self._textField.inputType = value; + end; + + function editField:setIsSecure(value) + self.isSecure = value; + self._textField.isSecure = value; + end; + function editField:validate() + if self._errorFrame then + self.validating = true; + self._errorFrame.isVisible = + self.required and + string.len(self._textField.text) == 0 + return self._errorFrame.isVisible + end + return false + end + + function editField:setEditMode(value) + self:_swapFakeField( not value ) + end + + function editField:getEditMode() + return not self._fakingIt; + end -- Finalize function function editField:_finalize() - -- Remove the textField - display.remove( self._view._textField ) - - self._view._textField._view = nil; - self._view._textField = nil - self._view._fakeTextField._view = nil; - self._view._fakeTextField = nil; - self._view._cancelButton = nil - - + --remove from storyboard + local scene = self._scene; + if scene then + if scene.removeEditField then + scene.removeEditField(self) + end + end - self._view = nil + -- Remove the textField + display.remove( self._textField ) + self._textField = nil + self._fakeTextField = nil; + self._cancelButton = nil end @@ -400,14 +639,29 @@ function M.new( options, theme ) opt.x = customOptions.x or nil opt.y = customOptions.y or nil if customOptions.x and customOptions.y then - opt.left = 0 - opt.top = 0 - else - opt.x = opt.left - opt.y = opt.top + opt.left = 0 + opt.top = 0 end opt.width = customOptions.width or 150 opt.height = customOptions.height or 29 + opt.frame = customOptions.frame + if opt.frame then + + opt.frame.cornerRadius = opt.frame.cornerRadius or 0; + opt.frame.strokeWidth = opt.frame.strokeWidth or 1; + opt.frame.strokeColor = opt.frame.strokeColor or frameStrokeDefault; + opt.frame.fillColor = opt.frame.fillColor or frameFillDefault; + end; + + opt.errorFrame = customOptions.errorFrame + if opt.errorFrame then + opt.errorFrame.cornerRadius = opt.errorFrame.cornerRadius or (opt.frame and opt.frame.cornerRadius or 0); + opt.errorFrame.strokeWidth = opt.errorFrame.strokeWidth or (opt.frame and opt.frame.strokeWidth or 1); + opt.errorFrame.strokeColor = opt.errorFrame.strokeColor or frameErrorStrokeDefault; + opt.errorFrame.offset = opt.errorFrame.offset or 3; + + end; + opt.id = customOptions.id opt.baseDir = customOptions.baseDir or system.ResourceDirectory opt.placeholder = customOptions.placeholder or ""; @@ -415,7 +669,7 @@ function M.new( options, theme ) opt.isSecure = customOptions.isSecure or false; opt.returnKey = customOptions.returnKey or "done"; opt.onClick = customOptions.onClick; - + opt.required = customOptions.required or false; if "Android" == system.getInfo("platformName") then opt.textFieldYOffset = customOptions.textFieldYOffset or 4 opt.textFieldXOffset = customOptions.textFieldXOffset or -5 @@ -446,7 +700,7 @@ function M.new( options, theme ) opt.labelColor = customOptions.labelColor or labelDefault opt.labelFont = customOptions.labelFont or themeOptions.font or native.systemFont opt.labelFontSize = customOptions.labelFontSize or themeOptions.fontSize or 14 - opt.spacing = customOptions.spacing or 5; + opt.spacing = customOptions.spacing or 2; opt.widgets = customOptions.widgets or {}; opt.listButton = customOptions.listButton or false; opt.maxChars = customOptions.maxChars or 0; @@ -455,13 +709,31 @@ function M.new( options, theme ) opt.editFont = customOptions.editFont or opt.labelFont opt.editFontSize = customOptions.editFontSize or opt.labelFontSize - opt.hasIcon = customOptions.hasIcon or false; + opt.slideGroup = customOptions.slideGroup + + -- Left ( 9 piece set ) + opt.topLeftFrame = customOptions.topLeftFrame or _widget._getFrameIndex( themeOptions, themeOptions.topLeftFrame ) + opt.middleLeftFrame = customOptions.middleLeftFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleLeftFrame ) + opt.bottomLeftFrame = customOptions.bottomLeftFrame or _widget._getFrameIndex( themeOptions, themeOptions.bottomLeftFrame ) + -- Right ( 9 piece set ) + opt.topRightFrame = customOptions.topRightFrame or _widget._getFrameIndex( themeOptions, themeOptions.topRightFrame ) + opt.middleRightFrame = customOptions.middleRightFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleRightFrame ) + opt.bottomRightFrame = customOptions.bottomRightFrame or _widget._getFrameIndex( themeOptions, themeOptions.bottomRightFrame ) + + -- Middle ( 9 piece set ) + opt.topMiddleFrame = customOptions.topMiddleFrame or _widget._getFrameIndex( themeOptions, themeOptions.topMiddleFrame ) + opt.middleFrame = customOptions.middleFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleFrame ) + opt.bottomMiddleFrame = customOptions.bottomMiddleFrame or _widget._getFrameIndex( themeOptions, themeOptions.bottomMiddleFrame ) + + --3 slice opt.leftFrame = customOptions.leftFrame or _widget._getFrameIndex( themeOptions, themeOptions.leftFrame ) opt.rightFrame = customOptions.rightFrame or _widget._getFrameIndex( themeOptions, themeOptions.rightFrame ) - opt.middleFrame = customOptions.middleFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleFrame ) - opt.edgeWidth = customOptions.edgeWidth or themeOptions.edgeWidth or error( "ERROR: " .. M._widgetName .. ": edgeFrameWidth expected, got nil", 3 ) - opt.edgeHeight = customOptions.edgeHeight or themeOptions.edgeHeight or error( "ERROR: " .. M._widgetName .. ": edgeFrameHeight expected, got nil", 3 ) + opt.middleFrame = opt.middleFrame or customOptions.middleFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleFrame ) + if opt.leftFrame and opt.rightFrame and opt.middleFrame then + opt.edgeWidth = customOptions.edgeWidth or themeOptions.edgeWidth or error( "ERROR: " .. M._widgetName .. ": edgeFrameWidth expected, got nil", 3 ) + opt.edgeHeight = customOptions.edgeHeight or themeOptions.edgeHeight or error( "ERROR: " .. M._widgetName .. ": edgeFrameHeight expected, got nil", 3 ) + end ------------------------------------------------------- -- Create the editField @@ -477,7 +749,7 @@ function M.new( options, theme ) } - initWithImage( editField, opt ) + initEditField( editField, opt ) -- Set the editField's position ( set the reference point to center, just to be sure ) From f5cbf637e064da0e0d2de4330518b43ce698d1ae Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 25 Dec 2013 14:45:54 -0500 Subject: [PATCH 12/55] added support for custom theme for newEditField Added parameter theme in the constructor for newEditField --- widgetLibrary/widgetext.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/widgetLibrary/widgetext.lua b/widgetLibrary/widgetext.lua index 1e8dd56..8bef27e 100644 --- a/widgetLibrary/widgetext.lua +++ b/widgetLibrary/widgetext.lua @@ -65,8 +65,14 @@ end widget.newPageSlider = newPageSlider; + local function newEditField( options ) - local theme = _getTheme( "editField", options ); + local theme; + if options.theme then + theme = require(options.theme)["editField"] + else + theme = _getTheme( "editField", options ); + end if theme == nil then --if the current theme does not have a editfield, revert to searchfield theme = _getTheme( "searchField", options ) @@ -121,7 +127,7 @@ end widget.newSwitch = newSwitch; -function newPickerWheel( options ) +local function newPickerWheel( options ) local theme = _getTheme( "pickerWheel", options ) local _pickerWheel = require( "widgets.widget_pickerWheel" ) return _pickerWheel.new( options, theme ) From daaf1ec5e3d230c7dcb7e97f7ca8ca35bdf5b51f Mon Sep 17 00:00:00 2001 From: atanasster Date: Mon, 30 Dec 2013 01:42:11 -0500 Subject: [PATCH 13/55] newEditField Fixes - Support for Calibration - Separated editfield defaults in another file - Added background group to eat touch events - Support for native fields that do not swap, for scenes that are topmost --- widgetLibrary/editfield_defaults.lua | 122 +++++++++ widgetLibrary/widget_editfield.lua | 356 ++++++++++++++++++--------- 2 files changed, 365 insertions(+), 113 deletions(-) create mode 100644 widgetLibrary/editfield_defaults.lua diff --git a/widgetLibrary/editfield_defaults.lua b/widgetLibrary/editfield_defaults.lua new file mode 100644 index 0000000..df5a516 --- /dev/null +++ b/widgetLibrary/editfield_defaults.lua @@ -0,0 +1,122 @@ +local M = {} + +if "Android" == system.getInfo("platformName") then + M.textFieldYOffset = 6 + M.textFieldXOffset = -5 + M.fakeLabelYOffset = 1 + M.fakeLabelXOffset = 4 + M.textFieldHeightAdjust = 12 +elseif system.getInfo("environment") == "simulator" then + M.textFieldYOffset = -3 + M.textFieldXOffset = 0 + M.fakeLabelYOffset = 0 + M.fakeLabelXOffset = 2 + M.textFieldHeightAdjust = 0; +else + M.textFieldYOffset = 0 + M.textFieldXOffset = 0 + M.fakeLabelYOffset = 0 + M.fakeLabelXOffset = 0 + M.textFieldHeightAdjust = 0; + +end +local function calcFontSize(targetFontSize) + local sysType = system.getInfo("architectureInfo") + local environment = system.getInfo("environment") + local fontScale = (display.pixelWidth / display.contentWidth) * display.contentScaleX; + if display.pixelWidth == display.contentWidth then + fontScale = 1; + end + if system.getInfo("platformName") == "Android" then + fontScale = (display.pixelWidth / display.contentWidth) * 0.5; + elseif environment ~= "simulator" then + if string.match(system.getInfo("model"),"iPa") then + --iPads + if display.pixelHeight == 2048 then + --iPad retina + fontScale = (display.pixelHeight / display.contentHeight) * 0.5; + else + fontScale = 1 / display.contentScaleY + end + end + end + + return fontScale + +end + +function M:robMiracleCalcFontSize() + return ( display.pixelWidth / display.contentWidth ) * 0.5 +end + +function M:mpappasCalcFontSize() + local sysType = system.getInfo("architectureInfo") + + local fontScale = 1 / display.contentScaleY -- old method is fallback (ends up being sim setting) + + if system.getInfo("platformName") == "Android" or not string.match(system.getInfo("model"),"iP") then -- try and get the real width / height and deal with it + --print(" -- -- Android font size calc...") + + local missingInches = display.screenOriginY * -2 -- account for both top and bottom area (x2), and change the sign sign since originY is always negative, if it exists... + + missingInches = missingInches / 320 -- 320 is 1 inch, in my 640x960 virual content space (960 == 3 inches for my app, designed for a standard iphone 4 display) + -- different contentScale sizes will use a different virtual pixel / inch value (eg, 320x480 virtual content = missingInches / 160) + --print(" -- missing inches == ", missingInches) + + local heightIn = system.getInfo( "androidDisplayHeightInInches" ) + local widthIn = system.getInfo( "androidDisplayWidthInInches" ) + --print(" -- original height == ", heightIn) + if heightIn ~= nil then + heightIn = heightIn - missingInches + + --Make sure its not nil... e.g. the simulator will return nil, perhaps some bad devices will too... + + -- heightIn is height of actual droid app is running on + fontScale = heightIn / 3.0 -- 3.0 is actual iPhone 3gs /4 /4s height + --print(" -- fontsize set on actual droid screen inch height") + --print(" -- widthIn = ", widthIn) + --print(" -- heightIn = ", heightIn) + else + fontScale = 4/3 --Default to a 4 inch diagonal (iphone is 3.0) + --print(" -- fontsize set to 4 inch phone size") + end + + + else + local fontScale = 1 + local heightIn = 3 -- default to stnadard iPhone size + local missingInches = display.screenOriginY * -2 -- account for both top and bottom area (x2), and change the sign sign originY is negative, if it exists... + + missingInches = missingInches / 320 -- 320 is 1 inch, in my 640x960 virual content space (960 == 3 inches for my app, designed for a standard iphone 4 display) + -- different contentScale sizes will use a different virtual pixel / inch value (eg, 320x480 virtual content = missingInches / 160) + -- + -- Since there is no corona facility to get the screen height of the device on iOS, we'll determine it ourselves. + -- + if( sysType == "iPhone2,1" ) then -- 3GS + heightIn = 3.0 - missingInches -- original iPhone size + elseif( string.match(sysType, "iPhone3") or string.match(sysType, "iPhone4") ) then -- iPhone 4, 4S + heightIn = 3.0 - missingInches -- Same size as the old 3gs- better resolution, but same size + elseif( string.match(sysType, "iPhone5") ) then -- iPhone 5 + heightIn = 4.0 - missingInches -- Should go back to 3, after missing inches chopped off by corona are deducted. + elseif sysType == "iPad2,5" or sysType == "iPad2,6" or sysType == "iPad2,7" or sysType == "iPad2,8" then -- 2,8 is unknown, just a guess at next mini # + heightIn = 6.25 - missingInches -- mini + elseif( string.match(sysType, "iPad") ) then -- standard iPad + heightIn = 7.75 - missingInches -- iPad + else + if( missingInches == 0 ) then + -- iPod falls through to here (and it is 3 inches tall, and any missing inches accounted for in a tall version, so that works for now) + heightIn = 3.0 - missingInches -- I would hope this is typical, zero extra on an unknown ios device + else + heightIn = 4.0 - missingInches -- otherwise, we'll take a flying guess that the unknown device is bigger than a tiny breadbox, and smaller than a car. (4 inches tall, iphone 5 format) + end + end + fontScale = heightIn / 3.0 -- 3.0 inches is actual iPhone 4 height (that my content is based on) + end + return fontScale + +end + +M.fontScale = calcFontSize() + +return M + diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 7526e19..c54b5c6 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -1,4 +1,7 @@ +-- Require needed widget files +local _widget = require( "widget" ) local _storyboard = require("storyboard") +local efDefaults = require("widgets.editfield_defaults") local M = { @@ -7,7 +10,6 @@ local M = } - local isGraphicsV1 = ( 1 == display.getDefault( "graphicsCompatibility" ) ) local labelDefault = { 0, 0, 0 } @@ -43,8 +45,6 @@ end --- Require needed widget files -local _widget = require( "widget" ) local _focusedField = nil; local function getKeyboardHeight() @@ -69,7 +69,7 @@ local function getKeyboardHeight() else --dear android - return 350; + return math.min(350, display.contentHeight / 2); end end -- Creates a new edit field from an image @@ -82,6 +82,7 @@ local function initEditField( editField, options ) local themeData = require( opt.themeData ) local yCenter = opt.height / 2 + local imageSheet --default values for start, end local xStart = 0; @@ -91,7 +92,7 @@ local function initEditField( editField, options ) local viewTopLeft, viewMiddleLeft, viewBottomLeft local viewTopMiddle, viewMiddle, viewBottomMiddle local viewTopRight, viewMiddleRight, viewBottomRight - local imageSheet,sheet + local sheet local themeData = require( opt.themeData ) @@ -169,11 +170,10 @@ local function initEditField( editField, options ) xStart = viewMiddleLeft.contentWidth ; xEnd = opt.width - viewMiddleRight.contentWidth ; - + height = opt.height - (viewBottomMiddle.height + viewTopMiddle.height) + 2; end local function create3SliceFrame() - local imageSheet -- Create the imageSheet if opt.sheet then imageSheet = opt.sheet @@ -203,6 +203,7 @@ local function initEditField( editField, options ) xStart = viewLeft.x + viewLeft.contentWidth / 2 ; xEnd = viewRight.x - viewRight.contentWidth / 2 ; + height = opt.height - 2*4 ; end local function createErrorFrame() @@ -226,7 +227,7 @@ local function initEditField( editField, options ) rect:setFillColor(unpack(frame.fillColor)); xStart = math.max(frame.strokeWidth, frame.cornerRadius); xEnd = opt.width - math.max(frame.strokeWidth, frame.cornerRadius); - + height = opt.height - 2*frame.strokeWidth - 2; end --if there is an "validation error" frame, create it and subtract from height/width @@ -310,7 +311,7 @@ local function initEditField( editField, options ) fieldDescription:setFillColor(unpack(opt.labelColor)); fieldDescription.anchorX = 0; fieldDescription.x = xStart + widgetsWidthLeft + opt.spacing ; - fieldDescription.y = yCenter + fieldDescription.y = yCenter + opt.fakeLabelYOffset textLabelX = fieldDescription.x; textLabelWidth = fieldDescription.contentWidth end; @@ -320,20 +321,27 @@ local function initEditField( editField, options ) textFieldWidth = (xEnd - xStart) - widgetsWidthLeft - widgetsWidthRight -opt.textFieldXOffset - textLabelWidth - 2* opt.spacing; end - local textFieldHeight = (opt.height - 8) --* fontScale; - local tHeight = textFieldHeight; - if "Android" == system.getInfo("platformName") then - tHeight = tHeight + 10; - end - viewTextField = native.newTextField( -1000, -1000, textFieldWidth,tHeight ) + local textFieldHeight = height; + local tmpField = display.newText("W",0,0,opt.editFont,opt.editFontSize) + local lineHeight = tmpField.contentHeight; + tmpField:removeSelf(); + editField._xOriginal = textLabelX + textLabelWidth + opt.textFieldXOffset + widgetsWidthLeft + editField._yOriginal = yCenter + opt.textFieldYOffset + if opt.native then + viewTextField = native.newTextField(editField._xOriginal, editField._yOriginal, textFieldWidth,lineHeight + opt.textFieldHeightAdjust ) + viewTextField.placeholder = opt.placeholder; + else + viewTextField = native.newTextField( -1000, -1000, textFieldWidth,lineHeight + opt.textFieldHeightAdjust ) + end + viewTextField.anchorX = 0; editField:insert(viewTextField); - viewTextField.anchorX = 0; viewTextField.isEditable = true viewTextField.hasBackground = false viewTextField.align = "left" viewTextField.inputType = opt.inputType; + editField.inputType = opt.inputType; viewTextField.isSecure = opt.isSecure; @@ -345,24 +353,28 @@ local function initEditField( editField, options ) editField.required = opt.required; editField.slideGroup = opt.slideGroup + editField.keyboardSlideTime = opt.keyboardSlideTime + editField.calibrating = opt.calibrating + editField.native = opt.native; + editField.fontScale = opt.fontScale; - editField._yOriginal = yCenter + opt.textFieldYOffset - editField._xOriginal = textLabelX + textLabelWidth + opt.textFieldXOffset + widgetsWidthLeft - local deviceScale = ( display.pixelWidth / display.contentWidth ) * 0.5 viewTextField.font = native.newFont( opt.editFont ) - viewTextField.size = opt.editFontSize * deviceScale + viewTextField.size = opt.editFontSize * opt.fontScale --deviceScale viewTextField:setTextColor(opt.editFontColor[1]*255, opt.editFontColor[2]*255, - opt.editFontColor[3]*255, opt.editFontColor[4]*255); - local fakeTextField = display.newText(editField, "", 0, 0, textFieldWidth-2*opt.fakeLabelShiftX, - textFieldHeight - 2* opt.fakeLabelShiftY , opt.editFont, opt.editFontSize) - fakeTextField.anchorX = 0; - fakeTextField.x = textLabelX + textLabelWidth + widgetsWidthLeft + opt.fakeLabelShiftX ; - fakeTextField.y = yCenter + opt.fakeLabelShiftY; - fakeTextField:setFillColor(unpack(opt.editFontColor)); - fakeTextField._viewTextField = viewTextField; - fakeTextField._placeholder = opt.placeholder; - editField._fakeTextField = fakeTextField; + opt.editFontColor[3]*255, opt.editFontColor[4]*255); + local fakeTextField + if not opt.native then + fakeTextField = display.newText(editField, "", 0, 0, textFieldWidth, + lineHeight, opt.editFont, opt.editFontSize) + fakeTextField.anchorX = 0; + fakeTextField.x = textLabelX + textLabelWidth + widgetsWidthLeft + opt.fakeLabelXOffset ; + fakeTextField.y = yCenter + opt.fakeLabelYOffset ; + fakeTextField:setFillColor(unpack(opt.editFontColor)); + fakeTextField._viewTextField = viewTextField; + fakeTextField._placeholder = opt.placeholder; + editField._fakeTextField = fakeTextField; + end; if ( opt.listener and type(opt.listener) == "function" ) then viewTextField._listener = opt.listener end @@ -375,6 +387,9 @@ local function initEditField( editField, options ) editField._textLabelWidth = textLabelWidth editField.submitOnClear = opt.submitOnClear; editField.maxChars = opt.maxChars; + editField.allowedChars = opt.allowedChars; + + viewTextField._editField = editField; if "function" == type(opt.onClick) then editField._onClick = opt.onClick; @@ -391,21 +406,17 @@ local function initEditField( editField, options ) end local function onClearTap(event) - local function onClearClicked(event) - editField._clearButton.isVisible = false; - editField:updateFakeContent() - editField._clearClicked = false; - event.target = editField; - if editField._submitOnClear and editField._onSubmit then - editField._onSubmit(event); - end - - - end + editField._clearClicked = true; editField._textField.text = ""; - --android async handling of events - timer.performWithDelay(5, onClearClicked, 1) + + editField._clearButton.isVisible = false; + editField:updateFakeContent("") + editField._clearClicked = false; + event.target = editField; + if editField._submitOnClear and editField._onSubmit then + editField._onSubmit(event); + end return true; end @@ -416,89 +427,174 @@ local function initEditField( editField, options ) ---------------------------------------------------------- -- PUBLIC METHODS ---------------------------------------------------------- - function editField:updateFakeContent() + function editField:updateFakeContent(value) if self._fakingIt then local fakeTextField = self._fakeTextField; - local viewTextField = self._textField; - local text = viewTextField.text; + local text = value; if text:len() > 0 then - fakeTextField:setFillColor(unpack(opt.editFontColor)); - fakeTextField.text = viewTextField.text; + if not self.calibrating then + fakeTextField:setFillColor(unpack(opt.editFontColor)); + else + fakeTextField:setFillColor(1,0,0,1); + fakeTextField:toFront(); + end + if self.isSecure then + fakeTextField.text = string.rep("•", string.len(text)); + else + fakeTextField.text = text; + end else - fakeTextField:setFillColor(unpack(opt.editHintColor)); - fakeTextField.text = fakeTextField._placeholder; + if not self.calibrating then + fakeTextField:setFillColor(unpack(opt.editHintColor)); + fakeTextField.text = fakeTextField._placeholder; + else + fakeTextField:setFillColor(1,0,0,1); + fakeTextField:toFront(); + end + end end; end - function editField:_swapFakeField( fakeIt ) - local function onTransition(event) - self._slideTrans = nil; + function editField:slideBackKeyboard() + local slideGroup = self.slideGroup + + if slideGroup then + --check if we are in a scrollview + if self == slideGroup._slidingField then + if slideGroup.getContentPosition and slideGroup.scrollToPosition then + slideGroup:scrollToPosition({y=self._originalSlideY,time = self.keyboardSlideTime}) + else + transition.to(self.slideGroup,{y = self._originalSlideY,time=self.keyboardSlideTime}) + end + slideGroup._slidingField = nil; + else + if slideGroup._slidingField then + slideGroup._slidingField._originalSlideY = self._originalSlideY; + end + end + + end + end + + + function editField:slideForKeyboard() + local slideGroup = self.slideGroup; + if slideGroup then + local y = self.y; + local parent = self.parent; + while parent and parent.y do + y = y + parent.y; + parent = parent.parent + end + local top = y - self.contentHeight * self.anchorY; + local kbHeight = getKeyboardHeight(); + local desiredTop = display.contentHeight - kbHeight - self.contentHeight; + if top > desiredTop then + --check if we are in a scrollview + slideGroup._slidingField = self + if slideGroup.getContentPosition and slideGroup.scrollToPosition then + local xGroup, yGroup = slideGroup:getContentPosition() + local y = yGroup - (top - desiredTop) + self._originalSlideY = yGroup + slideGroup:scrollToPosition({y=y,time = self.keyboardSlideTime}) + else + local y = slideGroup.y - (top - desiredTop) + self._originalSlideY = slideGroup.y + transition.to(slideGroup,{y = y,time=self.keyboardSlideTime} ) + end + end end + end + + function editField:_swapFakeField( fakeIt ) + + local fakeTextField = self._fakeTextField; local viewTextField = self._textField; - if fakeIt then - if not self._fakingIt then - self._fakingIt = true; - self:updateFakeContent() - if self._originalSlideY and self.slideGroup then - transition.to(self.slideGroup,{y = self._originalSlideY,time=300, onComplete = onTransition}) - self._originalSlideY = nil; - end - fakeTextField.isVisible = true; - display.getCurrentStage():insert(viewTextField) - viewTextField.x = -1000; - viewTextField.y = -1000; - end - else + + local function showEditField(event) - _focusedField = viewTextField; self:insert(viewTextField) viewTextField.x = self._xOriginal; viewTextField.y = self._yOriginal; native.setKeyboardFocus( viewTextField ) - fakeTextField.isVisible = false; + fakeTextField.isVisible = self.calibrating; self._fakingIt = false; if self._clearButton then - self._clearButton.isVisible = string.len(viewTextField.text) == 0 + self._clearButton.isVisible = string.len(viewTextField.text) ~= 0 end; - --check if we need to slide - if self.slideGroup and self._originalSlideY == nil then - local y = self.y; - local parent = self.parent; - while parent and parent.y do - y = y + parent.y; - parent = parent.parent - end - local top = y - self.contentHeight / 2; - local kbHeight = getKeyboardHeight(); - local desiredTop = display.contentHeight - kbHeight - self.contentHeight; - if top > desiredTop then - self._originalSlideY = self.slideGroup.y; - transition.to(self.slideGroup,{y = self.slideGroup.y - (top - desiredTop),time=300}) - end - end + end + + if fakeIt then + if not self._fakingIt then + self._fakingIt = true; + self:updateFakeContent(viewTextField.text) + fakeTextField.isVisible = true; + + if not self.calibrating then + display.getCurrentStage():insert(viewTextField) + viewTextField.x = -1000; + viewTextField.y = -1000; + else + viewTextField.x = self._xOriginal; + viewTextField.y = self._yOriginal; + end; + end + else + showEditField() end end - function fakeTextField:touch(event) - local editField = self.parent; - if "began" == event.phase then + local function touchFakeLabel(event) + local phase = event.phase; + if "began" == phase then + --keep focus, since the field can be scrolling up + display.getCurrentStage():setFocus(fakeTextField); if editField._onClick == nil then editField:_swapFakeField( false ) else editField._onClick(event) end + elseif ( "ended" == phase or "off" == phase or "cancelled" == phase ) then + --release focus + display.getCurrentStage():setFocus(nil); + end; return true end + local function touchLabelText(event) + if editField._onClick then + editField._onClick(event) + end + end + local function onBackgroundTouch(event) + local phase = event.phase; + if "began" == phase then + --keep focus, since the field can be scrolling up + display.getCurrentStage():setFocus(editField); + elseif ( "ended" == phase or "off" == phase or "cancelled" == phase ) then + --release focus + display.getCurrentStage():setFocus(nil); + end + return true + end + if fakeTextField then + fakeTextField:addEventListener( "touch", touchFakeLabel ) + end; + + if fieldDescription then + fieldDescription:addEventListener( "touch", touchLabelText ) + end - fakeTextField:addEventListener( "touch" ) editField._fakingIt = false; - editField:_swapFakeField( true ) + if not editField.native then + editField:_swapFakeField( true ) + end + editField:addEventListener( "touch", onBackgroundTouch ) -- Function to listen for textbox events function viewTextField:_inputListener( event ) @@ -507,16 +603,29 @@ local function initEditField( editField, options ) end local phase = event.phase - local editField = self.parent; - if "editing" == phase then + local editField = self._editField; + + if "began" == phase then + _focusedField = self; + editField:slideForKeyboard() + elseif "editing" == phase then -- If there is one or more characters in the textField show the cancel button, if not hide it - local sText = editField._textField.text; + local sText = self.text; local textLen = string.len(sText); + if editField.allowedChars and event.newCharacters then + if not string.match(editField.allowedChars, event.newCharacters) then + --remove the offending character + self.text = string.gsub(sText, event.newCharacters,""); + end + end if editField.maxChars > 0 then if textLen > editField.maxChars then self.text = string.sub(sText, 1, editField.maxChars) end end + if editField.calibrating then + editField._fakeTextField.text = self.text; + end if editField._clearButton then editField._clearButton.isVisible = textLen > 0 end @@ -527,11 +636,15 @@ local function initEditField( editField, options ) elseif "submitted" == phase or "ended" == phase then -- Hide keyboard - if _focusedField == nil or _focusedField == self then + if _focusedField == nil or _focusedField == self and not editField.native then native.setKeyboardFocus( nil ) end; _focusedField = nil; - editField:_swapFakeField( true ) + if not editField.native then + editField:_swapFakeField( true ) + end + --if another sliding editField taes focus, leave him time to slide up + timer.performWithDelay(100, function () editField:slideBackKeyboard() end,1) if editField._onSubmit and (editField._clearButton == nil or phase == "submitted") then event.target = editField; editField._onSubmit(event); @@ -555,13 +668,23 @@ local function initEditField( editField, options ) function editField:setText(value) self._textField.text = value - self:updateFakeContent() + self:updateFakeContent(value) + --android sets text asynchroneously + end function editField:getText() return self._textField.text end + function editField:setValue(value) + self:setText(value) + end + + function editField:getValue() + return self:getText() + end + function editField:setReturnKey(value) self.returnKey = value; self._textField:setReturnKey(self.returnKey); @@ -615,6 +738,12 @@ local function initEditField( editField, options ) end + --create a hidden background to "eat" the touch events" + local bg = display.newRect(editField, opt.width / 2, opt.height / 2, opt.width, opt.height) + bg:setFillColor(0,0,0,0); + bg.isHitTestable = true; + bg:toBack() + bg:addEventListener("touch", function (event) return true; end) return editField end @@ -639,11 +768,11 @@ function M.new( options, theme ) opt.x = customOptions.x or nil opt.y = customOptions.y or nil if customOptions.x and customOptions.y then - opt.left = 0 - opt.top = 0 + opt.left = 0 + opt.top = 0 end opt.width = customOptions.width or 150 - opt.height = customOptions.height or 29 + opt.frame = customOptions.frame if opt.frame then @@ -663,24 +792,19 @@ function M.new( options, theme ) end; opt.id = customOptions.id - opt.baseDir = customOptions.baseDir or system.ResourceDirectory opt.placeholder = customOptions.placeholder or ""; opt.inputType = customOptions.inputType or "default" opt.isSecure = customOptions.isSecure or false; opt.returnKey = customOptions.returnKey or "done"; opt.onClick = customOptions.onClick; opt.required = customOptions.required or false; - if "Android" == system.getInfo("platformName") then - opt.textFieldYOffset = customOptions.textFieldYOffset or 4 - opt.textFieldXOffset = customOptions.textFieldXOffset or -5 - opt.fakeLabelShiftY = customOptions.fakeLabelShiftY or 0; - opt.fakeLabelShiftX = customOptions.fakeLabelShiftX or 4; - else - opt.textFieldYOffset = customOptions.textFieldYOffset or -2 - opt.textFieldXOffset = customOptions.textFieldXOffset or 0 - opt.fakeLabelShiftX = customOptions.fakeLabelShiftX or 2; - opt.fakeLabelShiftY = customOptions.fakeLabelShiftY or 1; - end + opt.textFieldYOffset = customOptions.textFieldYOffset or efDefaults.textFieldYOffset + opt.textFieldXOffset = customOptions.textFieldXOffset or efDefaults.textFieldXOffset + opt.fakeLabelYOffset = customOptions.fakeLabelYOffset or efDefaults.fakeLabelYOffset + opt.fakeLabelXOffset = customOptions.fakeLabelXOffset or efDefaults.fakeLabelXOffset + opt.textFieldHeightAdjust = customOptions.textFieldHeightAdjust or efDefaults.textFieldHeightAdjust + opt.fontScale = customOptions.fontScale or efDefaults.fontScale; + opt.calibrating = customOptions.calibrating opt.textFieldWidth = customOptions.textFieldWidth or 0; opt.listener = customOptions.listener @@ -704,12 +828,19 @@ function M.new( options, theme ) opt.widgets = customOptions.widgets or {}; opt.listButton = customOptions.listButton or false; opt.maxChars = customOptions.maxChars or 0; + opt.allowedChars = customOptions.allowedChars or nil; + if opt.allowedChars and string.len(opt.allowedChars)== 0 then + opt.allowedChars = nil; + end opt.buttonXOffset = customOptions.buttonXOffset or 0 opt.buttonYOffset = customOptions.buttonYOffset or 0 opt.editFont = customOptions.editFont or opt.labelFont opt.editFontSize = customOptions.editFontSize or opt.labelFontSize + opt.height = customOptions.height or (opt.editFontSize and opt.editFontSize + 12 or 29) + opt.native = customOptions.native or false opt.slideGroup = customOptions.slideGroup + opt.keyboardSlideTime = customOptions.keyboardSlideTime or 200 -- Left ( 9 piece set ) opt.topLeftFrame = customOptions.topLeftFrame or _widget._getFrameIndex( themeOptions, themeOptions.topLeftFrame ) @@ -745,7 +876,6 @@ function M.new( options, theme ) left = opt.left, top = opt.top, id = opt.id or "widget_editField", - baseDir = opt.baseDir, } From c1102e82608422e9eff4b4771148175809461b48 Mon Sep 17 00:00:00 2001 From: atanasster Date: Thu, 2 Jan 2014 09:41:32 -0500 Subject: [PATCH 14/55] widget_neweditfield Added editfield_calibrationdb.lua that contains the database of calibration data. - Changed the textfield offsets for Android devices to account for the adjusted height number, so now the offsets should be smaller - Changed the fontScale alto for Corona emulator. Unfortunately the Zooming of the emulator can not be retrieved, so to observe the real fontScaling, you would need to Zoom In until the Zoom In is greyed out (actual pixel size). If the emulator is zoomed at any level, it will display a wrong fontScale. - Fixed the double onSubmit events - Added androidKeyboardHeight to edit field defaults (defaults to 350 pixels) so user can change this setting in his app (like in main.lua file) - Added calibration string to send Email and save to file - this string can be copy-pasted into editfield_calibrationdb.lua - Fixed all known issues with scrolling of keyboard --- widgetLibrary/editfield_calibrationdb.lua | 17 ++++ widgetLibrary/editfield_defaults.lua | 47 +++++---- widgetLibrary/widget_editfield.lua | 116 +++++++++++++--------- 3 files changed, 115 insertions(+), 65 deletions(-) create mode 100644 widgetLibrary/editfield_calibrationdb.lua diff --git a/widgetLibrary/editfield_calibrationdb.lua b/widgetLibrary/editfield_calibrationdb.lua new file mode 100644 index 0000000..82dd8db --- /dev/null +++ b/widgetLibrary/editfield_calibrationdb.lua @@ -0,0 +1,17 @@ +local M = + +{ +["device-SAMSUNG-SGH-I896"] = { +fontScale = 1, +textFieldHeightAdjust = 12, +textFieldXOffset = 0, +textFieldYOffset = 0, +labelXoffset = 4, +labelYoffset = 1 +}, + + +} + +return M + diff --git a/widgetLibrary/editfield_defaults.lua b/widgetLibrary/editfield_defaults.lua index df5a516..2d3c49b 100644 --- a/widgetLibrary/editfield_defaults.lua +++ b/widgetLibrary/editfield_defaults.lua @@ -1,16 +1,19 @@ +local clbData = require("widgets.editfield_calibrationdb") + local M = {} +M.androidKeyboardHeight = 350 if "Android" == system.getInfo("platformName") then - M.textFieldYOffset = 6 - M.textFieldXOffset = -5 - M.fakeLabelYOffset = 1 - M.fakeLabelXOffset = 4 + M.textFieldYOffset = 0 + M.textFieldXOffset = 0 + M.fakeLabelYOffset = 2 + M.fakeLabelXOffset = 3 M.textFieldHeightAdjust = 12 elseif system.getInfo("environment") == "simulator" then - M.textFieldYOffset = -3 + M.textFieldYOffset = -1 M.textFieldXOffset = 0 M.fakeLabelYOffset = 0 - M.fakeLabelXOffset = 2 + M.fakeLabelXOffset = 1 M.textFieldHeightAdjust = 0; else M.textFieldYOffset = 0 @@ -20,15 +23,13 @@ else M.textFieldHeightAdjust = 0; end -local function calcFontSize(targetFontSize) +function M:calcFontSize() local sysType = system.getInfo("architectureInfo") local environment = system.getInfo("environment") - local fontScale = (display.pixelWidth / display.contentWidth) * display.contentScaleX; - if display.pixelWidth == display.contentWidth then - fontScale = 1; - end + --local fontScale = (display.pixelWidth / display.contentWidth) * display.contentScaleX; + local fontScale = (( display.contentWidth - (display.screenOriginX * 2) ) / display.contentScaleX) / display.contentWidth if system.getInfo("platformName") == "Android" then - fontScale = (display.pixelWidth / display.contentWidth) * 0.5; + fontScale = (display.pixelWidth / display.contentWidth) * 0.5; elseif environment ~= "simulator" then if string.match(system.getInfo("model"),"iPa") then --iPads @@ -46,7 +47,7 @@ local function calcFontSize(targetFontSize) end function M:robMiracleCalcFontSize() - return ( display.pixelWidth / display.contentWidth ) * 0.5 + return ( display.pixelWidth / display.contentWidth ) * 0.5 end function M:mpappasCalcFontSize() @@ -68,9 +69,9 @@ function M:mpappasCalcFontSize() --print(" -- original height == ", heightIn) if heightIn ~= nil then heightIn = heightIn - missingInches - - --Make sure its not nil... e.g. the simulator will return nil, perhaps some bad devices will too... - + + --Make sure its not nil... e.g. the simulator will return nil, perhaps some bad devices will too... + -- heightIn is height of actual droid app is running on fontScale = heightIn / 3.0 -- 3.0 is actual iPhone 3gs /4 /4s height --print(" -- fontsize set on actual droid screen inch height") @@ -116,7 +117,19 @@ function M:mpappasCalcFontSize() end -M.fontScale = calcFontSize() +M.fontScale = M:calcFontSize() + +local calibration = clbData[system.getInfo( "environment").."-".. system.getInfo("model")] +if calibration then + M.fontScale = calibration.fontScale + M.textFieldHeightAdjust = calibration.textFieldHeightAdjust + M.textFieldYOffset = calibration.textFieldYOffset + M.textFieldXOffset = calibration.textFieldXOffset + M.fakeLabelYOffset = calibration.labelYoffset + M.fakeLabelXOffset = calibration.labelXoffset + + +end return M diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index c54b5c6..cc38e0e 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -69,7 +69,7 @@ local function getKeyboardHeight() else --dear android - return math.min(350, display.contentHeight / 2); + return math.min(efDefaults.androidKeyboardHeight, display.contentHeight / 2); end end -- Creates a new edit field from an image @@ -321,12 +321,12 @@ local function initEditField( editField, options ) textFieldWidth = (xEnd - xStart) - widgetsWidthLeft - widgetsWidthRight -opt.textFieldXOffset - textLabelWidth - 2* opt.spacing; end - local textFieldHeight = height; + --calculate textheight for selected font local tmpField = display.newText("W",0,0,opt.editFont,opt.editFontSize) local lineHeight = tmpField.contentHeight; tmpField:removeSelf(); - editField._xOriginal = textLabelX + textLabelWidth + opt.textFieldXOffset + widgetsWidthLeft - editField._yOriginal = yCenter + opt.textFieldYOffset + editField._xOriginal = textLabelX - opt.textFieldHeightAdjust/2 + textLabelWidth + opt.textFieldXOffset + widgetsWidthLeft + editField._yOriginal = yCenter + opt.textFieldHeightAdjust/2 + opt.textFieldYOffset if opt.native then viewTextField = native.newTextField(editField._xOriginal, editField._yOriginal, textFieldWidth,lineHeight + opt.textFieldHeightAdjust ) viewTextField.placeholder = opt.placeholder; @@ -407,14 +407,13 @@ local function initEditField( editField, options ) local function onClearTap(event) - editField._clearClicked = true; editField._textField.text = ""; editField._clearButton.isVisible = false; editField:updateFakeContent("") - editField._clearClicked = false; + editField._textField._originalText = "" event.target = editField; - if editField._submitOnClear and editField._onSubmit then + if editField.submitOnClear and editField._onSubmit then editField._onSubmit(event); end @@ -462,23 +461,35 @@ local function initEditField( editField, options ) if slideGroup then --check if we are in a scrollview if self == slideGroup._slidingField then - if slideGroup.getContentPosition and slideGroup.scrollToPosition then - slideGroup:scrollToPosition({y=self._originalSlideY,time = self.keyboardSlideTime}) - else - transition.to(self.slideGroup,{y = self._originalSlideY,time=self.keyboardSlideTime}) - end - slideGroup._slidingField = nil; + self:setSlideGroupPosition(slideGroup._originalSlideY) + slideGroup._slidingField = nil + slideGroup._originalSlideY = nil else - if slideGroup._slidingField then - slideGroup._slidingField._originalSlideY = self._originalSlideY; - end end - end end + function editField:getSlideGroupPosition() + local slideGroup = self.slideGroup; + local xGroup, yGroup + if slideGroup.getContentPosition and slideGroup.scrollToPosition then + xGroup, yGroup = slideGroup:getContentPosition() + else + yGroup = slideGroup.y; + end + return yGroup + end - function editField:slideForKeyboard() + function editField:setSlideGroupPosition(yGroup) + local slideGroup = self.slideGroup; + if slideGroup.getContentPosition and slideGroup.scrollToPosition then + slideGroup:scrollToPosition({y=yGroup,time = self.keyboardSlideTime}) + else + transition.to(slideGroup,{y = yGroup,time=self.keyboardSlideTime} ) + end + end + + function editField:slideForKeyboard(neededHeight) local slideGroup = self.slideGroup; if slideGroup then local y = self.y; @@ -487,22 +498,24 @@ local function initEditField( editField, options ) y = y + parent.y; parent = parent.parent end - local top = y - self.contentHeight * self.anchorY; - local kbHeight = getKeyboardHeight(); + local yGroup = self:getSlideGroupPosition() + local groupOffset = 0 + --if the group is already slid up, check difference + if slideGroup._originalSlideY then + groupOffset = (slideGroup._originalSlideY - yGroup) + end + local top = y - self.contentHeight * self.anchorY + groupOffset; + + + local kbHeight = neededHeight or getKeyboardHeight(); local desiredTop = display.contentHeight - kbHeight - self.contentHeight; if top > desiredTop then - --check if we are in a scrollview + local y = yGroup - (top - desiredTop) + groupOffset + if not slideGroup._slidingField then + slideGroup._originalSlideY = yGroup + end + self:setSlideGroupPosition(y) slideGroup._slidingField = self - if slideGroup.getContentPosition and slideGroup.scrollToPosition then - local xGroup, yGroup = slideGroup:getContentPosition() - local y = yGroup - (top - desiredTop) - self._originalSlideY = yGroup - slideGroup:scrollToPosition({y=y,time = self.keyboardSlideTime}) - else - local y = slideGroup.y - (top - desiredTop) - self._originalSlideY = slideGroup.y - transition.to(slideGroup,{y = y,time=self.keyboardSlideTime} ) - end end end end @@ -566,9 +579,9 @@ local function initEditField( editField, options ) end local function touchLabelText(event) - if editField._onClick then - editField._onClick(event) - end + if editField._onClick then + editField._onClick(event) + end end local function onBackgroundTouch(event) local phase = event.phase; @@ -598,15 +611,29 @@ local function initEditField( editField, options ) -- Function to listen for textbox events function viewTextField:_inputListener( event ) + local editField = self._editField; + local phase = event.phase + + --async called on Submit in case other edit field is taking focus local function onHideField(event) - + if _focusedField == nil or _focusedField == self then + native.setKeyboardFocus( nil ) + _focusedField = nil; + end; + editField:slideBackKeyboard() + --phase submitted + if editField._onSubmit and (phase == "submitted" or phase == "ended" and self.text ~= self._originalText) then + event.target = editField + self._originalText = self.text + editField._onSubmit(event) + end + --phase ended - send onSubmit only if the text is different end - local phase = event.phase - local editField = self._editField; - + print(phase) if "began" == phase then _focusedField = self; + self._originalText = self.text editField:slideForKeyboard() elseif "editing" == phase then -- If there is one or more characters in the textField show the cancel button, if not hide it @@ -636,19 +663,12 @@ local function initEditField( editField, options ) elseif "submitted" == phase or "ended" == phase then -- Hide keyboard - if _focusedField == nil or _focusedField == self and not editField.native then - native.setKeyboardFocus( nil ) - end; - _focusedField = nil; + timer.performWithDelay(100,onHideField ,1) + if not editField.native then editField:_swapFakeField( true ) end - --if another sliding editField taes focus, leave him time to slide up - timer.performWithDelay(100, function () editField:slideBackKeyboard() end,1) - if editField._onSubmit and (editField._clearButton == nil or phase == "submitted") then - event.target = editField; - editField._onSubmit(event); - end + end -- If there is a listener defined, execute it From dc87a01af2e2c022bfa62e2f47defaf1e41b3db7 Mon Sep 17 00:00:00 2001 From: atanasster Date: Thu, 2 Jan 2014 13:25:55 -0500 Subject: [PATCH 15/55] fixes --- widgetLibrary/editfield_defaults.lua | 2 ++ widgetLibrary/widget_editfield.lua | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/widgetLibrary/editfield_defaults.lua b/widgetLibrary/editfield_defaults.lua index 2d3c49b..998dd71 100644 --- a/widgetLibrary/editfield_defaults.lua +++ b/widgetLibrary/editfield_defaults.lua @@ -39,6 +39,8 @@ function M:calcFontSize() else fontScale = 1 / display.contentScaleY end + else + fontScale = (display.pixelHeight / display.contentHeight) * 0.5; end end diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index cc38e0e..5c36090 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -630,7 +630,6 @@ local function initEditField( editField, options ) --phase ended - send onSubmit only if the text is different end - print(phase) if "began" == phase then _focusedField = self; self._originalText = self.text From 26043e47499341ff7324a7dd94c970cac65a7441 Mon Sep 17 00:00:00 2001 From: atanasster Date: Fri, 3 Jan 2014 15:23:35 -0500 Subject: [PATCH 16/55] fixes --- widgetLibrary/editfield_defaults.lua | 8 +++++++- widgetLibrary/widget_editfield.lua | 10 +++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/widgetLibrary/editfield_defaults.lua b/widgetLibrary/editfield_defaults.lua index 998dd71..7dcf90c 100644 --- a/widgetLibrary/editfield_defaults.lua +++ b/widgetLibrary/editfield_defaults.lua @@ -30,7 +30,12 @@ function M:calcFontSize() local fontScale = (( display.contentWidth - (display.screenOriginX * 2) ) / display.contentScaleX) / display.contentWidth if system.getInfo("platformName") == "Android" then fontScale = (display.pixelWidth / display.contentWidth) * 0.5; - elseif environment ~= "simulator" then + elseif environment == "simulator" then + --in Corona simulator, check if its a tall device, which is probably Zoomed out + if display.pixelHeight > 1000 then + fontScale = fontScale * .5 + end + else if string.match(system.getInfo("model"),"iPa") then --iPads if display.pixelHeight == 2048 then @@ -42,6 +47,7 @@ function M:calcFontSize() else fontScale = (display.pixelHeight / display.contentHeight) * 0.5; end + end return fontScale diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 5c36090..0297347 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -430,7 +430,7 @@ local function initEditField( editField, options ) if self._fakingIt then local fakeTextField = self._fakeTextField; local text = value; - if text:len() > 0 then + if text and text:len() > 0 then if not self.calibrating then fakeTextField:setFillColor(unpack(opt.editFontColor)); else @@ -623,8 +623,8 @@ local function initEditField( editField, options ) editField:slideBackKeyboard() --phase submitted if editField._onSubmit and (phase == "submitted" or phase == "ended" and self.text ~= self._originalText) then - event.target = editField self._originalText = self.text + event.target = editField editField._onSubmit(event) end --phase ended - send onSubmit only if the text is different @@ -633,6 +633,7 @@ local function initEditField( editField, options ) if "began" == phase then _focusedField = self; self._originalText = self.text + self._editing = true; editField:slideForKeyboard() elseif "editing" == phase then -- If there is one or more characters in the textField show the cancel button, if not hide it @@ -662,7 +663,10 @@ local function initEditField( editField, options ) elseif "submitted" == phase or "ended" == phase then -- Hide keyboard - timer.performWithDelay(100,onHideField ,1) + if self._editing then + timer.performWithDelay(100,onHideField ,1) + self._editing = false; + end if not editField.native then editField:_swapFakeField( true ) From 0f87bd666282b35bf06ac245d08d36ef4f5cc32d Mon Sep 17 00:00:00 2001 From: atanasster Date: Mon, 6 Jan 2014 18:21:16 -0500 Subject: [PATCH 17/55] widget.newPanel --- widgetLibrary/widget_panel.lua | 1205 ++++++++++++++++++++++++++++++++ 1 file changed, 1205 insertions(+) create mode 100644 widgetLibrary/widget_panel.lua diff --git a/widgetLibrary/widget_panel.lua b/widgetLibrary/widget_panel.lua new file mode 100644 index 0000000..977c563 --- /dev/null +++ b/widgetLibrary/widget_panel.lua @@ -0,0 +1,1205 @@ + +local M = +{ + _options = {}, + _widgetName = "widget.newPanel", +} + + +-- Require needed widget files +local _widget = require( "widget" ) + +-- define a default color set for both graphics modes +local panelDefault = { 0, 0, 0 } + +local shapeStrokeDefault = { 0, 0, 0 }; +local shapeFillDefault = { 0.8, 0.8, 0.8 }; + + +-- Function to handle touches on a widget panel, function is common to all widget panel creation types (ie image files, imagesheet, and 9 slice panel creation) +local function managePanelTouch( view, event ) + local phase = event.phase + + -- If the panel isn't active, just return + if not view._isEnabled then + return + end + + if "began" == phase then + -- Create the alpha fade if ios7 + + -- If there is a onPress method ( and not a onEvent method ) + if view._onPress and not view._onEvent then + view._onPress( event ) + end + + -- If the parent group still exists + if "table" == type( view.parent ) then + -- Set focus on the panel + view._isFocus = true + display.getCurrentStage():setFocus( view, event.id ) + + end + + elseif view._isFocus then + if "moved" == phase then + if not _widget._isWithinBounds( view, event ) then + + + else + + end + + elseif "ended" == phase or "cancelled" == phase then + if _widget._isWithinBounds( view, event ) then + -- If there is a onRelease method ( and not a onEvent method ) + if view._onRelease and not view._onEvent then + view._onRelease( event ) + end + end + + -- Remove focus from the panel + view._isFocus = false + display.getCurrentStage():setFocus( nil ) + end + end + + -- If there is a onEvent method ( and not a onPress or onRelease method ) + if view._onEvent and not view._onPress and not view._onRelease then + if not _widget._isWithinBounds( view, event ) and "ended" == phase then + event.phase = "cancelled" + + end + + view._onEvent( event ) + end +end + + +------------------------------------------------------------------------ +-- Text only panel +------------------------------------------------------------------------ +local function createUsingText( panel, options ) + -- Create a local reference to our options table + local opt = options + + -- Forward references + local view + local rect = nil; + local shape = opt.shape; + if shape then + + rect = display.newRoundedRect( panel, panel.x, panel.y, opt.width , opt.height , shape.cornerRadius); + rect.strokeWidth = shape.strokeWidth or 1; + rect:setStrokeColor(unpack(shape.strokeColor)); + rect:setFillColor(unpack(shape.fillColor)); + end + local viewLabel; + -- Create the label (either embossed or standard) + if opt.embossedLabel then + viewLabel = display.newEmbossedText( panel, opt.label, 0, 0, opt.font, opt.fontSize ) + else + viewLabel = display.newText( panel, opt.label, 0, 0, opt.font, opt.fontSize ) + end + + if rect then + view = rect; + view._shapeColor = shape.fillColor; + view._strokeColor = shape.strokeColor; + view._label = viewLabel; + + else + view = viewLabel; + end + viewLabel:setFillColor( unpack( opt.labelColor) ) + view._labelColor = opt.labelColor + + ---------------------------------- + -- Positioning + ---------------------------------- + + -- Labels position + if "center" == opt.labelAlign then + viewLabel.x = view.x + opt.labelXOffset + elseif "left" == opt.labelAlign then + viewLabel.x = view.x - ( view.contentWidth * 0.5 ) + ( viewLabel.contentWidth * 0.5 ) + opt.labelXOffset + elseif "right" == opt.labelAlign then + viewLabel.x = view.x + ( view.contentWidth * 0.5 ) - ( viewLabel.contentWidth * 0.5 ) + opt.labelXOffset + end + + + if "center" == opt.labelAlignY then + viewLabel.y = view.y + opt.labelYOffset + elseif "top" == opt.labelAlignY then + viewLabel.y = view.y - ( view.contentHeight * 0.5 ) + ( viewLabel.contentHeight * 0.5 ) + opt.labelYOffset + elseif "bottom" == opt.labelAlignY then + + viewLabel.y = view.y + ( view.contentHeight * 0.5 ) - ( viewLabel.contentHeight * 0.5 ) + opt.labelYOffset + end + + + ------------------------------------------------------- + -- Assign properties/objects to the view + ------------------------------------------------------- + + view._isEnabled = opt.isEnabled + viewLabel._fontSize = opt.fontSize + viewLabel._labelColor = view._labelColor + + -- Methods + view._onPress = opt.onPress + view._onRelease = opt.onRelease + view._onEvent = opt.onEvent + + ------------------------------------------------------- + -- Assign properties/objects to the panel + ------------------------------------------------------- + + -- Assign objects to the panel + panel._view = view + + ---------------------------------------------------------- + -- PUBLIC METHODS + ---------------------------------------------------------- + + -- Function to set the panels text color + function panel:setFillColor( ... ) + if self._label then + self._view._label:setFillColor( ... ) + else + self._view:setFillColor( ... ) + end; + end + + -- Function to set the panel's label + function panel:setLabel( newLabel ) + return self._view:_setLabel( newLabel ) + end + + -- Function to get the panel's label + function panel:getLabel() + return self._view:_getLabel() + end + + -- Function to set a panel as active + function panel:setEnabled( isEnabled ) + self._view._isEnabled = isEnabled + end + + -- Touch listener for our panel + function view:touch( event ) + -- Set the target to the view's parent group (the panel object) + event.target = self.parent + + -- Manage touch events on the panel + managePanelTouch( self, event ) + + return true + end + + view:addEventListener( "touch" ) + + ---------------------------------------------------------- + -- PRIVATE METHODS + ---------------------------------------------------------- + + -- Function to set the panel's label + function view:_setLabel( newLabel ) + -- Update the label's text + if "function" == type( self.setText ) or self._label then + if self._label then + self._label:setText( newLabel ) + else + self:setText( newLabel ) + end + else + self.text = newLabel + end + end + + -- Function to get the panel's label + function view:_getLabel() + return self._label.text + end + + + -- Finalize function + function panel:_finalize() + end + + return panel +end + + +------------------------------------------------------------------------ +-- Image Files Panel +------------------------------------------------------------------------ + +-- Creates a new panel from single png images +local function createUsingImageFiles( panel, options ) + -- Create a local reference to our options table + local opt = options + + -- Forward references + local view, viewLabel + + -- Create the view + if opt.width and opt.height then + view = display.newImageRect( panel, opt.defaultFile, opt.baseDir, opt.width, opt.height ) + else + view = display.newImage( panel, opt.defaultFile, opt.baseDir ) + end + + + -- Create the label (either embossed or standard) + if opt.embossedLabel then + viewLabel = display.newEmbossedText( panel, opt.label, 0, 0, opt.font, opt.fontSize ) + else + viewLabel = display.newText( panel, opt.label, 0, 0, opt.font, opt.fontSize ) + end + + ---------------------------------- + -- Positioning + ---------------------------------- + + -- The view + view.x = panel.x + ( view.contentWidth * 0.5 ) + view.y = panel.y + ( view.contentHeight * 0.5 ) + + + -- Setup the label + viewLabel:setFillColor( unpack( opt.labelColor) ) + viewLabel._isLabel = true + viewLabel._labelColor = opt.labelColor + + + -- Labels position + if "center" == opt.labelAlign then + viewLabel.x = view.x + opt.labelXOffset + elseif "left" == opt.labelAlign then + viewLabel.x = view.x - ( view.contentWidth * 0.5 ) + ( viewLabel.contentWidth * 0.5 ) + opt.labelXOffset + elseif "right" == opt.labelAlign then + viewLabel.x = view.x + ( view.contentWidth * 0.5 ) - ( viewLabel.contentWidth * 0.5 ) + opt.labelXOffset + end + + + if "center" == opt.labelAlignY then + viewLabel.y = view.y + opt.labelYOffset + elseif "top" == opt.labelAlignY then + viewLabel.y = view.y - ( view.contentHeight * 0.5 ) + ( viewLabel.contentHeight * 0.5 ) + opt.labelYOffset + elseif "bottom" == opt.labelAlignY then + + viewLabel.y = view.y + ( view.contentHeight * 0.5 ) - ( viewLabel.contentHeight * 0.5 ) + opt.labelYOffset + end + + ------------------------------------------------------- + -- Assign properties/objects to the view + ------------------------------------------------------- + + view._isEnabled = opt.isEnabled + view._fontSize = opt.fontSize + view._label = viewLabel + view._labelColor = viewLabel._labelColor + view._labelAlign = opt.labelAlign + view._labelXOffset = opt.labelXOffset + view._labelYOffset = opt.labelYOffset + + -- Methods + view._onPress = opt.onPress + view._onRelease = opt.onRelease + view._onEvent = opt.onEvent + + ------------------------------------------------------- + -- Assign properties/objects to the panel + ------------------------------------------------------- + + -- Assign objects to the panel + panel._view = view + + ---------------------------------------------------------- + -- PUBLIC METHODS + ---------------------------------------------------------- + + -- Function to set the panels fill color + function panel:setFillColor( ... ) + self._view:setFillColor( ... ) + + end + + -- Function to set the panel's label + function panel:setLabel( newLabel ) + return self._view:_setLabel( newLabel ) + end + + -- Function to get the panel's label + function panel:getLabel() + return self._view:_getLabel() + end + + -- Function to set a panel as active + function panel:setEnabled( isEnabled ) + self._view._isEnabled = isEnabled + end + + -- Touch listener for our panel + function view:touch( event ) + -- Set the target to the view's parent group (the panel object) + event.target = self.parent + + -- Manage touch events on the panel + managePanelTouch( self, event ) + + return true + end + + view:addEventListener( "touch" ) + + ---------------------------------------------------------- + -- PRIVATE METHODS + ---------------------------------------------------------- + + -- Function to set the panel's label + function view:_setLabel( newLabel ) + -- Update the label's text + if "function" == type( self._label.setText ) then + self._label:setText( newLabel ) + else + self._label.text = newLabel + end + + -- Labels position + if "center" == opt.labelAlign then + viewLabel.x = view.x + opt.labelXOffset + elseif "left" == opt.labelAlign then + viewLabel.x = view.x - ( view.contentWidth * 0.5 ) + ( viewLabel.contentWidth * 0.5 ) + opt.labelXOffset + elseif "right" == opt.labelAlign then + viewLabel.x = view.x + ( view.contentWidth * 0.5 ) - ( viewLabel.contentWidth * 0.5 ) + opt.labelXOffset + end + + + if "center" == opt.labelAlignY then + viewLabel.y = view.y + opt.labelYOffset + elseif "top" == opt.labelAlignY then + viewLabel.y = view.y - ( view.contentHeight * 0.5 ) + ( viewLabel.contentHeight * 0.5 ) + opt.labelYOffset + elseif "bottom" == opt.labelAlignY then + + viewLabel.y = view.y + ( view.contentHeight * 0.5 ) - ( viewLabel.contentHeight * 0.5 ) + opt.labelYOffset + end + + end + + -- Function to get the panel's label + function view:_getLabel() + return self._label.text + end + + + -- Finalize function + function panel:_finalize() + end + + return panel +end + + +------------------------------------------------------------------------ +-- Image Sheet (2 Frame) Panel +------------------------------------------------------------------------ + +-- Creates a new panel from a sprite (imageSheet) +local function createUsingImageSheet( panel, options ) + -- Create a local reference to our options table + local opt = options + + -- Animation options + local sheetOptions = + { + { + name = "default", + start = opt.defaultFrame, + count = 1, + }, + } + + -- Forward references + local view, viewLabel, imageSheet + + -- Create a reference to the imageSheet + imageSheet = opt.sheet + + -- Create the view + view = display.newSprite( panel, imageSheet, sheetOptions ) + + -- Create the label (either embossed or standard) + if opt.embossedLabel then + viewLabel = display.newEmbossedText( panel, opt.label, 0, 0, opt.font, opt.fontSize ) + else + viewLabel = display.newText( panel, opt.label, 0, 0, opt.font, opt.fontSize ) + end + + ---------------------------------- + -- Positioning + ---------------------------------- + + -- The view + view.x = panel.x + ( view.contentWidth * 0.5 ) + view.y = panel.y + ( view.contentHeight * 0.5 ) + + -- Setup the label + viewLabel:setFillColor( unpack( opt.labelColor) ) + viewLabel._isLabel = true + viewLabel._labelColor = opt.labelColor + + + -- Labels position + if "center" == opt.labelAlign then + viewLabel.x = view.x + opt.labelXOffset + elseif "left" == opt.labelAlign then + viewLabel.x = view.x - ( view.contentWidth * 0.5 ) + ( viewLabel.contentWidth * 0.5 ) + opt.labelXOffset + elseif "right" == opt.labelAlign then + viewLabel.x = view.x + ( view.contentWidth * 0.5 ) - ( viewLabel.contentWidth * 0.5 ) + opt.labelXOffset + end + + + if "center" == opt.labelAlignY then + viewLabel.y = view.y + opt.labelYOffset + elseif "top" == opt.labelAlignY then + viewLabel.y = view.y - ( view.contentHeight * 0.5 ) + ( viewLabel.contentHeight * 0.5 ) + opt.labelYOffset + elseif "bottom" == opt.labelAlignY then + + viewLabel.y = view.y + ( view.contentHeight * 0.5 ) - ( viewLabel.contentHeight * 0.5 ) + opt.labelYOffset + end + + + ------------------------------------------------------- + -- Assign properties/objects to the view + ------------------------------------------------------- + + view._isEnabled = opt.isEnabled + view._fontSize = opt.fontSize + view._label = viewLabel + view._labelColor = viewLabel._labelColor + view._labelAlign = opt.labelAlign + + view._labelXOffset = opt.labelXOffset + view._labelYOffset = opt.labelYOffset + + -- Methods + view._onPress = opt.onPress + view._onRelease = opt.onRelease + view._onEvent = opt.onEvent + + ------------------------------------------------------- + -- Assign properties/objects to the panel + ------------------------------------------------------- + + -- Assign objects to the panel + panel._imageSheet = imageSheet + panel._view = view + + ---------------------------------------------------------- + -- PUBLIC METHODS + ---------------------------------------------------------- + + -- Function to set the panels fill color + function panel:setFillColor( ... ) + self._view:setFillColor( ... ) + end + + -- Function to set the panel's label + function panel:setLabel( newLabel ) + return self._view:_setLabel( newLabel ) + end + + -- Function to get the panel's label + function panel:getLabel() + return self._view:_getLabel() + end + + -- Function to set a panel as active + function panel:setEnabled( isEnabled ) + self._view._isEnabled = isEnabled + end + + -- Touch listener for our panel + function view:touch( event ) + -- Set the target to the view's parent group (the panel object) + event.target = self.parent + + -- Manage touch events on the panel + managePanelTouch( self, event ) + + return true + end + + view:addEventListener( "touch" ) + + ---------------------------------------------------------- + -- PRIVATE METHODS + ---------------------------------------------------------- + + -- Function to set the panel's label + function view:_setLabel( newLabel ) + -- Update the label's text + if "function" == type( self._label.setText ) then + self._label:setText( newLabel ) + else + self._label.text = newLabel + end + + -- Labels position + if "center" == opt.labelAlign then + viewLabel.x = view.x + opt.labelXOffset + elseif "left" == opt.labelAlign then + self._label.x = view.x - ( view.contentWidth * 0.5 ) + ( self._label.contentWidth * 0.5 ) + opt.labelXOffset + elseif "right" == opt.labelAlign then + self._label.x = view.x + ( view.contentWidth * 0.5 ) - ( self._label.contentWidth * 0.5 ) + opt.labelXOffset + end + + + if "center" == opt.labelAlignY then + self._label.y = view.y + opt.labelYOffset + elseif "top" == opt.labelAlignY then + self._label.y = view.y - ( view.contentHeight * 0.5 ) + ( self._label.contentHeight * 0.5 ) + opt.labelYOffset + elseif "bottom" == opt.labelAlignY then + + self._label.y = view.y + ( view.contentHeight * 0.5 ) - ( self._label.contentHeight * 0.5 ) + opt.labelYOffset + end + + -- Update the label's y position + self._label.y = self._label.y + end + + -- Function to get the panel's label + function view:_getLabel() + return self._label.text + end + + -- Finalize function + function panel:_finalize() + -- Set the ImageSheet to nil + self._imageSheet = nil + end + + return panel +end + + +------------------------------------------------------------------------ +-- Image Sheet (9 piece/slice) Panel +------------------------------------------------------------------------ + +-- Creates a new panel from a 9 piece sprite +local function createUsing9Slice( panel, options ) + -- Create a local reference to our options table + local opt = options + + -- Forward references + local imageSheet, view, viewLabel + + local viewTopLeft, viewMiddleLeft, viewBottomLeft + local viewTopMiddle, viewMiddle, viewBottomMiddle + local viewTopRight, viewMiddleRight, viewBottomRight + local viewTopPointer, viewLabelLeft, viewLabelMiddle, viewLabelRight + + -- Create the imageSheet + if opt.sheet then + imageSheet = opt.sheet + else + local themeData = require( opt.themeData ) + imageSheet = graphics.newImageSheet( opt.themeSheetFile, themeData:getSheet() ) + end + + -- The view is the panel (group) + view = panel + + -- Imagesheet options + local sheetOptions = + { + -- Top Left + viewTopLeft = + { + { + --name = "default", + start = opt.topLeftFrame, + count = 1, + }, + + + }, + + -- Middle Left + viewMiddleLeft = + { + { + --name = "default", + start = opt.middleLeftFrame, + count = 1, + }, + + }, + + -- Bottom Left + viewBottomLeft = + { + { + --name = "default", + start = opt.bottomLeftFrame, + count = 1, + }, + + }, + + -- Top Middle + viewTopMiddle = + { + { + --name = "default", + start = opt.topMiddleFrame, + count = 1, + }, + + }, + viewTopPointer= + { + { + --name = "default", + start = opt.topPointerFrame, + count = 1, + }, + + }, + + -- Middle + viewMiddle = + { + { + --name = "default", + start = opt.middleFrame, + count = 1, + }, + + }, + + -- Bottom Middle + viewBottomMiddle = + { + { + --name = "default", + start = opt.bottomMiddleFrame, + count = 1, + }, + + }, + + + -- Top Right + viewTopRight = + { + { + --name = "default", + start = opt.topRightFrame, + count = 1, + }, + + }, + + -- Middle Right + viewMiddleRight = + { + { + --name = "default", + start = opt.middleRightFrame, + count = 1, + }, + + }, + + -- Bottom Right + viewBottomRight = + { + { + --name = "default", + start = opt.bottomRightFrame, + count = 1, + }, + + }, + } + + + -- Create the left portion of the panel + viewTopLeft = display.newSprite( panel, imageSheet, sheetOptions.viewTopLeft ) + viewMiddleLeft = display.newSprite( panel, imageSheet, sheetOptions.viewMiddleLeft ) + viewBottomLeft = display.newSprite( panel, imageSheet, sheetOptions.viewBottomLeft ) + + -- Create the right portion of the panel + viewTopRight = display.newSprite( panel, imageSheet, sheetOptions.viewTopRight ) + viewMiddleRight = display.newSprite( panel, imageSheet, sheetOptions.viewMiddleRight ) + viewBottomRight = display.newSprite( panel, imageSheet, sheetOptions.viewBottomRight ) + + -- Create the middle portion of the panel + viewTopMiddle = display.newSprite( panel, imageSheet, sheetOptions.viewTopMiddle ) + if opt.pointerX then + viewTopMiddle2 = display.newSprite( panel, imageSheet, sheetOptions.viewTopMiddle ) + viewPointer = display.newSprite( panel, imageSheet, sheetOptions.viewTopPointer ) + end + viewMiddle = display.newSprite( panel, imageSheet, sheetOptions.viewMiddle ) + viewBottomMiddle = display.newSprite( panel, imageSheet, sheetOptions.viewBottomMiddle ) + + -- Create the label (either embossed or standard) + if opt.embossedLabel then + viewLabel = display.newEmbossedText( panel, opt.label, 0, 0, opt.font, opt.fontSize ) + else + viewLabel = display.newText( panel, opt.label, 0, 0, opt.font, opt.fontSize ) + end + + ---------------------------------- + -- Positioning + ---------------------------------- + + -- Top + viewTopLeft.x = panel.x + ( viewTopLeft.contentWidth * 0.5 ) + viewTopLeft.y = panel.y + ( viewTopLeft.contentHeight * 0.5 ) + local middleWidth = opt.width - ( viewTopLeft.contentWidth + viewTopRight.contentWidth ); + + if opt.pointerX then + viewPointer.x = panel.x + opt.pointerX; + viewPointer.y = viewPointer.contentHeight / 2 + viewTopMiddle.width = math.max(opt.pointerX - viewTopLeft.contentWidth - viewPointer.contentWidth / 2, + viewTopMiddle.contentWidth); + + + viewTopMiddle2.width = opt.width - viewTopRight.contentWidth - viewTopLeft.contentWidth - + viewPointer.contentHeight - viewTopMiddle.width; + + viewTopMiddle2.x = viewPointer.x + viewPointer.contentWidth / 2 + viewTopMiddle2.contentWidth / 2; + viewTopMiddle2.y = viewTopMiddle2.contentHeight / 2; + else + + viewTopMiddle.width = middleWidth + end + viewTopMiddle.y = viewTopMiddle.contentHeight / 2; + viewTopMiddle.x = viewTopLeft.x + ( viewTopLeft.contentWidth * 0.5 ) + ( viewTopMiddle.contentWidth * 0.5 ) + viewTopRight.x = panel.x + opt.width - ( viewTopRight.contentWidth * 0.5 ) + viewTopRight.y = viewTopLeft.y + + -- Middle + viewMiddleLeft.height = opt.height - ( viewTopLeft.contentHeight + viewTopRight.contentHeight ) + viewMiddleLeft.x = viewTopLeft.x + viewMiddleLeft.y = viewTopLeft.y + ( viewMiddleLeft.contentHeight * 0.5 ) + ( viewBottomLeft.contentHeight * 0.5 ) + + + viewMiddle.width = middleWidth + viewMiddle.height = opt.height - ( viewTopLeft.contentHeight + ( viewTopRight.contentHeight ) ) + viewMiddle.x = viewTopLeft.x + ( viewTopLeft.contentWidth * 0.5 ) + (viewMiddle.contentWidth * 0.5 ) + viewMiddle.y = viewTopMiddle.contentHeight + ( viewMiddle.contentHeight * 0.5 ) + + viewMiddleRight.height = opt.height - ( viewTopLeft.contentHeight + viewTopRight.contentHeight ) + viewMiddleRight.x = viewTopRight.x + viewMiddleRight.y = viewTopRight.y + ( viewMiddleRight.contentHeight * 0.5 ) + ( viewBottomRight.contentHeight * 0.5 ) + + -- Bottom + viewBottomLeft.x = viewTopLeft.x + viewBottomLeft.y = viewMiddle.y + ( viewMiddle.contentHeight * 0.5 ) + ( viewBottomLeft.contentHeight * 0.5 ) + + viewBottomMiddle.width = middleWidth + viewBottomMiddle.x = viewBottomLeft.x + ( viewBottomLeft.contentWidth * 0.5 ) + ( viewBottomMiddle.contentWidth * 0.5 ) + viewBottomMiddle.y = viewMiddle.y + ( viewMiddle.contentHeight * 0.5 ) + ( viewBottomMiddle.contentHeight * 0.5 ) + + viewBottomRight.x = viewTopRight.x + viewBottomRight.y = viewMiddle.y + ( viewMiddle.contentHeight * 0.5 ) + ( viewBottomRight.contentHeight * 0.5 ) + + -- If the passed width is less than the topLeft & top right width then don't use the middle pieces + if opt.width <= ( viewTopLeft.contentWidth + viewTopRight.contentWidth ) then + -- Hide the middle slices + viewTopMiddle.isVisible = false + viewMiddle.isVisible = false + viewBottomMiddle.isVisible = false + viewTopMiddle2.isVisible = false + viewPointer.isVisible = false + -- Re-position slices + viewTopRight.x = viewTopLeft.x + ( viewTopLeft.contentWidth * 0.5 ) + ( viewBottomRight.contentWidth * 0.5 ) + viewMiddleRight.x = viewTopLeft.x + ( viewTopLeft.contentWidth * 0.5 ) + ( viewBottomRight.contentWidth * 0.5 ) + viewBottomRight.x = viewTopLeft.x + ( viewTopLeft.contentWidth * 0.5 ) + ( viewBottomRight.contentWidth * 0.5 ) + end + + -- If the passed height is less than the topLeft & top right height then don't use the middle pieces + if opt.height <= ( viewTopLeft.contentHeight + viewTopRight.contentHeight ) then + if opt.width <= ( viewTopLeft.contentWidth + viewTopRight.contentWidth ) then + -- Hide the middle slices + viewMiddleRight.isVisible = false + viewMiddleLeft.isVisible = false + viewMiddle.isVisible = false + viewTopMiddle.isVisible = false + viewTopMiddle2.isVisible = false + viewPointer.isVisible = false + viewBottomMiddle.isVisible = false + + -- Re-position slices + viewTopRight.x = viewTopLeft.x + ( viewTopLeft.contentWidth * 0.5 ) + ( viewTopRight.contentWidth * 0.5 ) + viewBottomLeft.y = viewTopLeft.y + ( viewTopLeft.contentHeight * 0.5 ) + ( viewBottomLeft.contentHeight * 0.5 ) + viewBottomRight.x = viewTopLeft.x + ( viewTopLeft.contentWidth * 0.5 ) + ( viewTopRight.contentWidth * 0.5 ) + viewBottomRight.y = viewTopLeft.y + ( viewTopLeft.contentHeight * 0.5 ) + ( viewBottomRight.contentHeight * 0.5 ) + + else + -- Hide the middle slices + viewMiddle.isVisible = false + viewMiddleRight.isVisible = false + viewMiddleLeft.isVisible = false + + -- Re-position slices + viewBottomLeft.y = viewTopLeft.y + ( viewTopLeft.contentHeight * 0.5 ) + ( viewBottomLeft.contentHeight * 0.5 ) + viewBottomMiddle.y = viewTopLeft.y + ( viewTopLeft.contentHeight * 0.5 ) + ( viewBottomLeft.contentHeight * 0.5 ) + viewBottomRight.y = viewTopLeft.y + ( viewTopLeft.contentHeight * 0.5 ) + ( viewBottomRight.contentHeight * 0.5 ) + + end + end + + -- Setup the Label + viewLabel:setFillColor( unpack( opt.labelColor ) ) + viewLabel._isLabel = true + viewLabel._labelColor = opt.labelColor + + + -- Labels position + if "center" == opt.labelAlign then + viewLabel.x = view.x + ( opt.width * 0.5 ) + opt.labelXOffset + elseif "left" == opt.labelAlign then + viewLabel.x = view.x - ( opt.width * 0.5 ) + ( viewLabel.contentWidth * 0.5 ) + opt.labelXOffset + elseif "right" == opt.labelAlign then + viewLabel.x = view.x + ( opt.width * 0.5 ) - ( viewLabel.contentWidth * 0.5 ) + opt.labelXOffset + end + + + if "center" == opt.labelAlignY then + viewLabel.y = view.y + opt.height / 2 + opt.labelYOffset + elseif "top" == opt.labelAlignY then + viewLabel.y = view.y + ( viewLabel.contentHeight * 0.5 ) + opt.labelYOffset + elseif "bottom" == view.y + viewLabel.contentHeight -viewLabel.contentWidth * 0.5 -opt.labelAlignY then + + viewLabel.y = view.y + ( view.contentHeight * 0.5 ) - ( viewLabel.contentHeight * 0.5 ) + opt.labelYOffset + end + + -- The label's y position + local minHeight = opt.height + if opt.height < 30 then + minHeight = 30 + end + + + ------------------------------------------------------- + -- Assign properties/objects to the view + ------------------------------------------------------- + + view._isEnabled = opt.isEnabled + view._width = opt.width + view._fontSize = opt.fontSize + view._labelAlign = opt.labelAlign + view._labelXOffset = opt.labelXOffset + view._labelYOffset = opt.labelYOffset + view._label = viewLabel + + -- Methods + view._onPress = opt.onPress + view._onRelease = opt.onRelease + view._onEvent = opt.onEvent + + ------------------------------------------------------- + -- Assign properties/objects to the panel + ------------------------------------------------------- + + -- Assign objects to the panel + panel._imageSheet = imageSheet + panel._view = view + + ---------------------------------------------------------- + -- PUBLIC METHODS + ---------------------------------------------------------- + + -- Function to set the panels fill color + function panel:setFillColor( ... ) + for i = self.numChildren, 1, -1 do + if "function" == type( self[i].setFillColor ) then + self[i]:setFillColor( ... ) + end + end + end + + -- Function to set the panel's label + function panel:setLabel( newLabel ) + return self._view:_setLabel( newLabel ) + end + + -- Function to get the panel's label + function panel:getLabel() + return self._view:_getLabel() + end + + -- Function to set a panel as active + function panel:setEnabled( isEnabled ) + self._view._isEnabled = isEnabled + end + + -- Touch listener for our panel + function view:touch( event ) + -- Manage touch events on the panel + managePanelTouch( self, event ) + + return true + end + + view:addEventListener( "touch" ) + + ---------------------------------------------------------- + -- PRIVATE METHODS + ---------------------------------------------------------- + + -- Function to set the panel's label + function view:_setLabel( newLabel ) + if "function" == type( self._label.setText ) then + self._label:setText( newLabel ) + else + self._label.text = newLabel + end + + -- Labels position + if "center" == opt.labelAlign then + self._label.x = view.x + opt.labelXOffset + elseif "left" == opt.labelAlign then + self._label.x = view.x - ( view.contentWidth * 0.5 ) + ( self._label.contentWidth * 0.5 ) + opt.labelXOffset + elseif "right" == opt.labelAlign then + self._label.x = view.x + ( view.contentWidth * 0.5 ) - ( self._label.contentWidth * 0.5 ) + opt.labelXOffset + end + + + if "center" == opt.labelAlignY then + self._label.y = view.y + opt.labelYOffset + elseif "top" == opt.labelAlignY then + self._label.y = view.y - ( view.contentHeight * 0.5 ) + ( self._label.contentHeight * 0.5 ) + opt.labelYOffset + elseif "bottom" == opt.labelAlignY then + + self._label.y = view.y + ( view.contentHeight * 0.5 ) - ( self._label.contentHeight * 0.5 ) + opt.labelYOffset + end + end + + -- Function to get the panel's label + function view:_getLabel() + return self._label.text + end + + -- Finalize function + function panel:_finalize() + -- Set the ImageSheet to nil + self._imageSheet = nil + end + + return panel +end + + +-- Function to create a new panel object ( widget.newPanel ) +function M.new( options, theme ) + local customOptions = options or {} + local themeOptions = theme or {} + + -- Create a local reference to our options table + local opt = M._options + + -- Check if the requirements for creating a widget has been met (throws an error if not) + _widget._checkRequirements( customOptions, themeOptions, M._widgetName ) + + ------------------------------------------------------- + -- Properties + ------------------------------------------------------- + + -- Positioning & properties + opt.left = customOptions.left or 0 + opt.top = customOptions.top or 0 + opt.x = customOptions.x or nil + opt.y = customOptions.y or nil + if customOptions.x and customOptions.y then + opt.left = 0 + opt.top = 0 + end + opt.width = customOptions.width or themeOptions.width + opt.height = customOptions.height or themeOptions.height + opt.id = customOptions.id + opt.baseDir = customOptions.baseDir or system.ResourceDirectory + opt.label = customOptions.label or "" + opt.labelColor = customOptions.labelColor or panelDefault + opt.font = customOptions.font or themeOptions.font or native.systemFont + opt.fontSize = customOptions.fontSize or themeOptions.fontSize or 14 + + if _widget.isSeven() then + opt.font = customOptions.font or themeOptions.font or "HelveticaNeue-Light" + opt.fontSize = customOptions.fontSize or themeOptions.fontSize or 17 + opt.labelColor = customOptions.labelColor or themeOptions.labelColor or panelDefault + end + + opt.labelAlign = customOptions.labelAlign or "center" + opt.labelAlignY = customOptions.labelAlignY or "center" + opt.labelXOffset = customOptions.labelXOffset or 0 + opt.labelYOffset = customOptions.labelYOffset or 0 + opt.embossedLabel = customOptions.emboss or themeOptions.emboss or false + opt.isEnabled = customOptions.isEnabled + opt.textOnlyPanel = customOptions.textOnly or false + opt.pointerX = customOptions.pointerX or nil; + + opt.shape = customOptions.shape or nil; + if opt.shape then + + opt.shape.cornerRadius = opt.shape.cornerRadius or 0; + opt.shape.strokeWidth = opt.shape.strokeWidth or 1; + opt.shape.strokeColor = opt.shape.strokeColor or shapeStrokeDefault; + opt.shape.fillColor = opt.shape.fillColor or shapeFillDefault; + end; + + -- If the user didn't pass in a isEnabled flag, set it to true + if nil == opt.isEnabled then + opt.isEnabled = true + end + + opt.onPress = customOptions.onPress + opt.onRelease = customOptions.onRelease + opt.onEvent = customOptions.onEvent + + -- Frames & Images + opt.sheet = customOptions.sheet + opt.themeSheetFile = themeOptions.sheet + opt.themeData = themeOptions.data + + -- Single image files + opt.defaultFile = customOptions.defaultFile + + if opt.defaultFile then + opt.width = customOptions.width + opt.height = customOptions.height + end + + -- ImageSheet ( 2 frame panel ) + opt.defaultFrame = customOptions.defaultFrame or _widget._getFrameIndex( themeOptions, themeOptions.defaultFrame ) + + -- Left ( 9 piece set ) + opt.topLeftFrame = customOptions.topLeftFrame or _widget._getFrameIndex( themeOptions, themeOptions.topLeftFrame ) + opt.middleLeftFrame = customOptions.middleLeftFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleLeftFrame ) + + opt.bottomLeftFrame = customOptions.bottomLeftFrame or _widget._getFrameIndex( themeOptions, themeOptions.bottomLeftFrame ) + + -- Right ( 9 piece set ) + opt.topRightFrame = customOptions.topRightFrame or _widget._getFrameIndex( themeOptions, themeOptions.topRightFrame ) + + opt.middleRightFrame = customOptions.middleRightFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleRightFrame ) + + opt.bottomRightFrame = customOptions.bottomRightFrame or _widget._getFrameIndex( themeOptions, themeOptions.bottomRightFrame ) + + -- Middle ( 9 piece set ) + opt.topMiddleFrame = customOptions.topMiddleFrame or _widget._getFrameIndex( themeOptions, themeOptions.topMiddleFrame ) + opt.topPointerFrame= customOptions.topPointerFrame or _widget._getFrameIndex( themeOptions, themeOptions.topPointerFrame ) + + opt.middleFrame = customOptions.middleFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleFrame ) + + opt.bottomMiddleFrame = customOptions.bottomMiddleFrame or _widget._getFrameIndex( themeOptions, themeOptions.bottomMiddleFrame ) + + -- Are we using a nine piece panel? + local using9PiecePanel = not opt.defaultFrame and not opt.defaultFile and not opt.textOnlyPanel and not opt.shape and opt.topLeftFrame and opt.middleLeftFrame and opt.bottomLeftFrame and + opt.topRightFrame and opt.middleRightFrame and opt.bottomRightFrame and + opt.topMiddleFrame and opt.middleFrame and opt.bottomMiddleFrame + + -- If we are using a 9-piece panel and have not passed in an imageSheet, throw an error + local isUsingSheet = opt.sheet or opt.themeSheetFile + + -- If were using a 9 piece/slice panel and have not passed a width/height + if using9PiecePanel and not opt.width then + error( "ERROR: " .. M._widgetName .. ": width expected, got nil", 3 ) + elseif using9PiecePanel and not opt.height then + error( "ERROR: " .. M._widgetName .. ": height expected, got nil", 3 ) + end + + if using9PiecePanel and not isUsingSheet then + error( "ERROR: " .. M._widgetName .. ": 9 piece frame or default frame definition expected, got nil", 3 ) + end + + -- Are we using a 2 frame panel? + local using2FramePanel = not using9PiecePanel and opt.defaultFrame + + -- If we are using a 2 frame panel and have not passed in an imageSheet, throw an error + if using2FramePanel and not opt.sheet then + error( "ERROR: " .. M._widgetName .. ": sheet definition expected, got nil", 3 ) + end + + + -- Turn off theme setting for text emboss if the user isn't using a theme + if "boolean" == type( customOptions.emboss ) then + opt.embossedLabel = customOptions.emboss + end + + --[[ + Notes: + *) A 9-piece/slice panel is favored over a 2 frame panel. + *) A 2 frame panel is favored over a 2 file panel. + --]] + + -- Favor nine piece panel over single image panel + if using9PiecePanel then + opt.defaultFrame = nil + + end + + -- Favor 2 frame panel over 2 file panel + if using2FramePanel then + opt.defaultFile = nil + + end + + ------------------------------------------------------- + -- Create the panel + ------------------------------------------------------- + + -- Create the panel object + local panel = _widget._new + { + left = opt.left, + top = opt.top, + id = opt.id or "widget_panel", + baseDir = opt.baseDir, + widgetType = "panel", + } + + -- Create the panel + if using9PiecePanel then + -- If we are using a 9 piece panel + createUsing9Slice( panel, opt ) + else + -- If using a 2 frame panel + if using2FramePanel then + createUsingImageSheet( panel, opt ) + end + + -- If using 2 images + if opt.defaultFile then + createUsingImageFiles( panel, opt ) + end + + -- Text only panel + if opt.textOnlyPanel or opt.shape then + createUsingText( panel, opt ) + end + end + + -- Set the panel's position ( set the reference point to center, just to be sure ) + if ( isGraphicsV1 ) then + panel:setReferencePoint( display.CenterReferencePoint ) + end + + local x, y = opt.x, opt.y + if not opt.x or not opt.y then + x = opt.left + panel.contentWidth * 0.5 + y = opt.top + panel.contentHeight * 0.5 + end + panel.x, panel.y = x, y + + return panel +end + +return M From e305ad6a2d796b915038cd3b34d33ca69a6d1f5c Mon Sep 17 00:00:00 2001 From: atanasster Date: Mon, 6 Jan 2014 18:22:23 -0500 Subject: [PATCH 18/55] support for display.setDefault( "anchorX", ...) --- widgetLibrary/widget_editfield.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 0297347..11a6e2f 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -901,8 +901,14 @@ function M.new( options, theme ) id = opt.id or "widget_editField", } + local defAnchorX = display.getDefault( "anchorX") + local defAnchorY = display.getDefault( "anchorY" ) + display.setDefault( "anchorX", 0.5) + display.setDefault( "anchorY", 0.5 ) initEditField( editField, opt ) + display.setDefault( "anchorX", defAnchorX) + display.setDefault( "anchorY", defAnchorY) -- Set the editField's position ( set the reference point to center, just to be sure ) From 3948ed3be5cd03c083f08d8b8720c870374d4a94 Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 8 Jan 2014 08:58:41 -0500 Subject: [PATCH 19/55] fixes + calibration db Fix for slideForKeyboard in complex groups --- widgetLibrary/editfield_calibrationdb.lua | 17 ++++++++++++++++- widgetLibrary/widget_editfield.lua | 15 ++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/widgetLibrary/editfield_calibrationdb.lua b/widgetLibrary/editfield_calibrationdb.lua index 82dd8db..cde500b 100644 --- a/widgetLibrary/editfield_calibrationdb.lua +++ b/widgetLibrary/editfield_calibrationdb.lua @@ -9,7 +9,22 @@ textFieldYOffset = 0, labelXoffset = 4, labelYoffset = 1 }, - +["device-SGH-I727R"] = { +fontScale = 1, +textFieldHeightAdjust = 12, +textFieldXOffset = -1, +textFieldYOffset = 0, +labelXoffset = 3, +labelYoffset = 0, +}, +["device-SM-N900W8"] = { +fontScale = 1.12, +textFieldHeightAdjust = 13, +textFieldXOffset = 0, +textFieldYOffset = 0, +labelXoffset = 3, +labelYoffset = 2, +}, } diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 11a6e2f..3de726a 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -492,19 +492,20 @@ local function initEditField( editField, options ) function editField:slideForKeyboard(neededHeight) local slideGroup = self.slideGroup; if slideGroup then - local y = self.y; - local parent = self.parent; - while parent and parent.y do - y = y + parent.y; - parent = parent.parent - end +-- local y = self.y; +-- local parent = self.parent; +-- while parent and parent.y do +-- y = y + parent.y; +-- parent = parent.parent +-- end local yGroup = self:getSlideGroupPosition() local groupOffset = 0 --if the group is already slid up, check difference if slideGroup._originalSlideY then groupOffset = (slideGroup._originalSlideY - yGroup) end - local top = y - self.contentHeight * self.anchorY + groupOffset; + local lx, ly = self:contentToLocal(0,0) + local top = -ly - self.contentHeight * self.anchorY + groupOffset; local kbHeight = neededHeight or getKeyboardHeight(); From 2a6f1b12889a50465f1d545ad05fe9addb071828 Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 8 Jan 2014 10:22:48 -0500 Subject: [PATCH 20/55] sync --- LICENSE | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..18e79ea --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Corona Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file From a9cd1564e8d9e437f66c9b8dc7489e3619d35ae7 Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 8 Jan 2014 10:30:37 -0500 Subject: [PATCH 21/55] sync --- widgetLibrary/widget_segmentedControl.lua | 954 +++++++++++----------- 1 file changed, 475 insertions(+), 479 deletions(-) diff --git a/widgetLibrary/widget_segmentedControl.lua b/widgetLibrary/widget_segmentedControl.lua index be5b104..99dc625 100755 --- a/widgetLibrary/widget_segmentedControl.lua +++ b/widgetLibrary/widget_segmentedControl.lua @@ -28,8 +28,8 @@ local M = { - _options = {}, - _widgetName = "widget.newSegmentedControl", + _options = {}, + _widgetName = "widget.newSegmentedControl", } @@ -37,11 +37,12 @@ local M = local _widget = require( "widget" ) local isGraphicsV1 = ( 1 == display.getDefault( "graphicsCompatibility" ) ) +local isByteColorRange = display.getDefault( "isByteColorRange" ) -- define a default color set for both graphics modes local labelDefault local whiteColor -if isGraphicsV1 then +if isByteColorRange then labelDefault = { default = { 0, 0, 0 }, over = { 255, 255, 255 } } whiteColor = { 255 } else @@ -51,493 +52,488 @@ end -- Creates a new segmentedControl from an image local function initWithImage( segmentedControl, options ) - -- Create a local reference to our options table - local opt = options - - -- Forward references - local imageSheet, view, segmentLabels, segmentDividers - - -- Create the imageSheet - if opt.sheet then - imageSheet = opt.sheet - else - local themeData = require( opt.themeData ) - imageSheet = graphics.newImageSheet( opt.themeSheetFile, themeData:getSheet() ) - end - - -- The view is the segmentedControl (group) - view = segmentedControl + -- Create a local reference to our options table + local opt = options + -- Forward references + local imageSheet, view, segmentLabels, segmentDividers + + -- Create the imageSheet + if opt.sheet then + imageSheet = opt.sheet + else + local themeData = require( opt.themeData ) + imageSheet = graphics.newImageSheet( opt.themeSheetFile, themeData:getSheet() ) + end + + -- The view is the segmentedControl (group) + view = segmentedControl + view._segmentWidth = M.segmentWidth + view._labelColor = opt.labelColor + + -- Create the sequenceData table + local leftSegmentOptions = + { + { + name = "leftSegmentOff", + start = opt.leftSegmentFrame, + count = 1, + time = 1, + }, + + { + name = "leftSegmentOn", + start = opt.leftSegmentSelectedFrame, + count = 1, + time = 1, + }, + } + + local rightSegmentOptions = + { + { + name = "rightSegmentOff", + start = opt.rightSegmentFrame, + count = 1, + time = 1, + }, + + { + name = "rightSegmentOn", + start = opt.rightSegmentSelectedFrame, + count = 1, + time = 1, + }, + } + + local middleSegmentOptions = + { + { + name = "middleSegmentOff", + start = opt.middleSegmentFrame, + count = 1, + time = 1, + }, + + { + name = "middleSegmentOn", + start = opt.middleSegmentSelectedFrame, + count = 1, + time = 1, + }, + } + + local dividerSegmentOptions = + { + { + name = "middleSegmentOff", + start = opt.middleSegmentFrame, + count = 1, + time = 1, + }, + + { + name = "middleSegmentOn", + start = opt.middleSegmentSelectedFrame, + count = 1, + time = 1, + }, + } + + -- Reference the passed in segments + local segments = opt.segments + + -- Create the view's segments + segmentLabels = {} + segmentDividers = {} + + local overallControlWidth = ( view._segmentWidth * #segments ) + local segmentWidth = overallControlWidth / #segments + + -- The left segment edge + local leftSegment = display.newSprite( segmentedControl, imageSheet, leftSegmentOptions ) + leftSegment.x = segmentedControl.x + ( opt.width * 0.5 ) + leftSegment.y = segmentedControl.y + ( leftSegment.contentHeight * 0.5 ) + leftSegment:setSequence( "leftSegmentOff" ) + leftSegment.width = opt.width + -- The segment fill + local middleSegment = display.newSprite( segmentedControl, imageSheet, middleSegmentOptions ) + middleSegment:setSequence( "middleSegmentOff" ) + + middleSegment.width = ( overallControlWidth ) - ( opt.width * 2 ) + middleSegment.x = leftSegment.x + leftSegment.contentWidth * 0.5 + ( middleSegment.width * 0.5 ) + middleSegment.y = segmentedControl.y + ( middleSegment.contentHeight * 0.5 ) + + -- The right segment edge + local rightSegment = display.newSprite( segmentedControl, imageSheet, rightSegmentOptions ) + rightSegment:setSequence( "rightSegmentOff" ) + rightSegment.width = opt.width + rightSegment.x = middleSegment.x + ( middleSegment.width * 0.5 ) + opt.width * 0.5 + rightSegment.y = segmentedControl.y + ( rightSegment.contentHeight * 0.5 ) + + -- Create the segment labels & dividers + for i = 1, #segments do + -- Create the labels + local label + if _widget.isSeven() then + label = display.newText( segmentedControl, segments[i], 0, 0, opt.labelFont, opt.labelSize ) + if view._segmentNumber == i or opt.defaultSegment == i then + label:setFillColor( unpack( view._labelColor.over ) ) + else + label:setFillColor( unpack( view._labelColor.default ) ) + end + else + label = display.newEmbossedText( segmentedControl, segments[i], 0, 0, opt.labelFont, opt.labelSize ) + label:setFillColor( unpack( whiteColor ) ) + end + + + + label.x = leftSegment.x + ( segmentWidth * 0.5 + segmentWidth * ( i - 1 ) ) - leftSegment.width * 0.5 + label.y = leftSegment.y + label.segmentName = segments[i] + segmentLabels[i] = label + + -- Create the dividers + if i < #segments then + local divider = display.newImageRect( segmentedControl, imageSheet, opt.dividerFrame, 1, 29 ) + divider.x = leftSegment.x + ( segmentWidth * i ) - ( leftSegment.width * 0.5 ) + divider.y = leftSegment.y + segmentDividers[i] = divider + end + end - view._segmentWidth = M.segmentWidth - view._labelColor = opt.labelColor - view._isSeven = _widget.isSeven() - view._labelNotEmbossed = opt.labelNotEmbossed - - -- Create the sequenceData table - local leftSegmentOptions = - { - { - name = "leftSegmentOff", - start = opt.leftSegmentFrame, - count = 1, - time = 1, - }, - - { - name = "leftSegmentOn", - start = opt.leftSegmentSelectedFrame, - count = 1, - time = 1, - }, - } - - local rightSegmentOptions = - { - { - name = "rightSegmentOff", - start = opt.rightSegmentFrame, - count = 1, - time = 1, - }, - - { - name = "rightSegmentOn", - start = opt.rightSegmentSelectedFrame, - count = 1, - time = 1, - }, - } - - local middleSegmentOptions = - { - { - name = "middleSegmentOff", - start = opt.middleSegmentFrame, - count = 1, - time = 1, - }, - - { - name = "middleSegmentOn", - start = opt.middleSegmentSelectedFrame, - count = 1, - time = 1, - }, - } - - local dividerSegmentOptions = - { - { - name = "middleSegmentOff", - start = opt.middleSegmentFrame, - count = 1, - time = 1, - }, - - { - name = "middleSegmentOn", - start = opt.middleSegmentSelectedFrame, - count = 1, - time = 1, - }, - } - - -- Reference the passed in segments - local segments = opt.segments - - -- Create the view's segments - segmentLabels = {} - segmentDividers = {} - - local overallControlWidth = ( view._segmentWidth * #segments ) - local segmentWidth = overallControlWidth / #segments - - -- The left segment edge - local leftSegment = display.newSprite( segmentedControl, imageSheet, leftSegmentOptions ) - leftSegment.x = segmentedControl.x + ( opt.width * 0.5 ) - leftSegment.y = segmentedControl.y + ( leftSegment.contentHeight * 0.5 ) - leftSegment:setSequence( "leftSegmentOff" ) - leftSegment.width = opt.width - -- The segment fill - local middleSegment = display.newSprite( segmentedControl, imageSheet, middleSegmentOptions ) - middleSegment:setSequence( "middleSegmentOff" ) - - middleSegment.width = ( overallControlWidth ) - ( opt.width * 2 ) - middleSegment.x = leftSegment.x + leftSegment.contentWidth * 0.5 + ( middleSegment.width * 0.5 ) - middleSegment.y = segmentedControl.y + ( middleSegment.contentHeight * 0.5 ) - - -- The right segment edge - local rightSegment = display.newSprite( segmentedControl, imageSheet, rightSegmentOptions ) - rightSegment:setSequence( "rightSegmentOff" ) - rightSegment.width = opt.width - rightSegment.x = middleSegment.x + ( middleSegment.width * 0.5 ) + opt.width * 0.5 - rightSegment.y = segmentedControl.y + ( rightSegment.contentHeight * 0.5 ) - - -- Create the segment labels & dividers - for i = 1, #segments do - -- Create the labels - local label - if (view._labelNotEmbossed == true) or view._isSeven then - label = display.newText( segmentedControl, segments[i], 0, 0, opt.labelFont, opt.labelSize ) - if view._segmentNumber == i or opt.defaultSegment == i then - label:setFillColor( unpack( view._labelColor.over ) ) - else - label:setFillColor( unpack( view._labelColor.default ) ) - end - else - label = display.newEmbossedText( segmentedControl, segments[i], 0, 0, opt.labelFont, opt.labelSize ) - label:setFillColor( unpack( whiteColor ) ) - end - - - - label.x = leftSegment.x + ( segmentWidth * 0.5 + segmentWidth * ( i - 1 ) ) - leftSegment.width * 0.5 - label.y = leftSegment.y - label.segmentName = segments[i] - segmentLabels[i] = label + -- The "over" frame + local segmentOver = display.newSprite( segmentedControl, imageSheet, middleSegmentOptions ) + segmentOver:setSequence( "middleSegmentOn" ) + + segmentOver.width = opt.width + segmentOver.y = leftSegment.y + + ------------------------------------------------------- + -- Assign properties to the view + ------------------------------------------------------- + + -- Segment properties + view._segmentWidth = segmentWidth + view._edgeWidth = opt.width + view._totalSegments = #segments + + -- Create a reference to the segments + view._leftSegment = leftSegment + view._middleSegment = middleSegment + view._rightSegment = rightSegment + view._segmentOver = segmentOver + view._segmentLabels = segmentLabels + view._segmentDividers = segmentDividers + view._segmentNumber = opt.defaultSegment + view._onPress = opt.onPress + + -- Insert the segment labels into the view + for i = 1, #view._segmentLabels do + view:insert( view._segmentLabels[i] ) + end + + -- Insert the segment dividers into the view + for i = 1, #segmentDividers do + view:insert( view._segmentDividers[i] ) + end + + ------------------------------------------------------- + -- Assign properties/objects to the segmentedControl + ------------------------------------------------------- + + -- Assign objects to the segmentedControl + segmentedControl._imageSheet = imageSheet + segmentedControl._view = view + segmentedControl._onPress = opt.onPress + + -- Public properties + segmentedControl.segmentLabel = view._segmentLabels[1].text + segmentedControl.segmentNumber = view._segmentNumber + + ---------------------------------------------------------- + -- PUBLIC METHODS + ---------------------------------------------------------- + + -- Touch listener for our segmented control + function view:touch( event ) + local phase = event.phase + local _segmentedControl = self.parent + event.target = _segmentedControl + local firstSegment = 1 + local lastSegment = self._totalSegments - -- Create the dividers - if i < #segments then - local divider = display.newImageRect( segmentedControl, imageSheet, opt.dividerFrame, 1, 29 ) - divider.x = leftSegment.x + ( segmentWidth * i ) - ( leftSegment.width * 0.5 ) - divider.y = leftSegment.y - segmentDividers[i] = divider - end - end + if "began" == phase then + -- Loop through the segments + for i = 1, self._totalSegments do + local segmentedControlXPosition = self.x - ( self.contentWidth * 0.5 ) + -- for g2, we have to take into account the current anchorX for this position + if not isGraphicsV1 then + local oldAnchorX = self.anchorX + segmentedControlXPosition = segmentedControlXPosition + ( 0.5 - oldAnchorX ) * self.contentWidth + end + + local currentSegment = i + local segmentWidth = self._segmentWidth + + -- Work out the current segments position - -- The "over" frame - local segmentOver = display.newSprite( segmentedControl, imageSheet, middleSegmentOptions ) - segmentOver:setSequence( "middleSegmentOn" ) - - segmentOver.width = opt.width - segmentOver.y = leftSegment.y - - ------------------------------------------------------- - -- Assign properties to the view - ------------------------------------------------------- - - -- Segment properties - view._segmentWidth = segmentWidth - view._edgeWidth = opt.width - view._totalSegments = #segments - - -- Create a reference to the segments - view._leftSegment = leftSegment - view._middleSegment = middleSegment - view._rightSegment = rightSegment - view._segmentOver = segmentOver - view._segmentLabels = segmentLabels - view._segmentDividers = segmentDividers - view._segmentNumber = opt.defaultSegment - view._onPress = opt.onPress - - -- Insert the segment labels into the view - for i = 1, #view._segmentLabels do - view:insert( view._segmentLabels[i] ) - end - - -- Insert the segment dividers into the view - for i = 1, #segmentDividers do - view:insert( view._segmentDividers[i] ) - end - - ------------------------------------------------------- - -- Assign properties/objects to the segmentedControl - ------------------------------------------------------- - - -- Assign objects to the segmentedControl - segmentedControl._imageSheet = imageSheet - segmentedControl._view = view - segmentedControl._onPress = opt.onPress - - -- Public properties - segmentedControl.segmentLabel = view._segmentLabels[1].text - segmentedControl.segmentNumber = view._segmentNumber - - ---------------------------------------------------------- - -- PUBLIC METHODS - ---------------------------------------------------------- - - -- Touch listener for our segmented control - function view:touch( event ) - local phase = event.phase - local _segmentedControl = self - local firstSegment = 1 - local lastSegment = self._totalSegments + local parentOffsetX = 0 - if "began" == phase then - native.setKeyboardFocus(nil) - -- Loop through the segments - for i = 1, self._totalSegments do - local segmentedControlXPosition = self.x - ( self.contentWidth * 0.5 ) + -- First, we check if the widget is in a group + if nil ~= self.parent and nil ~= self.parent.x then + parentOffsetX = self.parent.x + end + + --local currentSegmentLeftEdge = ( segmentedControlXPosition * 0.5 ) * currentSegment + parentOffsetX + --local currentSegmentRightEdge = segmentedControlXPosition + ( segmentWidth * currentSegment ) + parentOffsetX - local currentSegment = i - local segmentWidth = self._segmentWidth - - local x,y = self:contentToLocal(event.x, event.y); - local currentSegmentLeftEdge = ( segmentWidth * currentSegment ) - segmentWidth - local currentSegmentRightEdge = ( segmentWidth * currentSegment ) - - -- If the touch is within the segments range - if x >= currentSegmentLeftEdge and x <= currentSegmentRightEdge then - -- First segment (Near left) - if firstSegment == i then - self:setLeftSegmentActive() - -- Last segment (Far right) - elseif lastSegment == i then - self:setRightSegmentActive() - -- Any other segment - else - self:setMiddleSegmentActive( i ) - end - - -- Set the segment name - _segmentedControl.segmentLabel = self._segmentLabels[i].segmentName - - -- Set the segment number - _segmentedControl.segmentNumber = self._segmentNumber - - -- Execute onPress listener - if self._onPress and "function" == type( self._onPress ) then - event.target = _segmentedControl - self._onPress( event ) - end - - break - end - end - end - - return true - end - - view:addEventListener( "touch" ) + local currentSegmentLeftEdge = segmentedControlXPosition + ( segmentWidth * currentSegment ) - segmentWidth + parentOffsetX + local currentSegmentRightEdge = segmentedControlXPosition + ( segmentWidth * currentSegment ) + parentOffsetX + + -- If the touch is within the segments range + if event.x >= currentSegmentLeftEdge and event.x <= currentSegmentRightEdge then + -- First segment (Near left) + if firstSegment == i then + self:setLeftSegmentActive() + -- Last segment (Far right) + elseif lastSegment == i then + self:setRightSegmentActive() + -- Any other segment + else + self:setMiddleSegmentActive( i ) + end + + -- Set the segment name + _segmentedControl.segmentLabel = self._segmentLabels[i].segmentName + + -- Set the segment number + _segmentedControl.segmentNumber = self._segmentNumber + + -- Execute onPress listener + if self._onPress and "function" == type( self._onPress ) then + self._onPress( event ) + end + + break + end + end + end + + return true + end + + view:addEventListener( "touch" ) - ---------------------------------------------------------- - -- PRIVATE METHODS - ---------------------------------------------------------- - - -- Function to set the left segment active - function view:setLeftSegmentActive() - -- Turn off the right segment - self._rightSegment:setSequence( "rightSegmentOff" ) - -- Turn on the left segment - self._leftSegment:setSequence( "leftSegmentOn" ) - -- Set the over segment's width - segmentOver.width = view._segmentWidth - self._leftSegment.width - 0.5 - -- Set the over segment's position - - segmentOver.x = self._leftSegment.x + self._leftSegment.width * 0.5 + segmentOver.width * 0.5 - - if isGraphicsV1 then - segmentOver:setReferencePoint( display.CenterReferencePoint ) - end - - -- Set the segment's name - self._segmentLabel = self._segmentLabels[1].text - - -- Set the segment number - self._segmentNumber = 1 - - -- Reset the colors if ios7 - if self._labelNotEmbossed == true or self._isSeven then - for i = 1, #view._segmentLabels do - local currentSegment = view._segmentLabels[ i ] - currentSegment:setFillColor( unpack( self._labelColor.default ) ) - end - - view._segmentLabels[1]:setFillColor( unpack( self._labelColor.over ) ) - - end - - end - - -- Function to set the right segment active - function view:setRightSegmentActive() - -- Turn off the left segment - self._leftSegment:setSequence( "leftSegmentOff" ) - -- Turn on the right segment - self._rightSegment:setSequence( "rightSegmentOn" ) - -- Set the over segment's width - segmentOver.width = view._segmentWidth - self._rightSegment.width - -- Set the over segment's position - segmentOver.x = self._rightSegment.x - self._rightSegment.width * 0.5 - segmentOver.width * 0.5 - - -- Set the segment's name - self._segmentLabel = self._segmentLabels[self._totalSegments].text - - -- Set the segment number - self._segmentNumber = self._totalSegments - - -- Reset the colors if ios7 - if self._labelNotEmbossed == true or self._isSeven then - for i = 1, #view._segmentLabels do - local currentSegment = view._segmentLabels[ i ] - currentSegment:setFillColor( unpack( self._labelColor.default ) ) - end - - view._segmentLabels[ #view._segmentLabels ]:setFillColor( unpack( self._labelColor.over ) ) - - end - - end - - -- Function to set the middle segment active - function view:setMiddleSegmentActive( segmentNum ) - -- Turn off the left segment - self._leftSegment:setSequence( "leftSegmentOff" ) - -- Turn off the right segment - self._rightSegment:setSequence( "rightSegmentOff" ) - -- Set the over segment's width - segmentOver.width = self._segmentWidth - -- Set the over segment's position - segmentOver.x = self._segmentDividers[segmentNum - 1].x + segmentOver.width * 0.5 - - -- Set the segment's name - self._segmentLabel = self._segmentLabels[segmentNum].text - - -- Set the segment number - self._segmentNumber = segmentNum - - -- Reset the colors if ios7 - if self._labelNotEmbossed == true or self._isSeven then - for i = 1, #view._segmentLabels do - local currentSegment = view._segmentLabels[ i ] - currentSegment:setFillColor( unpack( self._labelColor.default ) ) - end - - view._segmentLabels[ segmentNum ]:setFillColor( unpack( self._labelColor.over ) ) - - end - - end - - function segmentedControl:getDefaultSegment( ) - return self._view._segmentNumber; - end - function segmentedControl:getValue( ) - return self._view._segmentNumber; - end - function segmentedControl:setValue( segmentNum ) - self:setDefaultSegment( segmentNum ) - end - -- Set the intial segment to active - function segmentedControl:setDefaultSegment( segmentNum ) - if 1 == segmentNum then - view:setLeftSegmentActive() - elseif #segments == segmentNum then - view:setRightSegmentActive() - else - view:setMiddleSegmentActive( segmentNum ) - end - view._segmentNumber = segmentNum; - end - - -- Finalize function for the segmentedControl - function segmentedControl:_finalize() - self._view._segments = nil - self._view = nil - - -- Set the ImageSheet to nil - self._imageSheet = nil - end - - -- Set the default segment - segmentedControl:setDefaultSegment( view._segmentNumber ) - - return segmentedControl + ---------------------------------------------------------- + -- PRIVATE METHODS + ---------------------------------------------------------- + + -- Function to set the left segment active + function view:setLeftSegmentActive() + -- Turn off the right segment + self._rightSegment:setSequence( "rightSegmentOff" ) + -- Turn on the left segment + self._leftSegment:setSequence( "leftSegmentOn" ) + -- Set the over segment's width + segmentOver.width = view._segmentWidth - self._leftSegment.width - 0.5 + -- Set the over segment's position + + segmentOver.x = self._leftSegment.x + self._leftSegment.width * 0.5 + segmentOver.width * 0.5 + + if isGraphicsV1 then + segmentOver:setReferencePoint( display.CenterReferencePoint ) + end + + -- Set the segment's name + self._segmentLabel = self._segmentLabels[1].text + + -- Set the segment number + self._segmentNumber = 1 + + -- Reset the colors if ios7 + if _widget.isSeven() then + for i = 1, #view._segmentLabels do + local currentSegment = view._segmentLabels[ i ] + currentSegment:setFillColor( unpack( view._labelColor.default ) ) + end + + view._segmentLabels[1]:setFillColor( unpack( whiteColor ) ) + + end + + end + + -- Function to set the right segment active + function view:setRightSegmentActive() + -- Turn off the left segment + self._leftSegment:setSequence( "leftSegmentOff" ) + -- Turn on the right segment + self._rightSegment:setSequence( "rightSegmentOn" ) + -- Set the over segment's width + segmentOver.width = view._segmentWidth - self._rightSegment.width + -- Set the over segment's position + segmentOver.x = self._rightSegment.x - self._rightSegment.width * 0.5 - segmentOver.width * 0.5 + + -- Set the segment's name + self._segmentLabel = self._segmentLabels[self._totalSegments].text + + -- Set the segment number + self._segmentNumber = self._totalSegments + + -- Reset the colors if ios7 + if _widget.isSeven() then + for i = 1, #view._segmentLabels do + local currentSegment = view._segmentLabels[ i ] + currentSegment:setFillColor( unpack( view._labelColor.default ) ) + end + + view._segmentLabels[ #view._segmentLabels ]:setFillColor( unpack( whiteColor ) ) + + end + + end + + -- Function to set the middle segment active + function view:setMiddleSegmentActive( segmentNum ) + -- Turn off the left segment + self._leftSegment:setSequence( "leftSegmentOff" ) + -- Turn off the right segment + self._rightSegment:setSequence( "rightSegmentOff" ) + -- Set the over segment's width + segmentOver.width = self._segmentWidth + -- Set the over segment's position + segmentOver.x = self._segmentDividers[segmentNum - 1].x + segmentOver.width * 0.5 + + -- Set the segment's name + self._segmentLabel = self._segmentLabels[segmentNum].text + + -- Set the segment number + self._segmentNumber = segmentNum + + -- Reset the colors if ios7 + if _widget.isSeven() then + for i = 1, #view._segmentLabels do + local currentSegment = view._segmentLabels[ i ] + currentSegment:setFillColor( unpack( view._labelColor.default ) ) + end + + view._segmentLabels[ segmentNum ]:setFillColor( unpack( whiteColor ) ) + + end + + end + + -- Set the intial segment to active + local function setDefaultSegment( segmentNum ) + if 1 == segmentNum then + view:setLeftSegmentActive() + elseif #segments == segmentNum then + view:setRightSegmentActive() + else + view:setMiddleSegmentActive( view._segmentNumber ) + end + end + + -- Finalize function for the segmentedControl + function segmentedControl:_finalize() + self._view._segments = nil + self._view = nil + + -- Set the ImageSheet to nil + self._imageSheet = nil + end + + -- Set the default segment + setDefaultSegment( view._segmentNumber ) + + return segmentedControl end -- Function to create a new segmentedControl object ( widget.newSegmentedControl ) -function M.new( options, theme ) - local customOptions = options or {} - local themeOptions = theme or {} - - -- Create a local reference to our options table - local opt = M._options - - -- Check if the requirements for creating a widget has been met (throws an error if not) - _widget._checkRequirements( customOptions, themeOptions, M._widgetName ) - - ------------------------------------------------------- - -- Properties - ------------------------------------------------------- - -- Positioning & properties - opt.left = customOptions.left or 0 - opt.top = customOptions.top or 0 - opt.x = customOptions.x or nil - opt.y = customOptions.y or nil - if customOptions.x and customOptions.y then - opt.left = 0 - opt.top = 0 - end - opt.width = customOptions.width or themeOptions.width or error( "ERROR:" .. M._widgetName .. ": width expected, got nil", 3 ) - opt.height = customOptions.height or themeOptions.height or error( "ERROR:" .. M._widgetName .. ": height expected, got nil", 3 ) - opt.id = customOptions.id - opt.baseDir = customOptions.baseDir or system.ResourceDirectory - opt.segments = customOptions.segments or { "One", "Two" } - M.segmentWidth = customOptions.segmentWidth or 50 - opt.defaultSegment = customOptions.defaultSegment or 1 - opt.labelSize = customOptions.labelSize or 12 - opt.labelFont = customOptions.labelFont or native.systemFont - opt.labelNotEmbossed = customOptions.labelNotEmbossed or false; - -- TODO: document this in the API - opt.labelColor = customOptions.labelColor or themeOptions.labelColor or buttonDefault - - if _widget.isSeven() then - opt.labelFont = customOptions.labelFont or "HelveticaNeue" - opt.labelSize = customOptions.labelSize or 13 - end - - opt.labelXOffset = customOptions.labelXOffset or 0 - opt.labelYOffset = customOptions.labelYOffset or 0 - opt.onPress = customOptions.onPress - - -- Frames & Images - opt.sheet = customOptions.sheet - opt.themeSheetFile = themeOptions.sheet - opt.themeData = themeOptions.data - - opt.leftSegmentFrame = customOptions.leftSegmentFrame or _widget._getFrameIndex( themeOptions, themeOptions.leftSegmentFrame ) - opt.leftSegmentSelectedFrame = customOptions.leftSegmentSelectedFrame or _widget._getFrameIndex( themeOptions, themeOptions.leftSegmentSelectedFrame ) - opt.rightSegmentFrame = customOptions.rightSegmentFrame or _widget._getFrameIndex( themeOptions, themeOptions.rightSegmentFrame ) - opt.rightSegmentSelectedFrame = customOptions.rightSegmentSelectedFrame or _widget._getFrameIndex( themeOptions,themeOptions.rightSegmentSelectedFrame ) - opt.middleSegmentFrame = customOptions.middleSegmentFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleSegmentFrame ) - opt.middleSegmentSelectedFrame = customOptions.middleSegmentSelectedFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleSegmentSelectedFrame) - opt.dividerFrame = customOptions.dividerFrame or _widget._getFrameIndex( themeOptions, themeOptions.dividerFrame) +function M.new( options, theme ) + local customOptions = options or {} + local themeOptions = theme or {} + + -- Create a local reference to our options table + local opt = M._options + + -- Check if the requirements for creating a widget has been met (throws an error if not) + _widget._checkRequirements( customOptions, themeOptions, M._widgetName ) + + ------------------------------------------------------- + -- Properties + ------------------------------------------------------- + -- Positioning & properties + opt.left = customOptions.left or 0 + opt.top = customOptions.top or 0 + opt.x = customOptions.x or nil + opt.y = customOptions.y or nil + if customOptions.x and customOptions.y then + opt.left = 0 + opt.top = 0 + end + opt.width = customOptions.width or themeOptions.width or error( "ERROR:" .. M._widgetName .. ": width expected, got nil", 3 ) + opt.height = customOptions.height or themeOptions.height or error( "ERROR:" .. M._widgetName .. ": height expected, got nil", 3 ) + opt.id = customOptions.id + opt.baseDir = customOptions.baseDir or system.ResourceDirectory + opt.segments = customOptions.segments or { "One", "Two" } + M.segmentWidth = customOptions.segmentWidth or 50 + opt.defaultSegment = customOptions.defaultSegment or 1 + opt.labelSize = customOptions.labelSize or 12 + opt.labelFont = customOptions.labelFont or native.systemFont + -- TODO: document this in the API + opt.labelColor = customOptions.labelColor or themeOptions.labelColor or buttonDefault + + if _widget.isSeven() then + opt.labelFont = customOptions.labelFont or "HelveticaNeue" + opt.labelSize = customOptions.labelSize or 13 + end + + opt.labelXOffset = customOptions.labelXOffset or 0 + opt.labelYOffset = customOptions.labelYOffset or 0 + opt.onPress = customOptions.onPress + + -- Frames & Images + opt.sheet = customOptions.sheet + opt.themeSheetFile = themeOptions.sheet + opt.themeData = themeOptions.data + + opt.leftSegmentFrame = customOptions.leftSegmentFrame or _widget._getFrameIndex( themeOptions, themeOptions.leftSegmentFrame ) + opt.leftSegmentSelectedFrame = customOptions.leftSegmentSelectedFrame or _widget._getFrameIndex( themeOptions, themeOptions.leftSegmentSelectedFrame ) + opt.rightSegmentFrame = customOptions.rightSegmentFrame or _widget._getFrameIndex( themeOptions, themeOptions.rightSegmentFrame ) + opt.rightSegmentSelectedFrame = customOptions.rightSegmentSelectedFrame or _widget._getFrameIndex( themeOptions,themeOptions.rightSegmentSelectedFrame ) + opt.middleSegmentFrame = customOptions.middleSegmentFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleSegmentFrame ) + opt.middleSegmentSelectedFrame = customOptions.middleSegmentSelectedFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleSegmentSelectedFrame) + opt.dividerFrame = customOptions.dividerFrame or _widget._getFrameIndex( themeOptions, themeOptions.dividerFrame) - ------------------------------------------------------- - -- Create the segmentedControl - ------------------------------------------------------- - - -- Create the segmentedControl object - local segmentedControl = _widget._new - { - left = opt.left, - top = opt.top, - id = opt.id or "widget_segmentedControl", - baseDir = opt.baseDir, - } - - -- Create the segmentedControl - initWithImage( segmentedControl, opt ) - - -- Set the segmentedControl's position ( set the reference point to center, just to be sure ) - if ( isGraphicsV1 ) then - segmentedControl:setReferencePoint( display.CenterReferencePoint ) - end - - local x, y = opt.x, opt.y - if (not opt.x) or (not opt.y) then - x = opt.left + segmentedControl.contentWidth * 0.5 - y = opt.top + segmentedControl.contentHeight * 0.5 - end - segmentedControl.x, segmentedControl.y = x, y - - - return segmentedControl + ------------------------------------------------------- + -- Create the segmentedControl + ------------------------------------------------------- + + -- Create the segmentedControl object + local segmentedControl = _widget._new + { + left = opt.left, + top = opt.top, + id = opt.id or "widget_segmentedControl", + baseDir = opt.baseDir, + } + + -- Create the segmentedControl + initWithImage( segmentedControl, opt ) + + -- Set the segmentedControl's position ( set the reference point to center, just to be sure ) + if ( isGraphicsV1 ) then + segmentedControl:setReferencePoint( display.CenterReferencePoint ) + end + + local x, y = _widget._calculatePosition( segmentedControl, opt ) + segmentedControl.x, segmentedControl.y = x, y + + return segmentedControl end -return M +return M \ No newline at end of file From 4b7ae5bdfe8063f768a21508570076c5e0211306 Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 8 Jan 2014 10:30:46 -0500 Subject: [PATCH 22/55] sync --- widgetLibrary/widget_pickerWheel.lua | 798 +++++++++++++-------------- 1 file changed, 399 insertions(+), 399 deletions(-) diff --git a/widgetLibrary/widget_pickerWheel.lua b/widgetLibrary/widget_pickerWheel.lua index a79e5fa..48720b3 100644 --- a/widgetLibrary/widget_pickerWheel.lua +++ b/widgetLibrary/widget_pickerWheel.lua @@ -28,317 +28,318 @@ local M = { - _options = {}, - _widgetName = "widget.newPickerWheel", + _options = {}, + _widgetName = "widget.newPickerWheel", } -- Require needed widget files local _widget = require( "widget" ) local isGraphicsV1 = ( 1 == display.getDefault( "graphicsCompatibility" ) ) +local isByteColorRange = display.getDefault( "isByteColorRange" ) local labelColor = { 0.60 } local defaultRowColor = { 1 } local blackColor = { 0 } -if isGraphicsV1 then - _widget._convertColorToV1( labelColor ) - _widget._convertColorToV1( defaultRowColor ) - _widget._convertColorToV1( blackColor ) +if isByteColorRange then + _widget._convertColorToV1( labelColor ) + _widget._convertColorToV1( defaultRowColor ) + _widget._convertColorToV1( blackColor ) end -- Creates a new pickerWheel local function createPickerWheel( pickerWheel, options ) - -- Create a local reference to our options table - local opt = options - - -- Forward references - local imageSheet, view, viewBackground, viewOverlay, viewColumns - - -- Create the imageSheet - if opt.sheet then - imageSheet = opt.sheet - else - local themeData = require( opt.themeData ) - imageSheet = graphics.newImageSheet( opt.themeSheetFile, themeData:getSheet() ) - end - - -- Create the view - view = display.newGroup() - - -- The view's background - viewOverlay = display.newImageRect( pickerWheel, imageSheet, opt.overlayFrame, opt.overlayFrameWidth, opt.overlayFrameHeight ) - - ---------------------------------- - -- Properties - ---------------------------------- - - -- The table which holds our pickerWheel columns - viewColumns = {} - - ------------------------------------------------------- - -- Assign properties to the view - ------------------------------------------------------- - - -- Assign properties to our view - view._width = opt.overlayFrameWidth - view._height = opt.overlayFrameHeight - view._top = opt.top - view._yPosition = pickerWheel.y + ( view._height * 0.5 ) - - -- Assign objects to our view - view._overlay = viewOverlay - view._background = viewBackground - view._columns = viewColumns - view._didTap = false - if "function" == type(opt.onScroll) then - view._onScroll = opt.onScroll; - end; - - ------------------------------------------------------- - -- Assign properties/objects to the pickerWheel - ------------------------------------------------------- - - -- Assign objects to the pickerWheel - pickerWheel._imageSheet = imageSheet - pickerWheel._view = view - pickerWheel:insert( view ) - - -- Function to render the pickerWheels columns - local function _renderColumns( event ) - local phase = event.phase - local row = event.row - local fontSize = event.target._fontSize - local alignment = event.target._align + -- Create a local reference to our options table + local opt = options - -- Create the column's title text - local rowTitle = display.newText( row, row._label, 0, 0, opt.font, fontSize ) - rowTitle.y = row.contentHeight * 0.5 + -- Forward references + local imageSheet, view, viewBackground, viewOverlay, viewColumns - if _widget.isSeven() and row.index == pickerWheel._view._columns[row.id]._values.index then - rowTitle:setFillColor( 0 ) + -- Create the imageSheet + if opt.sheet then + imageSheet = opt.sheet else - rowTitle:setFillColor( unpack( opt.fontColor ) ) + local themeData = require( opt.themeData ) + imageSheet = graphics.newImageSheet( opt.themeSheetFile, themeData:getSheet() ) end - row.value = rowTitle.text + -- Create the view + view = display.newGroup() - -- check if the text is greater than the actual column size - local availableWidth = viewOverlay.width - 28 - local columnWidth = view._columns[ row.id ].width or availableWidth / #view._columns - local textWidth = rowTitle.contentWidth - if textWidth > columnWidth - 1 then - --cap the text - local pixelsPerChar = 23 -- aproximate median value - local numChars = columnWidth / pixelsPerChar - row._label = row._label:sub(1, numChars) - rowTitle.text = row._label - - end - - -- Align the text as requested - if "center" == alignment then - - local rowTitleX - if isGraphicsV1 then - rowTitleX = row.x - else - rowTitleX = row.x + columnWidth * 0.5 - end - rowTitle.x = rowTitleX - - elseif "left" == alignment then - - local rowTitleX - if isGraphicsV1 then - rowTitleX = ( rowTitle.contentWidth * 0.5 ) + 6 - else - rowTitleX = row.x + 6 - rowTitle.anchorX = 0 - end - rowTitle.x = rowTitleX - - elseif "right" == alignment then - - local rowTitleX - if isGraphicsV1 then - rowTitleX = row.x + ( row.contentWidth * 0.5 ) - ( rowTitle.contentWidth * 0.5 ) - 6 - else - rowTitleX = row.x + columnWidth - 6 - rowTitle.anchorX = 1 - end - rowTitle.x = rowTitleX - - end + -- The view's background + viewOverlay = display.newImageRect( pickerWheel, imageSheet, opt.overlayFrame, opt.overlayFrameWidth, opt.overlayFrameHeight ) + ---------------------------------- + -- Properties + ---------------------------------- - end - - -- Create a background to sit behind the pickerWheel - viewBackground = display.newImageRect( view, imageSheet, opt.backgroundFrame, opt.overlayFrameWidth, opt.overlayFrameHeight ) - viewBackground.x = viewOverlay.x - viewBackground.y = viewOverlay.y - - -- Function to create the column seperator - function view:_createSeperator( x ) - local seperator = display.newImageRect( self, imageSheet, opt.seperatorFrame, opt.seperatorFrameWidth + 4, opt.backgroundFrameHeight ) - seperator.x = x - - return seperator - end - - -- The available width for the whole pickerWheel (to fit columns) - local availableWidth = viewOverlay.width - 28 - - -- local method that handles scrolling to the tapped / touched index - local function didTapValue( event ) - local phase = event.phase - local row = event.target - if "tap" == phase or "release" == phase then - view._columns[ row.id ]:scrollToIndex( row.index ) - view._didTap = true - end - end - - -- Create the pickerWheel Columns (which are tableView's) - local topPadding = 84 - local bottomPadding = 96 - if isGraphicsV1 then - topPadding = 90 - bottomPadding = 92 - end - - local initialX = 0 - local initialPos = - 144 - - for i = 1, #opt.columnData do + -- The table which holds our pickerWheel columns + viewColumns = {} + + ------------------------------------------------------- + -- Assign properties to the view + ------------------------------------------------------- - if i > 1 then - initialPos = viewColumns[i-1].x + viewColumns[i-1]._view._width * 0.5 - end + -- Assign properties to our view + view._width = opt.overlayFrameWidth + view._height = opt.overlayFrameHeight + view._top = opt.top + view._yPosition = pickerWheel.y + ( view._height * 0.5 ) - viewColumns[i] = _widget.newTableView - { - left = initialPos, - top = -110, - width = opt.columnData[i].width or availableWidth / #opt.columnData, - height = opt.overlayFrameHeight - 1, - topPadding = topPadding, - bottomPadding = bottomPadding, - noLines = true, - hideBackground = true, - hideScrollBar = true, - friction = 0.92, - rowColor = opt.columnColor, - onRowRender = _renderColumns, - maskFile = opt.maskFile, - listener = nil, - onRowTouch = didTapValue - } - viewColumns[i]._view._isUsedInPickerWheel = true + -- Assign objects to our view + view._overlay = viewOverlay + view._background = viewBackground + view._columns = viewColumns + view._didTap = false + if "function" == type(opt.onScroll) then + view._onScroll = opt.onScroll; + end; - -- Column properties - viewColumns[i]._align = opt.columnData[i].align - viewColumns[i]._fontSize = opt.fontSize + ------------------------------------------------------- + -- Assign properties/objects to the pickerWheel + ------------------------------------------------------- - -- Set the volumns initial values - viewColumns[i]._values = - { - index = opt.columnData[i].startIndex, - value = opt.columnData[i].labels[opt.columnData[i].startIndex], - } + -- Assign objects to the pickerWheel + pickerWheel._imageSheet = imageSheet + pickerWheel._view = view + pickerWheel:insert( view ) - -- Create the columns row's - for j = 1, #opt.columnData[i].labels do - viewColumns[i]:insertRow - { - rowHeight = opt.rowHeight, - rowColor = { - default = opt.columnColor, - over = opt.columnColor, - }, - label = opt.columnData[i].labels[j], - id = i, - lineColor = opt.columnColor, - } + -- Function to render the pickerWheels columns + local function _renderColumns( event ) + local phase = event.phase + local row = event.row + local fontSize = event.target._fontSize + local alignment = event.target._align + + -- Create the column's title text + local rowTitle = display.newText( row, row._label, 0, 0, opt.font, fontSize ) + rowTitle.y = row.contentHeight * 0.5 + + if _widget.isSeven() and row.index == pickerWheel._view._columns[row.id]._values.index then + rowTitle:setFillColor( 0 ) + else + rowTitle:setFillColor( unpack( opt.fontColor ) ) + end + + row.value = rowTitle.text + + -- check if the text is greater than the actual column size + local availableWidth = viewOverlay.width - 28 + local columnWidth = view._columns[ row.id ].width or availableWidth / #view._columns + local textWidth = rowTitle.contentWidth + if textWidth > columnWidth - 1 then + --cap the text + local pixelsPerChar = 23 -- aproximate median value + local numChars = columnWidth / pixelsPerChar + row._label = row._label:sub(1, numChars) + rowTitle.text = row._label + + end + + -- Align the text as requested + if "center" == alignment then + + local rowTitleX + if isGraphicsV1 then + rowTitleX = row.x + else + rowTitleX = row.x + columnWidth * 0.5 + end + rowTitle.x = rowTitleX + + elseif "left" == alignment then + + local rowTitleX + if isGraphicsV1 then + rowTitleX = ( rowTitle.contentWidth * 0.5 ) + 6 + else + rowTitleX = row.x + 6 + rowTitle.anchorX = 0 + end + rowTitle.x = rowTitleX + + elseif "right" == alignment then + + local rowTitleX + if isGraphicsV1 then + rowTitleX = row.x + ( row.contentWidth * 0.5 ) - ( rowTitle.contentWidth * 0.5 ) - 6 + else + rowTitleX = row.x + columnWidth - 6 + rowTitle.anchorX = 1 + end + rowTitle.x = rowTitleX + + end + + end - -- Insert the pickerWheel column into the view - view:insert( viewColumns[i] ) - - -- Scroll to the defined index -- TODO needs failsafe - viewColumns[i]:scrollToIndex( opt.columnData[i].startIndex, 0 ) - end - - -- Create the column seperators - for i = 1, #opt.columnData - 1 do - view:_createSeperator( viewColumns[i].x + viewColumns[i]._view._width * 0.5 ) - end - - -- Push the view's background to the front. - viewOverlay:toFront() - - ---------------------------------------------------------- - -- PUBLIC METHODS - ---------------------------------------------------------- - - -- Function to retrieve the column values - function pickerWheel:getValues() - return self._view:_getValues() - end - - -- Function to scroll to a specific pickerWheel column row - function pickerWheel:scrollToIndex( ... ) - local arg = { ... } - - local column = nil - - -- If the first arg is a number, set the column to that - if "number" == type( arg[1] ) then - column = arg[1] - - -- We have retrieved the column, now set arg1 to arg2 (which is the index to scroll to) so scrollTo index gets called as expected - arg[1] = arg[2] + -- Create a background to sit behind the pickerWheel + viewBackground = display.newImageRect( view, imageSheet, opt.backgroundFrame, opt.overlayFrameWidth, opt.overlayFrameHeight ) + viewBackground.x = viewOverlay.x + viewBackground.y = viewOverlay.y + + -- Function to create the column seperator + function view:_createSeperator( x ) + local seperator = display.newImageRect( self, imageSheet, opt.seperatorFrame, opt.seperatorFrameWidth + 4, opt.backgroundFrameHeight ) + seperator.x = x + + return seperator end + + -- The available width for the whole pickerWheel (to fit columns) + local availableWidth = viewOverlay.width - 28 - arg[4] = self._view:_getValues() - - -- Scroll to the specified column index - return self._view._columns[column]:scrollToIndex( unpack( arg ) ) - end - - ---------------------------------------------------------- - -- PRIVATE METHODS - ---------------------------------------------------------- - - -- Override scale function as pickerWheels don't support it - function pickerWheel:scale() - print( M._widgetName, "Does not support scaling" ) - end - - -- EnterFrame listener for our pickerWheel - function view:enterFrame( event ) - local _pickerWheel = self.parent + -- local method that handles scrolling to the tapped / touched index + function didTapValue( event ) + local phase = event.phase + local row = event.target + if "tap" == phase or "release" == phase then + view._columns[ row.id ]:scrollToIndex( row.index ) + view._didTap = true + end + end - -- Update the y position - self._yPosition = _pickerWheel.y + ( self._height * 0.5 ) + -- Create the pickerWheel Columns (which are tableView's) + local topPadding = 84 + local bottomPadding = 96 + if isGraphicsV1 then + topPadding = 90 + bottomPadding = 92 + end + + local initialX = 0 + local initialPos = - 144 + + for i = 1, #opt.columnData do + + if i > 1 then + initialPos = viewColumns[i-1].x + viewColumns[i-1]._view._width * 0.5 + end + + viewColumns[i] = _widget.newTableView + { + left = initialPos, + top = -110, + width = opt.columnData[i].width or availableWidth / #opt.columnData, + height = opt.overlayFrameHeight - 1, + topPadding = topPadding, + bottomPadding = bottomPadding, + noLines = true, + hideBackground = false, + hideScrollBar = true, + friction = 0.92, + rowColor = opt.columnColor, + backgroundColor = opt.backgroundColor or defaultRowColor, + onRowRender = _renderColumns, + maskFile = opt.maskFile, + listener = nil, + onRowTouch = didTapValue + } + viewColumns[i]._view._isUsedInPickerWheel = true + + -- Column properties + viewColumns[i]._align = opt.columnData[i].align + viewColumns[i]._fontSize = opt.fontSize + + -- Set the volumns initial values + viewColumns[i]._values = + { + index = opt.columnData[i].startIndex, + value = opt.columnData[i].labels[opt.columnData[i].startIndex], + } + + -- Create the columns row's + for j = 1, #opt.columnData[i].labels do + viewColumns[i]:insertRow + { + rowHeight = 40, + rowColor = { + default = opt.columnColor, + over = opt.columnColor, + }, + label = opt.columnData[i].labels[j], + id = i + } + end + + -- Insert the pickerWheel column into the view + view:insert( viewColumns[i] ) + -- Scroll to the defined index -- TODO needs failsafe + viewColumns[i]:scrollToIndex( opt.columnData[i].startIndex, 0 ) + end + + -- Create the column seperators + for i = 1, #opt.columnData - 1 do + view:_createSeperator( viewColumns[i].x + viewColumns[i]._view._width * 0.5 ) + end + + -- Push the view's background to the front. + viewOverlay:toFront() + ---------------------------------------------------------- + -- PUBLIC METHODS + ---------------------------------------------------------- + + -- Function to retrieve the column values + function pickerWheel:getValues() + return self._view:_getValues() + end - -- Manage the Picker Wheels columns - for i = 1, #self._columns do - - if "ended" == self._columns[i]._view._phase and not self._columns[i]._view._updateRuntime then - if not self._didTap then - local calculatePosition = self._yPosition - self.parent.contentHeight * 0.5 - if isGraphicsV1 then - calculatePosition = self._yPosition - end - self._columns[i]._values = self._columns[i]._view:_getRowAtPosition( calculatePosition ) - else - self._columns[i]._values = self._columns[i]._view:_getRowAtIndex( self._columns[ i ]._view._lastRowIndex ) - self._didTap = false + -- Function to scroll to a specific pickerWheel column row + function pickerWheel:scrollToIndex( ... ) + local arg = { ... } + + local column = nil + + -- If the first arg is a number, set the column to that + if "number" == type( arg[1] ) then + column = arg[1] + + -- We have retrieved the column, now set arg1 to arg2 (which is the index to scroll to) so scrollTo index gets called as expected + arg[1] = arg[2] end + + arg[4] = self._view:_getValues() + + -- Scroll to the specified column index + return self._view._columns[column]:scrollToIndex( unpack( arg ) ) + end + + ---------------------------------------------------------- + -- PRIVATE METHODS + ---------------------------------------------------------- + + -- Override scale function as pickerWheels don't support it + function pickerWheel:scale() + print( M._widgetName, "Does not support scaling" ) + end + + -- EnterFrame listener for our pickerWheel + function view:enterFrame( event ) + local _pickerWheel = self.parent + + -- Update the y position + self._yPosition = _pickerWheel.y + ( self._height * 0.5 ) + + + + -- Manage the Picker Wheels columns + for i = 1, #self._columns do + + if "ended" == self._columns[i]._view._phase and not self._columns[i]._view._updateRuntime then + if not self._didTap then + local calculatePosition = self._yPosition - self.parent.contentHeight * 0.5 + if isGraphicsV1 then + calculatePosition = self._yPosition + end + self._columns[i]._values = self._columns[i]._view:_getRowAtPosition( calculatePosition ) + else + self._columns[i]._values = self._columns[i]._view:_getRowAtIndex( self._columns[ i ]._view._lastRowIndex ) + self._didTap = false + end if view._onScroll then local event = {column = i, @@ -346,143 +347,142 @@ local function createPickerWheel( pickerWheel, options ) } view._onScroll(event) end - self._columns[i]._view._phase = "none" + + self._columns[i]._view._phase = "none" + + -- update the actual values, by rerendering row + if _widget.isSeven() and nil ~= self._columns[i]._values then + self._columns[i]._view._rows[self._columns[i]._values.index]._view[ 2 ]:setFillColor( 0 ) + end + end + end - -- update the actual values, by rerendering row - if _widget.isSeven() and nil ~= self._columns[i]._values then - self._columns[i]._view._rows[self._columns[i]._values.index]._view[ 2 ]:setFillColor( 0 ) + -- Constrain x/y scale values to 1.0 + if _pickerWheel.xScale ~= 1.0 then + _pickerWheel.xScale = 1.0 + print( M._widgetName, "Does not support scaling" ) end - end + + if _pickerWheel.yScale ~= 1.0 then + _pickerWheel.yScale = 1.0 + print( M._widgetName, "Does not support scaling" ) + end + + return true end - -- Constrain x/y scale values to 1.0 - if _pickerWheel.xScale ~= 1.0 then - _pickerWheel.xScale = 1.0 - print( M._widgetName, "Does not support scaling" ) - end + Runtime:addEventListener( "enterFrame", view ) - if _pickerWheel.yScale ~= 1.0 then - _pickerWheel.yScale = 1.0 - print( M._widgetName, "Does not support scaling" ) + -- Function to retrieve the column values + function view:_getValues() + local values = {} + + -- Loop through all the columns and retrieve the values + for i = 1, #self._columns do + values[i] = self._columns[i]._values + end + + return values end + + -- Finalize function for the pickerWheel + function pickerWheel:_finalize() + -- Remove the event listener + Runtime:removeEventListener( "enterFrame", self._view ) + + -- Set the ImageSheet to nil + self._imageSheet = nil + end + + return pickerWheel +end + + +-- Function to create a new pickerWheel object ( widget.newPickerWheel ) +function M.new( options, theme ) + local customOptions = options or {} + local themeOptions = theme or {} + + -- Create a local reference to our options table + local opt = M._options - return true - end - - Runtime:addEventListener( "enterFrame", view ) - - -- Function to retrieve the column values - function view:_getValues() - local values = {} + -- Check if the requirements for creating a widget has been met (throws an error if not) + _widget._checkRequirements( customOptions, themeOptions, M._widgetName ) - -- Loop through all the columns and retrieve the values - for i = 1, #self._columns do - values[i] = self._columns[i]._values + ------------------------------------------------------- + -- Properties + ------------------------------------------------------- + + -- Positioning & properties + opt.left = customOptions.left or 0 + opt.top = customOptions.top or 0 + opt.x = customOptions.x or nil + opt.y = customOptions.y or nil + if customOptions.x and customOptions.y then + opt.left = 0 + opt.top = 0 end + opt.id = customOptions.id + opt.baseDir = customOptions.baseDir or system.ResourceDirectory + opt.maskFile = customOptions.maskFile or themeOptions.maskFile + opt.font = customOptions.font or native.systemFontBold + opt.fontSize = customOptions.fontSize or 22 + opt.fontColor = customOptions.fontColor or blackColor + opt.columnColor = customOptions.columnColor or defaultRowColor + opt.backgroundColor = customOptions.backgroundColor or defaultRowColor - return values - end - - -- Finalize function for the pickerWheel - function pickerWheel:_finalize() - -- Remove the event listener - Runtime:removeEventListener( "enterFrame", self._view ) + if _widget.isSeven() then + opt.font = customOptions.font or themeOptions.font or "HelveticaNeue-Medium" + opt.fontSize = customOptions.fontSize or themeOptions.fontSize or 20 + opt.fontColor = labelColor + end + + -- Properties + opt.rowHeight = customOptions.rowHeight or 40 + opt.columnData = customOptions.columns + opt.onScroll = customOptions.onScroll + + -- Frames & images + opt.sheet = customOptions.sheet + opt.themeSheetFile = themeOptions.sheet + opt.themeData = themeOptions.data - -- Set the ImageSheet to nil - self._imageSheet = nil - end - - return pickerWheel -end + opt.backgroundFrame = customOptions.backgroundFrame or _widget._getFrameIndex( themeOptions, themeOptions.backgroundFrame ) + opt.backgroundFrameWidth = customOptions.backgroundFrameWidth or themeOptions.backgroundFrameWidth + opt.backgroundFrameHeight = customOptions.backgroundFrameHeight or themeOptions.backgroundFrameHeight + + opt.overlayFrame = customOptions.overlayFrame or _widget._getFrameIndex( themeOptions, themeOptions.overlayFrame ) + opt.overlayFrameWidth = customOptions.overlayFrameWidth or themeOptions.overlayFrameWidth + opt.overlayFrameHeight = customOptions.overlayFrameHeight or themeOptions.overlayFrameHeight + + opt.seperatorFrame = customOptions.seperatorFrame or _widget._getFrameIndex( themeOptions, themeOptions.seperatorFrame ) + opt.seperatorFrameWidth = customOptions.seperatorFrameWidth or themeOptions.seperatorFrameWidth + opt.seperatorFrameHeight = customOptions.seperatorFrameHeight or themeOptions.seperatorFrameHeight + + ------------------------------------------------------- + -- Create the pickerWheel + ------------------------------------------------------- + + -- Create the pickerWheel object + local pickerWheel = _widget._new + { + left = opt.left, + top = opt.top, + id = opt.id or "widget_pickerWheel", + baseDir = opt.baseDir, + } + -- Create the pickerWheel + createPickerWheel( pickerWheel, opt ) + + if isGraphicsV1 then + pickerWheel:setReferencePoint( display.TopLeftReferencePoint ) + end --- Function to create a new pickerWheel object ( widget.newPickerWheel ) -function M.new( options, theme ) - local customOptions = options or {} - local themeOptions = theme or {} - - -- Create a local reference to our options table - local opt = M._options - - -- Check if the requirements for creating a widget has been met (throws an error if not) - _widget._checkRequirements( customOptions, themeOptions, M._widgetName ) - - ------------------------------------------------------- - -- Properties - ------------------------------------------------------- - - -- Positioning & properties - opt.left = customOptions.left or 0 - opt.top = customOptions.top or 0 - opt.x = customOptions.x or nil - opt.y = customOptions.y or nil - if customOptions.x and customOptions.y then - opt.left = 0 - opt.top = 0 - end - opt.id = customOptions.id - opt.baseDir = customOptions.baseDir or system.ResourceDirectory - opt.maskFile = customOptions.maskFile or themeOptions.maskFile - opt.font = customOptions.font or native.systemFontBold - opt.fontSize = customOptions.fontSize or 22 - opt.fontColor = customOptions.fontColor or blackColor - opt.columnColor = customOptions.columnColor or defaultRowColor - - if _widget.isSeven() then - opt.font = customOptions.font or themeOptions.font or "HelveticaNeue-Medium" - opt.fontSize = customOptions.fontSize or themeOptions.fontSize or 20 - opt.fontColor = labelColor - end - - -- Properties - opt.rowHeight = customOptions.rowHeight or 40 - opt.columnData = customOptions.columns - opt.onScroll = customOptions.onScroll - -- Frames & images - opt.sheet = customOptions.sheet - opt.themeSheetFile = themeOptions.sheet - opt.themeData = themeOptions.data - - opt.backgroundFrame = customOptions.backgroundFrame or _widget._getFrameIndex( themeOptions, themeOptions.backgroundFrame ) - opt.backgroundFrameWidth = customOptions.backgroundFrameWidth or themeOptions.backgroundFrameWidth - opt.backgroundFrameHeight = customOptions.backgroundFrameHeight or themeOptions.backgroundFrameHeight - - opt.overlayFrame = customOptions.overlayFrame or _widget._getFrameIndex( themeOptions, themeOptions.overlayFrame ) - opt.overlayFrameWidth = customOptions.overlayFrameWidth or themeOptions.overlayFrameWidth - opt.overlayFrameHeight = customOptions.overlayFrameHeight or themeOptions.overlayFrameHeight - - opt.seperatorFrame = customOptions.seperatorFrame or _widget._getFrameIndex( themeOptions, themeOptions.seperatorFrame ) - opt.seperatorFrameWidth = customOptions.seperatorFrameWidth or themeOptions.seperatorFrameWidth - opt.seperatorFrameHeight = customOptions.seperatorFrameHeight or themeOptions.seperatorFrameHeight - - ------------------------------------------------------- - -- Create the pickerWheel - ------------------------------------------------------- - - -- Create the pickerWheel object - local pickerWheel = _widget._new - { - left = opt.left, - top = opt.top, - id = opt.id or "widget_pickerWheel", - baseDir = opt.baseDir, - } - - -- Create the pickerWheel - createPickerWheel( pickerWheel, opt ) - - local x, y = opt.x, opt.y - if not opt.x or not opt.y then - x = opt.left + pickerWheel.contentWidth * 0.5 - y = opt.top + pickerWheel.contentHeight * 0.5 - end - pickerWheel.x, pickerWheel.y = x, y - - if isGraphicsV1 then - pickerWheel:setReferencePoint( display.TopLeftReferencePoint ) - end - - return pickerWheel + local x, y = _widget._calculatePosition( pickerWheel, opt ) + pickerWheel.x, pickerWheel.y = x, y + + return pickerWheel end -return M +return M \ No newline at end of file From bd92e3c3037a73af8a7709848b9090ae6b20b899 Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 8 Jan 2014 11:57:06 -0500 Subject: [PATCH 23/55] added getValue, setValue and fix for setDefaultSegment --- widgetLibrary/widget_segmentedControl.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/widgetLibrary/widget_segmentedControl.lua b/widgetLibrary/widget_segmentedControl.lua index 99dc625..aa171e0 100755 --- a/widgetLibrary/widget_segmentedControl.lua +++ b/widgetLibrary/widget_segmentedControl.lua @@ -432,10 +432,17 @@ local function initWithImage( segmentedControl, options ) elseif #segments == segmentNum then view:setRightSegmentActive() else - view:setMiddleSegmentActive( view._segmentNumber ) + view:setMiddleSegmentActive( segmentNum ) end end + function segmentedControl:setValue(segmentNum) + setDefaultSegment(segmentNum) + end + + function segmentedControl:getValue() + return self._view._segmentNumber + end -- Finalize function for the segmentedControl function segmentedControl:_finalize() self._view._segments = nil From 9670faadb0034ac480932386a5efd7d40bbd44e8 Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 8 Jan 2014 12:05:08 -0500 Subject: [PATCH 24/55] sync for widget._calculatePosition --- widgetLibrary/widget_panel.lua | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/widgetLibrary/widget_panel.lua b/widgetLibrary/widget_panel.lua index 977c563..16da715 100644 --- a/widgetLibrary/widget_panel.lua +++ b/widgetLibrary/widget_panel.lua @@ -9,11 +9,22 @@ local M = -- Require needed widget files local _widget = require( "widget" ) +local isGraphicsV1 = ( 1 == display.getDefault( "graphicsCompatibility" ) ) +local isByteColorRange = display.getDefault( "isByteColorRange" ) + + -- define a default color set for both graphics modes local panelDefault = { 0, 0, 0 } local shapeStrokeDefault = { 0, 0, 0 }; -local shapeFillDefault = { 0.8, 0.8, 0.8 }; + +local shapeFillDefault +if isGraphicsV1 then + shapeFillDefault = { 204, 204, 204 } +else + shapeFillDefault = { 0.8, 0.8, 0.8 } +end + -- Function to handle touches on a widget panel, function is common to all widget panel creation types (ie image files, imagesheet, and 9 slice panel creation) @@ -1191,13 +1202,9 @@ function M.new( options, theme ) if ( isGraphicsV1 ) then panel:setReferencePoint( display.CenterReferencePoint ) end - - local x, y = opt.x, opt.y - if not opt.x or not opt.y then - x = opt.left + panel.contentWidth * 0.5 - y = opt.top + panel.contentHeight * 0.5 - end - panel.x, panel.y = x, y + local x, y = _widget._calculatePosition( panel, opt ) + panel.x, panel.y = x, y + return panel end From 8b8c276c4bdd81a58ddf5ea5f0fb42f811446e88 Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 8 Jan 2014 12:32:24 -0500 Subject: [PATCH 25/55] pageSlider widget --- widgetLibrary/widget_pageslider.lua | 309 ++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 widgetLibrary/widget_pageslider.lua diff --git a/widgetLibrary/widget_pageslider.lua b/widgetLibrary/widget_pageslider.lua new file mode 100644 index 0000000..af07075 --- /dev/null +++ b/widgetLibrary/widget_pageslider.lua @@ -0,0 +1,309 @@ +-- Copyright © 2014 Top Rank Software LLC. All Rights Reserved. +-- This library includes code developed by Corona Labs Inc. (http://www.coronalabs.com). +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- * Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- * Neither the name of the company nor the names of its contributors +-- may be used to endorse or promote products derived from this software +-- without specific prior written permission. +-- * Redistributions in any form whatsoever must retain the following +-- acknowledgment visually in the program (e.g. the credits of the program): +-- 'This product includes software developed by Top Rank Software LLC' +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +-- DISCLAIMED. IN NO EVENT SHALL CORONA LABS INC. BE LIABLE FOR ANY +-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +-- Require needed widget files +local _widget = require( "widget" ) + + +local M = +{ + _options = {}, + _widgetName = "widget.newPageSlider", +} + +local isGraphicsV1 = ( 1 == display.getDefault( "graphicsCompatibility" ) ) +local isByteColorRange = display.getDefault( "isByteColorRange" ) + +local fillColorDefault +if isByteColorRange then + fillColorDefault = { 255, 255, 255 } +else + fillColorDefault = { 1, 1, 1 } +end + +local dotFillColorDefault + +if isByteColorRange then + dotFillColorDefault = { 127, 127, 127 } +else + dotFillColorDefault = { 0.5, 0.5, 0.5 } +end + +local function createPageSlider( pageSlider, options ) + local opt = options + + + local view = display.newGroup(); + + + local rect = display.newRect( 0, 0,opt.width * opt.numPages, opt.height); + rect:setFillColor(unpack(opt.fillColor)); + rect.x = rect.contentWidth / 2; + rect.y = rect.contentHeight / 2; + rect.isHitTestable = true; + view:insert(rect) + + view.x = -(opt.selectedPage-1) * opt.width + pageSlider:insert(view); + + pageSlider._view = view + pageSlider._transition = 0; + pageSlider._numPages = opt.numPages; + + local dots = {}; + local dGroup = nil + if opt.dotSegmentHeight > 0 then + dGroup = display.newGroup() + dGroup.x = (opt.width - (opt.numPages+1)*opt.dotsMargin)/ 2; + dGroup.y = opt.height - opt.dotSegmentHeight + pageSlider:insert(dGroup); + end; + + local pages = {}; + for i = 1, opt.numPages do + if opt.dotSegmentHeight > 0 then + local dot = display.newCircle(dGroup, i*opt.dotsMargin, + opt.dotSegmentHeight / 2, + opt.dotRadius) ; + dot:setFillColor(unpack(opt.dotFillColor)) + dot:setStrokeColor(unpack(opt.dotStrokeColor)); + dot.strokeWidth = 1; + dots[#dots+1] = dot + end; + + local page = display.newGroup(); + page.x = opt.width * (i - 1) --+ opt.width / 2; + page.y = 0 --opt.height / 2 + page.contentWidth = opt.width + page.contentHeight = opt.height + view:insert(page); + pages[i] = page; + end + + view._dots = dots; + + view._width = opt.width; + view._isEnabled = opt.isEnabled + view._fastSwipeTime = opt.fastSwipeTime; + view._fastSwipeDist = opt.fastSwipeDist; + pageSlider.pages = pages; + pageSlider._onChangePage = opt.onChangePage; + + function pageSlider:selectPage(iPage, isAnimated) + + local function onTransitionComplete( event ) + transition.cancel( pageSlider._transition ) ; + pageSlider._transition = 0 + + local targetX = -(self._view.selectedPage-1)* self._view._width + if ( self._view.x ~= targetX ) then + self._view.x = targetX + end + self:updateDots( self._view.selectedPage) + end + + local canChangePage = true; + if self._onChangePage then + canChangePage = self._onChangePage(iPage) + + end + + if canChangePage then + self._view.selectedPage = iPage; + end; + if ( self._transition ~= 0 ) then + transition.cancel( self._transition ) + self._transition = 0 + end + local targetX = -(self._view.selectedPage-1) * self._view._width + local _view = self._view; + if targetX ~= _view.X then + + if isAnimated then + self._transition = transition.to( + _view , + { x = targetX, + time = 1000*math.abs(targetX - _view.x)/self._view._width, + transition = easing.outQuad, + onComplete = onTransitionComplete } ) + + else + _view.x = targetX; + end; + self:updateDots( self._view.selectedPage ); + end + + end + + function pageSlider:updateDots( iPage ) + local dots = self._view._dots; + + for i = 1, #dots do + if i == iPage then + dots[i].alpha = 1.0 + else + dots[i].alpha = 0.3 + end + end + end + + + + function pageSlider:getPage( iPage ) + return self.pages[iPage]; + end + + function pageSlider:getSelected() + return self._ciew.selectedPage; + end + -- Function to set a pageSlider as active + function pageSlider:setEnabled( isEnabled ) + self._view._isEnabled = isEnabled + end + + function pageSlider:takeFocus(event) + self._view:touch(event) + end + + function view:touch( event ) + + local phase = event.phase + local currentPage = self.selectedPage; + + -- If the pageSlider isn't active, just return + if not self._isEnabled then + return + end + if "began" == phase then + display.getCurrentStage():setFocus(self); + self.isFocus = true; + native.setKeyboardFocus(nil) + if (self._transition ~= 0 ) then + transition.cancel( self._transition ) ; + self._transition = 0 + end + self._startX = event.x ; + self._lastX = event.x ; + self._startTime = event.time; + elseif ( "moved" == phase and self.isFocus == true ) then + local movedDistance = event.x - self._lastX; + local totalDistance = event.x - self._startX ; + local resist = 1; + if (( currentPage == 1 and totalDistance > 0 ) or + ( currentPage == self.parent._numPages and totalDistance < 0 ) ) then + resist = 0.3; + end + self.x = self.x + (movedDistance * resist) ; + self._lastX = event.x ; + + elseif ( "ended" == phase or "off" == phase or "cancelled" == phase ) and self._startTime then + display.getCurrentStage():setFocus(nil); + self.isFocus = false; + local totalSwipeTime = system.getTimer() - self._startTime + self._startTime = nil + local totalDistance = event.x - self._startX ; + local swipeDist = math.abs( totalDistance ) + local fastSwipeTime = self._fastSwipeTime; + local pageWidth = self._width; + if (totalSwipeTime <= fastSwipeTime and swipeDist >= self._fastSwipeDist) or + ( totalSwipeTime > fastSwipeTime and swipeDist >= pageWidth*0.5 ) then + if totalDistance < 0 then + currentPage = math.min(self.parent._numPages, currentPage + 1); + else + currentPage = math.max(1, currentPage - 1) + end + end; + self.parent:selectPage(currentPage, true) + + end + return true + end + + view:addEventListener( "touch") + pageSlider:selectPage(opt.selectedPage, false) + + + +end + +-- Function to create a new button object ( widget.newButton ) +function M.new( options, theme ) + local customOptions = options or {} + local themeOptions = theme or {} + + -- Create a local reference to our options table + local opt = M._options + + -- Positioning & properties + opt.left = customOptions.left or 0 + opt.top = customOptions.top or 0 + opt.x = customOptions.x or nil + opt.y = customOptions.y or nil + + if customOptions.x and customOptions.y then + opt.left = 0 + opt.top = 0 + end + opt.width = customOptions.width or themeOptions.width + opt.height = customOptions.height or themeOptions.height + opt.isEnabled = customOptions.isEnabled or true; + opt.numPages = customOptions.numPages or 1; + opt.fillColor = customOptions.fillColor or fillColorDefault; + opt.selectedPage = customOptions.selectedPage or 1; + opt.dotFillColor = customOptions.dotFillColor or dotFillColorDefault; + opt.dotStrokeColor = customOptions.dotStrokeColor or opt.dotFillColor + opt.dotsMargin = customOptions.dotsMargin or 35; + opt.fastSwipeTime = customOptions.fastSwipeTime or 300; + opt.dotSegmentHeight = customOptions.dotSegmentHeight or 20; + opt.dotRadius = customOptions.dotRadius or 6; + + opt.fastSwipeDist = customOptions.fastSwipeDist or display.contentWidth/10 + opt.onChangePage = ( type(customOptions.onChangePage) == "function" ) and customOptions.onChangePage or nil; + -- Create the pageslider object + local pageSlider = _widget._new + { + left = opt.left, + top = opt.top, + id = opt.id or "widget_pageslider", + baseDir = opt.baseDir, + widgetType = "pageslider", + } + createPageSlider(pageSlider, opt) + + if ( isGraphicsV1 ) then + pageSlider:setReferencePoint( display.CenterReferencePoint ) + end + + local x, y = _widget._calculatePosition( pageSlider, opt ) + pageSlider.x, pageSlider.y = x, y + + return pageSlider +end; + +return M \ No newline at end of file From 0687192b13830eddb16dce49f562c54f83150932 Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 8 Jan 2014 12:35:58 -0500 Subject: [PATCH 26/55] sync to widget._calculatePosition --- widgetLibrary/widget_editfield.lua | 49 ++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 3de726a..bfbeb0e 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -1,3 +1,33 @@ +-- Copyright © 2014 Top Rank Software LLC. All Rights Reserved. +-- This library includes code developed by Corona Labs Inc. (http://www.coronalabs.com). +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- * Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- * Neither the name of the company nor the names of its contributors +-- may be used to endorse or promote products derived from this software +-- without specific prior written permission. +-- * Redistributions in any form whatsoever must retain the following +-- acknowledgment visually in the program (e.g. the credits of the program): +-- 'This product includes software developed by Top Rank Software LLC' +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +-- DISCLAIMED. IN NO EVENT SHALL CORONA LABS INC. BE LIABLE FOR ANY +-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + -- Require needed widget files local _widget = require( "widget" ) local _storyboard = require("storyboard") @@ -11,11 +41,12 @@ local M = local isGraphicsV1 = ( 1 == display.getDefault( "graphicsCompatibility" ) ) +local isByteColorRange = display.getDefault( "isByteColorRange" ) local labelDefault = { 0, 0, 0 } local frameStrokeDefault; -if isGraphicsV1 then +if isByteColorRange then frameStrokeDefault = { 0, 0, 0 } else frameStrokeDefault = { 0, 0, 0 } @@ -23,21 +54,21 @@ end local frameFillDefault; -if isGraphicsV1 then +if isByteColorRange then frameFillDefault = { 255, 255, 255} else frameFillDefault = { 1, 1, 1 } end local frameErrorStrokeDefault; -if isGraphicsV1 then +if isByteColorRange then frameErrorStrokeDefault = { .9, 0, 0 } else frameErrorStrokeDefault = { 240, 0, 0 } end local frameErrorFillDefault; -if isGraphicsV1 then +if isByteColorRange then frameErrorFillDefault = { 0, 0, 0, 0 } else frameErrorFillDefault = { 0, 0, 0, 0 } @@ -912,13 +943,13 @@ function M.new( options, theme ) display.setDefault( "anchorY", defAnchorY) -- Set the editField's position ( set the reference point to center, just to be sure ) - - local x, y = opt.x, opt.y - if not opt.x or not opt.y then - x = opt.left + editField.contentWidth * 0.5 - y = opt.top + editField.contentHeight * 0.5 + if ( isGraphicsV1 ) then + editField:setReferencePoint( display.CenterReferencePoint ) end + local x, y = _widget._calculatePosition( editField, opt ) editField.x, editField.y = x, y + + return editField end From 844b43c178ab84a989968b3386ba6273b7d0d1a6 Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 8 Jan 2014 12:58:03 -0500 Subject: [PATCH 27/55] sync for default anchor positions --- widgetLibrary/widgetext.lua | 51 +++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/widgetLibrary/widgetext.lua b/widgetLibrary/widgetext.lua index 8bef27e..94db0a7 100644 --- a/widgetLibrary/widgetext.lua +++ b/widgetLibrary/widgetext.lua @@ -1,4 +1,5 @@ local widget = require("widget"); +local isGraphicsV1 = ( 1 == display.getDefault( "graphicsCompatibility" ) ) -- Function to retrieve a widget's theme settings local function _getTheme( widgetTheme, options ) @@ -28,12 +29,34 @@ end -- Check if the theme is ios7 local function isSeven() - return widget.themeName ~= "widget_theme_android" and - widget.themeName ~= "widget_theme_ios"; + return widget.themeName ~= "widget_theme_android" and + widget.themeName ~= "widget_theme_ios"; end --widget.isSeven = isSeven; +local function createWidget(createFunction, ...) + local defAnchorX, defAnchorY + if not isGraphicsV1 then + defAnchorX = display.getDefault( "anchorX") + defAnchorY = display.getDefault( "anchorY" ) + widget._oldAnchorX = defAnchorX + widget._oldAnchorY = defAnchorY + + display.setDefault( "anchorX", 0.5) + display.setDefault( "anchorY", 0.5 ) + + end + local w = createFunction(...) + if not isGraphicsV1 then + display.setDefault( "anchorX", defAnchorX) + display.setDefault( "anchorY", defAnchorY ) + w.anchorX = defAnchorX + w.anchorY = defAnchorY + end + return w +end + local function newPanel( options ) local theme = _getTheme( "panel", options ); if theme == nil then @@ -41,7 +64,7 @@ local function newPanel( options ) theme = _getTheme( "button", options ) end; local _panel = require( "widgets.widget_panel" ) - return _panel.new( options, theme ) + return createWidget(_panel.new, options, theme ) end widget.newPanel = newPanel; @@ -50,7 +73,7 @@ local function newButton( options ) local theme = _getTheme( "button", options ) local _button = require( "widgets.widget_button" ) - return _button.new( options, theme ) + return createWidget(_button.new, options, theme ) end widget.newButton = newButton; @@ -60,7 +83,7 @@ local function newPageSlider( options ) local theme = _getTheme( "pageslider", options ) local _pageslider = require( "widgets.widget_pageslider" ) - return _pageslider.new( options, theme ) + return createWidget(_pageslider.new, options, theme ) end widget.newPageSlider = newPageSlider; @@ -78,7 +101,7 @@ local function newEditField( options ) theme = _getTheme( "searchField", options ) end; local _editField = require( "widgets.widget_editfield" ) - return _editField.new( options, theme ) + return createWidget(_editField.new, options, theme ) end widget.newEditField = newEditField; @@ -86,7 +109,7 @@ widget.newEditField = newEditField; local function newSegmentedControl( options ) local theme = _getTheme( "segmentedControl", options ) local _segmentedControl = require( "widgets.widget_segmentedControl" ) - return _segmentedControl.new( options, theme ) + return createWidget(_segmentedControl.new, options, theme ) end widget.newSegmentedControl = newSegmentedControl; @@ -97,8 +120,8 @@ widget.newSegmentedControl = newSegmentedControl; ----------------------------------------------------------------------------------------- local old_newTableView = nil; local function newTableView( options ) - local _tableView = require( "widgets.widget_tableviewext" ) - return _tableView.new(old_newTableView, options ) + local _tableView = require( "widgets.widget_tableviewext" ) + return _tableView.new(old_newTableView, options ) end if old_newTableView ~= widget.newTableView then @@ -109,8 +132,8 @@ widget.newTableView = newTableView; local old_newScrollView = nil; local function newScrollView( options ) - local _scrollView = require( "widgets.widget_scrollviewext" ) - return _scrollView.new(old_newScrollView, options ) + local _scrollView = require( "widgets.widget_scrollviewext" ) + return _scrollView.new(old_newScrollView, options ) end if old_newScrollView ~= widget.newScrollView then @@ -128,9 +151,9 @@ widget.newSwitch = newSwitch; local function newPickerWheel( options ) - local theme = _getTheme( "pickerWheel", options ) - local _pickerWheel = require( "widgets.widget_pickerWheel" ) - return _pickerWheel.new( options, theme ) + local theme = _getTheme( "pickerWheel", options ) + local _pickerWheel = require( "widgets.widget_pickerWheel" ) + return _pickerWheel.new( options, theme ) end widget.newPickerWheel = newPickerWheel; From b4984b22bf90f0470f64781b6fec27c958894c9d Mon Sep 17 00:00:00 2001 From: atanasster Date: Thu, 9 Jan 2014 03:08:22 -0500 Subject: [PATCH 28/55] keyboard height scaled now --- widgetLibrary/widget_editfield.lua | 69 ++++++++++++++---------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index bfbeb0e..fec668c 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -79,29 +79,33 @@ end local _focusedField = nil; local function getKeyboardHeight() - local function isLandscape() - return system.orientation == "landscapeLeft" or - system.orientation == "landscapeRight" - end - - if system.getInfo("model") == "iPad" then - if isLandscape() then - return 352 - else - return 264 + local function getActualHeight() + local function isLandscape() + return system.orientation == "landscapeLeft" or + system.orientation == "landscapeRight" end - elseif system.getInfo("model") == "iPhone" or - system.getInfo("model") == "iPod" then - if isLandscape() then - return 162 - else - return 216 + local model = system.getInfo("model") + if model == "iPad" then + if isLandscape() then + return 352 + else + return 264 + end + elseif model == "iPhone" or + model == "iPod" then + if isLandscape() then + return 162 + else + return 216 + end + + else + --dear android + return math.min(efDefaults.androidKeyboardHeight, display.contentHeight / 2); end - - else - --dear android - return math.min(efDefaults.androidKeyboardHeight, display.contentHeight / 2); end + + return getActualHeight()/math.floor((display.pixelHeight / display.contentHeight) * 0.5); end -- Creates a new edit field from an image local function initEditField( editField, options ) @@ -523,12 +527,12 @@ local function initEditField( editField, options ) function editField:slideForKeyboard(neededHeight) local slideGroup = self.slideGroup; if slideGroup then --- local y = self.y; --- local parent = self.parent; --- while parent and parent.y do --- y = y + parent.y; --- parent = parent.parent --- end + -- local y = self.y; + -- local parent = self.parent; + -- while parent and parent.y do + -- y = y + parent.y; + -- parent = parent.parent + -- end local yGroup = self:getSlideGroupPosition() local groupOffset = 0 --if the group is already slid up, check difference @@ -648,7 +652,7 @@ local function initEditField( editField, options ) --async called on Submit in case other edit field is taking focus local function onHideField(event) - if _focusedField == nil or _focusedField == self then + if _focusedField == nil or _focusedField == self then native.setKeyboardFocus( nil ) _focusedField = nil; end; @@ -699,7 +703,7 @@ local function initEditField( editField, options ) timer.performWithDelay(100,onHideField ,1) self._editing = false; end - + if not editField.native then editField:_swapFakeField( true ) end @@ -933,14 +937,7 @@ function M.new( options, theme ) id = opt.id or "widget_editField", } - local defAnchorX = display.getDefault( "anchorX") - local defAnchorY = display.getDefault( "anchorY" ) - display.setDefault( "anchorX", 0.5) - display.setDefault( "anchorY", 0.5 ) - initEditField( editField, opt ) - display.setDefault( "anchorX", defAnchorX) - display.setDefault( "anchorY", defAnchorY) -- Set the editField's position ( set the reference point to center, just to be sure ) if ( isGraphicsV1 ) then @@ -948,7 +945,7 @@ function M.new( options, theme ) end local x, y = _widget._calculatePosition( editField, opt ) editField.x, editField.y = x, y - + return editField From d43294f8bf450079a77fbe2affa7162e92d69e48 Mon Sep 17 00:00:00 2001 From: atanasster Date: Thu, 9 Jan 2014 04:53:51 -0500 Subject: [PATCH 29/55] reintroduce fix for touch events was lost in the syncing --- widgetLibrary/widget_segmentedControl.lua | 24 ++++++----------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/widgetLibrary/widget_segmentedControl.lua b/widgetLibrary/widget_segmentedControl.lua index aa171e0..1d820a8 100755 --- a/widgetLibrary/widget_segmentedControl.lua +++ b/widgetLibrary/widget_segmentedControl.lua @@ -259,12 +259,13 @@ local function initWithImage( segmentedControl, options ) -- Touch listener for our segmented control function view:touch( event ) local phase = event.phase - local _segmentedControl = self.parent + local _segmentedControl = self event.target = _segmentedControl local firstSegment = 1 local lastSegment = self._totalSegments if "began" == phase then + native.setKeyboardFocus(nil) -- Loop through the segments for i = 1, self._totalSegments do local segmentedControlXPosition = self.x - ( self.contentWidth * 0.5 ) @@ -276,24 +277,11 @@ local function initWithImage( segmentedControl, options ) local currentSegment = i local segmentWidth = self._segmentWidth - - -- Work out the current segments position - - local parentOffsetX = 0 - - -- First, we check if the widget is in a group - if nil ~= self.parent and nil ~= self.parent.x then - parentOffsetX = self.parent.x - end - - --local currentSegmentLeftEdge = ( segmentedControlXPosition * 0.5 ) * currentSegment + parentOffsetX - --local currentSegmentRightEdge = segmentedControlXPosition + ( segmentWidth * currentSegment ) + parentOffsetX - - local currentSegmentLeftEdge = segmentedControlXPosition + ( segmentWidth * currentSegment ) - segmentWidth + parentOffsetX - local currentSegmentRightEdge = segmentedControlXPosition + ( segmentWidth * currentSegment ) + parentOffsetX - + local x,y = view:contentToLocal(event.x, event.y) + local currentSegmentLeftEdge = ( segmentWidth * currentSegment ) - segmentWidth + local currentSegmentRightEdge = ( segmentWidth * currentSegment ) -- If the touch is within the segments range - if event.x >= currentSegmentLeftEdge and event.x <= currentSegmentRightEdge then + if x >= currentSegmentLeftEdge and x <= currentSegmentRightEdge then -- First segment (Near left) if firstSegment == i then self:setLeftSegmentActive() From 0a8b0038d94524b19fea11667e6a2cd0fae3b897 Mon Sep 17 00:00:00 2001 From: atanasster Date: Thu, 9 Jan 2014 17:26:55 -0500 Subject: [PATCH 30/55] added device +fix for keyboard height scaling --- widgetLibrary/editfield_calibrationdb.lua | 9 ++++++++- widgetLibrary/widget_editfield.lua | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/widgetLibrary/editfield_calibrationdb.lua b/widgetLibrary/editfield_calibrationdb.lua index cde500b..ee7ecaf 100644 --- a/widgetLibrary/editfield_calibrationdb.lua +++ b/widgetLibrary/editfield_calibrationdb.lua @@ -25,7 +25,14 @@ textFieldYOffset = 0, labelXoffset = 3, labelYoffset = 2, }, - +["device-GT-I9000"] = { +fontScale = 0.99, +textFieldHeightAdjust = 12, +textFieldXOffset = 0, +textFieldYOffset = 1, +labelXoffset = 4, +labelYoffset = 2, +}, } return M diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index fec668c..07fcbbc 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -101,11 +101,11 @@ local function getKeyboardHeight() else --dear android - return math.min(efDefaults.androidKeyboardHeight, display.contentHeight / 2); + return math.min(efDefaults.androidKeyboardHeight, display.pixelHeight / 2); end end - return getActualHeight()/math.floor((display.pixelHeight / display.contentHeight) * 0.5); + return getActualHeight()/math.floor(efDefaults.fontScale); end -- Creates a new edit field from an image local function initEditField( editField, options ) From e5e402bf7c74c413f4b22be30289581af40ace20 Mon Sep 17 00:00:00 2001 From: atanasster Date: Fri, 10 Jan 2014 07:57:53 -0500 Subject: [PATCH 31/55] slideForKeyboard fix --- widgetLibrary/widget_editfield.lua | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 07fcbbc..c63d663 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -105,7 +105,7 @@ local function getKeyboardHeight() end end - return getActualHeight()/math.floor(efDefaults.fontScale); + return getActualHeight()/efDefaults.fontScale; end -- Creates a new edit field from an image local function initEditField( editField, options ) @@ -527,20 +527,14 @@ local function initEditField( editField, options ) function editField:slideForKeyboard(neededHeight) local slideGroup = self.slideGroup; if slideGroup then - -- local y = self.y; - -- local parent = self.parent; - -- while parent and parent.y do - -- y = y + parent.y; - -- parent = parent.parent - -- end local yGroup = self:getSlideGroupPosition() local groupOffset = 0 --if the group is already slid up, check difference if slideGroup._originalSlideY then groupOffset = (slideGroup._originalSlideY - yGroup) end - local lx, ly = self:contentToLocal(0,0) - local top = -ly - self.contentHeight * self.anchorY + groupOffset; + local lx, ly = self:contentToLocal(0,0) + local top = -ly + groupOffset; local kbHeight = neededHeight or getKeyboardHeight(); From 827122057c95b486931b0d52277e8165dffad2ff Mon Sep 17 00:00:00 2001 From: atanasster Date: Sat, 18 Jan 2014 03:19:34 -0500 Subject: [PATCH 32/55] fixes fix for Android keyboard slide fix for fake text color --- widgetLibrary/widget_editfield.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index c63d663..12e7149 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -101,7 +101,7 @@ local function getKeyboardHeight() else --dear android - return math.min(efDefaults.androidKeyboardHeight, display.pixelHeight / 2); + return math.min(efDefaults.androidKeyboardHeight, display.contentHeight*efDefaults.fontScale / 2); end end @@ -392,6 +392,8 @@ local function initEditField( editField, options ) editField.calibrating = opt.calibrating editField.native = opt.native; editField.fontScale = opt.fontScale; + editField.editFontColor = opt.editFontColor; + editField.editHintColor = opt.editHintColor; viewTextField.font = native.newFont( opt.editFont ) viewTextField.size = opt.editFontSize * opt.fontScale --deviceScale @@ -467,7 +469,7 @@ local function initEditField( editField, options ) local text = value; if text and text:len() > 0 then if not self.calibrating then - fakeTextField:setFillColor(unpack(opt.editFontColor)); + fakeTextField:setFillColor(unpack(self.editFontColor)); else fakeTextField:setFillColor(1,0,0,1); fakeTextField:toFront(); @@ -479,7 +481,7 @@ local function initEditField( editField, options ) end else if not self.calibrating then - fakeTextField:setFillColor(unpack(opt.editHintColor)); + fakeTextField:setFillColor(unpack(self.editHintColor)); fakeTextField.text = fakeTextField._placeholder; else fakeTextField:setFillColor(1,0,0,1); @@ -645,7 +647,7 @@ local function initEditField( editField, options ) local phase = event.phase --async called on Submit in case other edit field is taking focus - local function onHideField(event) + local function onHideField(e) if _focusedField == nil or _focusedField == self then native.setKeyboardFocus( nil ) _focusedField = nil; From 4dc79b583327c404e0a65e9c3e92a67cac90c006 Mon Sep 17 00:00:00 2001 From: atanasster Date: Sat, 18 Jan 2014 04:40:22 -0500 Subject: [PATCH 33/55] fix for setTextColor work with Graphics 2 --- widgetLibrary/widget_editfield.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 12e7149..f50fd89 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -398,8 +398,8 @@ local function initEditField( editField, options ) viewTextField.font = native.newFont( opt.editFont ) viewTextField.size = opt.editFontSize * opt.fontScale --deviceScale - viewTextField:setTextColor(opt.editFontColor[1]*255, opt.editFontColor[2]*255, - opt.editFontColor[3]*255, opt.editFontColor[4]*255); + viewTextField:setTextColor(opt.editFontColor[1], opt.editFontColor[2], + opt.editFontColor[3], opt.editFontColor[4]); local fakeTextField if not opt.native then fakeTextField = display.newText(editField, "", 0, 0, textFieldWidth, From e47f61d20b7f68086562633c5edf3888f5ffcc3e Mon Sep 17 00:00:00 2001 From: atanasster Date: Mon, 20 Jan 2014 20:59:06 -0500 Subject: [PATCH 34/55] fixes - renamed placeholder to hint - renamed widgets to buttons - fixed field width, especially for Androids - added 3 new Android device calibrations --- widgetLibrary/editfield_calibrationdb.lua | 26 ++++- widgetLibrary/widget_editfield.lua | 116 ++++++++++++---------- 2 files changed, 90 insertions(+), 52 deletions(-) diff --git a/widgetLibrary/editfield_calibrationdb.lua b/widgetLibrary/editfield_calibrationdb.lua index ee7ecaf..ed1a93b 100644 --- a/widgetLibrary/editfield_calibrationdb.lua +++ b/widgetLibrary/editfield_calibrationdb.lua @@ -26,13 +26,37 @@ labelXoffset = 3, labelYoffset = 2, }, ["device-GT-I9000"] = { -fontScale = 0.99, +fontScale = 1, textFieldHeightAdjust = 12, textFieldXOffset = 0, textFieldYOffset = 1, labelXoffset = 4, labelYoffset = 2, }, +["device-SAMSUNG-SGH-I777"] = { +fontScale = 1, +textFieldHeightAdjust = 12, +textFieldXOffset = 0, +textFieldYOffset = 0, +labelXoffset = 5, +labelYoffset = 0, +}, +["device-KFOT"] = { +fontScale = 1.9, +textFieldHeightAdjust = 12, +textFieldXOffset = 1, +textFieldYOffset = -4, +labelXoffset = 0, +labelYoffset = 0, +}, +["device-GT-I9300"] = { +fontScale = 1.12, +textFieldHeightAdjust = 12, +textFieldXOffset = 0, +textFieldYOffset = 0, +labelXoffset = 3, +labelYoffset = 1, +}, } return M diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index f50fd89..529c440 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -284,51 +284,51 @@ local function initEditField( editField, options ) end local fieldDescription, viewTextField - --add the widgets - local widgetsWidthLeft = 0; - local widgetsWidthRight = 0; - local widgets = opt.widgets; - for i = 1,#widgets do - local widget = widgets[i] - if widget.imageFrame or widget.style or widget.defaultFile then - local wgt = nil; - if (widget.kind == "icon") or (widget.kind == "clear") then - if widget.defaultFile then - wgt = display.newImage(widget.defaultFile) + --add the buttons + local buttonsWidthLeft = 0; + local buttonsWidthRight = 0; + local buttons = opt.buttons; + for i = 1,#buttons do + local button = buttons[i] + if button.imageFrame or button.style or button.defaultFile then + local btn = nil; + if (button.kind == "icon") or (button.kind == "clear") then + if button.defaultFile then + btn = display.newImage(button.defaultFile) else - wgt = display.newImage(widget.imageSheet or imageSheet, - widget.defaultFrame or themeData:getFrameIndex( opt.themeOptions[ widget.style] )) + btn = display.newImage(button.imageSheet or imageSheet, + button.defaultFrame or themeData:getFrameIndex( opt.themeOptions[ button.style] )) end - if widget.kind == "clear" then - editField._clearButton = wgt; - wgt.isVisible = false; + if button.kind == "clear" then + editField._clearButton = btn; + btn.isVisible = false; end else - wgt = _widget.newButton( - {sheet = widget.imageSheet or imageSheet, - defaultFrame = widget.defaultFrame or themeData:getFrameIndex( opt.themeOptions[ widget.style] ), - overFrame = widget.overFrame or themeData:getFrameIndex( opt.themeOptions[tostring( widget.style).."_over"] ), - defaultFile = widget.defaultFile, - overFile = widget.overFile, - onPress = widget.onPress, - onRelease = widget.onRelease + btn = _widget.newButton( + {sheet = button.imageSheet or imageSheet, + defaultFrame = button.defaultFrame or themeData:getFrameIndex( opt.themeOptions[ button.style] ), + overFrame = button.overFrame or themeData:getFrameIndex( opt.themeOptions[tostring( button.style).."_over"] ), + defaultFile = button.defaultFile, + overFile = button.overFile, + onPress = button.onPress, + onRelease = button.onRelease } ) end - if wgt then - editField:insert(wgt) - wgt.y = yCenter + opt.buttonYOffset - if widget.align == "left" then - wgt.x = xStart + widgetsWidthLeft + ( wgt.contentWidth * 0.5 )+ + if btn then + editField:insert(btn) + btn.y = yCenter + opt.buttonYOffset + if button.align == "left" then + btn.x = xStart + buttonsWidthLeft + ( btn.contentWidth * 0.5 )+ opt.spacing + opt.buttonXOffset - widgetsWidthLeft = opt.spacing + wgt.contentWidth + widgetsWidthLeft; + buttonsWidthLeft = opt.spacing + btn.contentWidth + buttonsWidthLeft; else --by default buttons are right aligned - wgt.x = xEnd - widgetsWidthRight - opt.spacing - - ( wgt.contentWidth * 0.5 ) + opt.buttonXOffset - widgetsWidthRight = opt.spacing + wgt.contentWidth + widgetsWidthRight; + btn.x = xEnd - buttonsWidthRight - opt.spacing - + ( btn.contentWidth * 0.5 ) + opt.buttonXOffset + buttonsWidthRight = opt.spacing + btn.contentWidth + buttonsWidthRight; end end; @@ -339,13 +339,13 @@ local function initEditField( editField, options ) local textLabelWidth = 0; local textLabelX = xStart; editField.label = opt.label; - editField.placeholder = opt.placeholder; + editField.hint = opt.hint; -- The label for the field if opt.label and opt.hideLabel == false then fieldDescription = display.newText( editField, opt.label, 0,0, opt.labelFont, opt.labelFontSize ); fieldDescription:setFillColor(unpack(opt.labelColor)); fieldDescription.anchorX = 0; - fieldDescription.x = xStart + widgetsWidthLeft + opt.spacing ; + fieldDescription.x = xStart + buttonsWidthLeft + opt.spacing ; fieldDescription.y = yCenter + opt.fakeLabelYOffset textLabelX = fieldDescription.x; textLabelWidth = fieldDescription.contentWidth @@ -353,20 +353,20 @@ local function initEditField( editField, options ) -- Create the textbox (that is contained within the editField) local textFieldWidth = opt.textFieldWidth; if textFieldWidth == 0 then - textFieldWidth = (xEnd - xStart) - widgetsWidthLeft - widgetsWidthRight -opt.textFieldXOffset + textFieldWidth = (xEnd - xStart) - buttonsWidthLeft - buttonsWidthRight -opt.textFieldXOffset - textLabelWidth - 2* opt.spacing; end --calculate textheight for selected font local tmpField = display.newText("W",0,0,opt.editFont,opt.editFontSize) local lineHeight = tmpField.contentHeight; tmpField:removeSelf(); - editField._xOriginal = textLabelX - opt.textFieldHeightAdjust/2 + textLabelWidth + opt.textFieldXOffset + widgetsWidthLeft + editField._xOriginal = textLabelX - opt.textFieldHeightAdjust/2 + textLabelWidth + opt.textFieldXOffset + buttonsWidthLeft editField._yOriginal = yCenter + opt.textFieldHeightAdjust/2 + opt.textFieldYOffset if opt.native then - viewTextField = native.newTextField(editField._xOriginal, editField._yOriginal, textFieldWidth,lineHeight + opt.textFieldHeightAdjust ) - viewTextField.placeholder = opt.placeholder; + viewTextField = native.newTextField(editField._xOriginal, editField._yOriginal, textFieldWidth+ opt.textFieldHeightAdjust,lineHeight + opt.textFieldHeightAdjust ) + viewTextField.placeholder = opt.hint; else - viewTextField = native.newTextField( -1000, -1000, textFieldWidth,lineHeight + opt.textFieldHeightAdjust ) + viewTextField = native.newTextField( -1000, -1000, textFieldWidth+ opt.textFieldHeightAdjust,lineHeight + opt.textFieldHeightAdjust ) end viewTextField.anchorX = 0; @@ -397,19 +397,33 @@ local function initEditField( editField, options ) viewTextField.font = native.newFont( opt.editFont ) viewTextField.size = opt.editFontSize * opt.fontScale --deviceScale - - viewTextField:setTextColor(opt.editFontColor[1], opt.editFontColor[2], - opt.editFontColor[3], opt.editFontColor[4]); + viewTextField.align = opt.align + if system.getInfo("platformName") == "Android" then + viewTextField:setTextColor(opt.editFontColor[1]*255, opt.editFontColor[2]*255, + opt.editFontColor[3]*255, opt.editFontColor[4]*255); + else + viewTextField:setTextColor(opt.editFontColor[1], opt.editFontColor[2], + opt.editFontColor[3], opt.editFontColor[4]); + end local fakeTextField if not opt.native then - fakeTextField = display.newText(editField, "", 0, 0, textFieldWidth, - lineHeight, opt.editFont, opt.editFontSize) + fakeTextField = display.newText( + {parent=editField, + text="", + x=0, + y=0, + width=textFieldWidth -2*opt.fakeLabelXOffset+2*opt.textFieldXOffset, + height=lineHeight, + font=opt.editFont, + fontSize=opt.editFontSize, + align = opt.align}) fakeTextField.anchorX = 0; - fakeTextField.x = textLabelX + textLabelWidth + widgetsWidthLeft + opt.fakeLabelXOffset ; + fakeTextField.x = textLabelX + textLabelWidth +buttonsWidthLeft + opt.fakeLabelXOffset ; fakeTextField.y = yCenter + opt.fakeLabelYOffset ; fakeTextField:setFillColor(unpack(opt.editFontColor)); fakeTextField._viewTextField = viewTextField; - fakeTextField._placeholder = opt.placeholder; + fakeTextField._hint = opt.hint; + editField._fakeTextField = fakeTextField; end; if ( opt.listener and type(opt.listener) == "function" ) then @@ -482,7 +496,7 @@ local function initEditField( editField, options ) else if not self.calibrating then fakeTextField:setFillColor(unpack(self.editHintColor)); - fakeTextField.text = fakeTextField._placeholder; + fakeTextField.text = fakeTextField._hint; else fakeTextField:setFillColor(1,0,0,1); fakeTextField:toFront(); @@ -847,7 +861,7 @@ function M.new( options, theme ) end; opt.id = customOptions.id - opt.placeholder = customOptions.placeholder or ""; + opt.hint = customOptions.hint or ""; opt.inputType = customOptions.inputType or "default" opt.isSecure = customOptions.isSecure or false; opt.returnKey = customOptions.returnKey or "done"; @@ -880,7 +894,7 @@ function M.new( options, theme ) opt.labelFont = customOptions.labelFont or themeOptions.font or native.systemFont opt.labelFontSize = customOptions.labelFontSize or themeOptions.fontSize or 14 opt.spacing = customOptions.spacing or 2; - opt.widgets = customOptions.widgets or {}; + opt.buttons = customOptions.buttons or {}; opt.listButton = customOptions.listButton or false; opt.maxChars = customOptions.maxChars or 0; opt.allowedChars = customOptions.allowedChars or nil; @@ -896,7 +910,7 @@ function M.new( options, theme ) opt.native = customOptions.native or false opt.slideGroup = customOptions.slideGroup opt.keyboardSlideTime = customOptions.keyboardSlideTime or 200 - + opt.align = customOptions.align or "left" -- Left ( 9 piece set ) opt.topLeftFrame = customOptions.topLeftFrame or _widget._getFrameIndex( themeOptions, themeOptions.topLeftFrame ) opt.middleLeftFrame = customOptions.middleLeftFrame or _widget._getFrameIndex( themeOptions, themeOptions.middleLeftFrame ) From f1b782681ed3af04b13f7375f490282bfb0956ae Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 22 Jan 2014 02:52:27 -0500 Subject: [PATCH 35/55] added labelWidth parameter --- widgetLibrary/widget_editfield.lua | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 529c440..2417db7 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -349,18 +349,22 @@ local function initEditField( editField, options ) fieldDescription.y = yCenter + opt.fakeLabelYOffset textLabelX = fieldDescription.x; textLabelWidth = fieldDescription.contentWidth - end; + end; + + local labelWidth = opt.labelWidth or textLabelWidth + buttonsWidthLeft -- Create the textbox (that is contained within the editField) local textFieldWidth = opt.textFieldWidth; + if textFieldWidth == 0 then - textFieldWidth = (xEnd - xStart) - buttonsWidthLeft - buttonsWidthRight -opt.textFieldXOffset - - textLabelWidth - 2* opt.spacing; + textFieldWidth = (xEnd - xStart) - labelWidth - buttonsWidthRight -opt.textFieldXOffset + - 2* opt.spacing; end --calculate textheight for selected font local tmpField = display.newText("W",0,0,opt.editFont,opt.editFontSize) local lineHeight = tmpField.contentHeight; tmpField:removeSelf(); - editField._xOriginal = textLabelX - opt.textFieldHeightAdjust/2 + textLabelWidth + opt.textFieldXOffset + buttonsWidthLeft + + editField._xOriginal = textLabelX - opt.textFieldHeightAdjust/2 + labelWidth + opt.textFieldXOffset editField._yOriginal = yCenter + opt.textFieldHeightAdjust/2 + opt.textFieldYOffset if opt.native then viewTextField = native.newTextField(editField._xOriginal, editField._yOriginal, textFieldWidth+ opt.textFieldHeightAdjust,lineHeight + opt.textFieldHeightAdjust ) @@ -418,7 +422,7 @@ local function initEditField( editField, options ) fontSize=opt.editFontSize, align = opt.align}) fakeTextField.anchorX = 0; - fakeTextField.x = textLabelX + textLabelWidth +buttonsWidthLeft + opt.fakeLabelXOffset ; + fakeTextField.x = textLabelX + labelWidth + opt.fakeLabelXOffset ; fakeTextField.y = yCenter + opt.fakeLabelYOffset ; fakeTextField:setFillColor(unpack(opt.editFontColor)); fakeTextField._viewTextField = viewTextField; @@ -435,7 +439,6 @@ local function initEditField( editField, options ) editField._textField = viewTextField editField._textLabelX = textLabelX - editField._textLabelWidth = textLabelWidth editField.submitOnClear = opt.submitOnClear; editField.maxChars = opt.maxChars; editField.allowedChars = opt.allowedChars; @@ -876,6 +879,7 @@ function M.new( options, theme ) opt.calibrating = customOptions.calibrating opt.textFieldWidth = customOptions.textFieldWidth or 0; + opt.labelWidth = customOptions.labelWidth opt.listener = customOptions.listener opt.onSubmit = customOptions.onSubmit opt.submitOnClear = customOptions.submitOnClear or false; @@ -895,7 +899,6 @@ function M.new( options, theme ) opt.labelFontSize = customOptions.labelFontSize or themeOptions.fontSize or 14 opt.spacing = customOptions.spacing or 2; opt.buttons = customOptions.buttons or {}; - opt.listButton = customOptions.listButton or false; opt.maxChars = customOptions.maxChars or 0; opt.allowedChars = customOptions.allowedChars or nil; if opt.allowedChars and string.len(opt.allowedChars)== 0 then From 0efa74ededf75048b1b7c2d72852441f2288b4f4 Mon Sep 17 00:00:00 2001 From: atanasster Date: Wed, 22 Jan 2014 02:53:17 -0500 Subject: [PATCH 36/55] fixes --- widgetLibrary/widget_pageslider.lua | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/widgetLibrary/widget_pageslider.lua b/widgetLibrary/widget_pageslider.lua index af07075..72b5d46 100644 --- a/widgetLibrary/widget_pageslider.lua +++ b/widgetLibrary/widget_pageslider.lua @@ -60,21 +60,19 @@ local function createPageSlider( pageSlider, options ) local view = display.newGroup(); - + pageSlider:insert(view) local rect = display.newRect( 0, 0,opt.width * opt.numPages, opt.height); rect:setFillColor(unpack(opt.fillColor)); - rect.x = rect.contentWidth / 2; - rect.y = rect.contentHeight / 2; + rect.x = rect.contentWidth / 2; + rect.y = rect.contentHeight / 2; rect.isHitTestable = true; view:insert(rect) - view.x = -(opt.selectedPage-1) * opt.width - pageSlider:insert(view); pageSlider._view = view pageSlider._transition = 0; - pageSlider._numPages = opt.numPages; + view._numPages = opt.numPages; local dots = {}; local dGroup = nil @@ -180,7 +178,7 @@ local function createPageSlider( pageSlider, options ) end function pageSlider:getSelected() - return self._ciew.selectedPage; + return self._view.selectedPage; end -- Function to set a pageSlider as active function pageSlider:setEnabled( isEnabled ) @@ -216,7 +214,7 @@ local function createPageSlider( pageSlider, options ) local totalDistance = event.x - self._startX ; local resist = 1; if (( currentPage == 1 and totalDistance > 0 ) or - ( currentPage == self.parent._numPages and totalDistance < 0 ) ) then + ( currentPage == self._numPages and totalDistance < 0 ) ) then resist = 0.3; end self.x = self.x + (movedDistance * resist) ; @@ -234,7 +232,7 @@ local function createPageSlider( pageSlider, options ) if (totalSwipeTime <= fastSwipeTime and swipeDist >= self._fastSwipeDist) or ( totalSwipeTime > fastSwipeTime and swipeDist >= pageWidth*0.5 ) then if totalDistance < 0 then - currentPage = math.min(self.parent._numPages, currentPage + 1); + currentPage = math.min(self._numPages, currentPage + 1); else currentPage = math.max(1, currentPage - 1) end @@ -280,10 +278,11 @@ function M.new( options, theme ) opt.dotStrokeColor = customOptions.dotStrokeColor or opt.dotFillColor opt.dotsMargin = customOptions.dotsMargin or 35; opt.fastSwipeTime = customOptions.fastSwipeTime or 300; + opt.fastSwipeDist = customOptions.fastSwipeDist or display.contentWidth/10 opt.dotSegmentHeight = customOptions.dotSegmentHeight or 20; opt.dotRadius = customOptions.dotRadius or 6; - opt.fastSwipeDist = customOptions.fastSwipeDist or display.contentWidth/10 + opt.onChangePage = ( type(customOptions.onChangePage) == "function" ) and customOptions.onChangePage or nil; -- Create the pageslider object local pageSlider = _widget._new From af9db59bf82f01095ca3d00917296a4869ec384a Mon Sep 17 00:00:00 2001 From: atanasster Date: Thu, 23 Jan 2014 02:03:25 -0500 Subject: [PATCH 37/55] cleanup --- widgetLibrary/widget_editfield.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 2417db7..3f0ddf7 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -686,17 +686,17 @@ local function initEditField( editField, options ) editField:slideForKeyboard() elseif "editing" == phase then -- If there is one or more characters in the textField show the cancel button, if not hide it - local sText = self.text; + local sText = event.text; local textLen = string.len(sText); if editField.allowedChars and event.newCharacters then if not string.match(editField.allowedChars, event.newCharacters) then --remove the offending character - self.text = string.gsub(sText, event.newCharacters,""); + event.target.text = string.gsub(sText, event.newCharacters,""); end end if editField.maxChars > 0 then if textLen > editField.maxChars then - self.text = string.sub(sText, 1, editField.maxChars) + event.target.text = string.sub(sText, 1, editField.maxChars) end end if editField.calibrating then From 5e06ec1bfc2250b8a5ffd6e2294167af4e0aee84 Mon Sep 17 00:00:00 2001 From: atanasster Date: Thu, 23 Jan 2014 12:51:37 -0500 Subject: [PATCH 38/55] Validation Validation enabled even if an errorFrame is not supplied --- widgetLibrary/widget_editfield.lua | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 3f0ddf7..d150bf5 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -774,14 +774,13 @@ local function initEditField( editField, options ) end; function editField:validate() + local notValid = self.required and + string.len(self._textField.text) == 0 if self._errorFrame then self.validating = true; - self._errorFrame.isVisible = - self.required and - string.len(self._textField.text) == 0 - return self._errorFrame.isVisible + self._errorFrame.isVisible = notValid end - return false + return notValid end function editField:setEditMode(value) From 31df94ca6c336d2a812dad8042c28940d8e68dd8 Mon Sep 17 00:00:00 2001 From: atanasster Date: Fri, 24 Jan 2014 16:32:19 -0500 Subject: [PATCH 39/55] isModified MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit editField:isModified() - returns true/false editField:setIsModified(boolean) - allows to reset the isModified flag to true or false. scene.isModified() — goes through all the fields on the current scene and returns the first one that is modified or nil if none scene.setIsModified(boolean) - goes through all the fields on the current scene and resets the isModified flag --- widgetLibrary/storyboardext.lua | 15 +++++++++++++++ widgetLibrary/widget_editfield.lua | 13 +++++++++++++ 2 files changed, 28 insertions(+) diff --git a/widgetLibrary/storyboardext.lua b/widgetLibrary/storyboardext.lua index d205e6b..ffa78e4 100644 --- a/widgetLibrary/storyboardext.lua +++ b/widgetLibrary/storyboardext.lua @@ -44,6 +44,21 @@ local function newScene() end + function scene.isModified() + for i,v in pairs(scene._editFields) do + if i:isModified() then + return i + end + end + return nil + end + function scene.setIsModified(value) + for i,v in pairs(scene._editFields) do + i:setIsModified(value) + end + end + + scene:addEventListener( "exitScene", onExitScene ) scene:addEventListener( "enterScene", onEnterScene ) scene:addEventListener( "createScene", onCreateScene ) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index d150bf5..077c43d 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -442,6 +442,7 @@ local function initEditField( editField, options ) editField.submitOnClear = opt.submitOnClear; editField.maxChars = opt.maxChars; editField.allowedChars = opt.allowedChars; + editField._isModified = false viewTextField._editField = editField; @@ -699,6 +700,8 @@ local function initEditField( editField, options ) event.target.text = string.sub(sText, 1, editField.maxChars) end end + editField._isModified = self._originalText ~= self.text + if editField.calibrating then editField._fakeTextField.text = self.text; end @@ -790,6 +793,16 @@ local function initEditField( editField, options ) function editField:getEditMode() return not self._fakingIt; end + function editField:setIsModified(value) + self._isModified = value == nil and false or value + end + + function editField:isModified() + return self._isModified; + end + + + -- Finalize function function editField:_finalize() --remove from storyboard From 7012d9e099677f86f27b41098a11b3bda83cc0fc Mon Sep 17 00:00:00 2001 From: atanasster Date: Fri, 24 Jan 2014 16:51:11 -0500 Subject: [PATCH 40/55] fixes for isModified --- widgetLibrary/widget_editfield.lua | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 077c43d..754328e 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -444,6 +444,7 @@ local function initEditField( editField, options ) editField.allowedChars = opt.allowedChars; editField._isModified = false + viewTextField._editField = editField; if "function" == type(opt.onClick) then @@ -461,7 +462,7 @@ local function initEditField( editField, options ) end local function onClearTap(event) - + editField._isModified = editField._originalText and string.len(editField._originalText) > 0; editField._textField.text = ""; editField._clearButton.isVisible = false; @@ -700,7 +701,7 @@ local function initEditField( editField, options ) event.target.text = string.sub(sText, 1, editField.maxChars) end end - editField._isModified = self._originalText ~= self.text + editField._isModified = editField._originalText ~= self.text if editField.calibrating then editField._fakeTextField.text = self.text; @@ -744,6 +745,7 @@ local function initEditField( editField, options ) function editField:setText(value) self._textField.text = value self:updateFakeContent(value) + self:setIsModified(false) --android sets text asynchroneously end @@ -794,7 +796,11 @@ local function initEditField( editField, options ) return not self._fakingIt; end function editField:setIsModified(value) - self._isModified = value == nil and false or value + local isModified = value == nil and false or value; + if not isModified then + self._originalText = self:getText() + end + self._isModified = isModified end function editField:isModified() From 7c089db867f6e489dca744e348ec76de65844fa8 Mon Sep 17 00:00:00 2001 From: atanasster Date: Sat, 25 Jan 2014 08:13:41 -0500 Subject: [PATCH 41/55] fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The clear button will generate a “submitted” phase - The scene.validateEditFields() and scene.isModified() will return an array of the fields or nil --- widgetLibrary/storyboardext.lua | 22 ++++++++++++++++------ widgetLibrary/widget_editfield.lua | 20 +++++++++++--------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/widgetLibrary/storyboardext.lua b/widgetLibrary/storyboardext.lua index ffa78e4..e6962d6 100644 --- a/widgetLibrary/storyboardext.lua +++ b/widgetLibrary/storyboardext.lua @@ -36,21 +36,31 @@ local function newScene() end function scene.validateEditFields() - local retVal = false + local retVal = {} for i,v in pairs(scene._editFields) do - retVal = i:validate() or retVal; + if i:validate() then + table.insert(retVal, i) + end end - return retVal - + if #retVal > 0 then + return retVal + else + return nil + end end function scene.isModified() + local retVal = {} for i,v in pairs(scene._editFields) do if i:isModified() then - return i + table.insert(retVal, i) end end - return nil + if #retVal > 0 then + return retVal + else + return nil + end end function scene.setIsModified(value) for i,v in pairs(scene._editFields) do diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 754328e..6aed632 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -463,16 +463,18 @@ local function initEditField( editField, options ) local function onClearTap(event) editField._isModified = editField._originalText and string.len(editField._originalText) > 0; - editField._textField.text = ""; - - editField._clearButton.isVisible = false; - editField:updateFakeContent("") - editField._textField._originalText = "" - event.target = editField; - if editField.submitOnClear and editField._onSubmit then - editField._onSubmit(event); - end + if string.len(editField._textField.text) > 0 then + editField._textField.text = ""; + editField._clearButton.isVisible = false; + editField:updateFakeContent("") + editField._textField._originalText = "" + event.target = editField; + if editField.submitOnClear and editField._onSubmit then + event.phase = "submitted" + editField._onSubmit(event); + end + end; return true; end From ce110171510ddc1348ca7feabf5994b996ab447f Mon Sep 17 00:00:00 2001 From: atanasster Date: Thu, 30 Jan 2014 01:01:05 -0500 Subject: [PATCH 42/55] editField MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added the event.phase = “cleared” - Removed the parameter submitOnClear - added your button options for label button label = button.label, labelColor = button.labelColor, fontSize = button.fontSize, width = button.width, height = button.height, - Fixed the spacing for the edit field x position --- widgetLibrary/widget_editfield.lua | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 6aed632..070a51d 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -290,7 +290,7 @@ local function initEditField( editField, options ) local buttons = opt.buttons; for i = 1,#buttons do local button = buttons[i] - if button.imageFrame or button.style or button.defaultFile then + if button.imageFrame or button.style or button.defaultFile or button.label then local btn = nil; if (button.kind == "icon") or (button.kind == "clear") then if button.defaultFile then @@ -312,6 +312,11 @@ local function initEditField( editField, options ) defaultFile = button.defaultFile, overFile = button.overFile, onPress = button.onPress, + label = button.label, + labelColor = button.labelColor, + fontSize = button.fontSize, + width = button.width, + height = button.height, onRelease = button.onRelease } ) @@ -364,7 +369,7 @@ local function initEditField( editField, options ) local lineHeight = tmpField.contentHeight; tmpField:removeSelf(); - editField._xOriginal = textLabelX - opt.textFieldHeightAdjust/2 + labelWidth + opt.textFieldXOffset + editField._xOriginal = textLabelX - opt.textFieldHeightAdjust/2 + labelWidth + opt.textFieldXOffset + opt.spacing editField._yOriginal = yCenter + opt.textFieldHeightAdjust/2 + opt.textFieldYOffset if opt.native then viewTextField = native.newTextField(editField._xOriginal, editField._yOriginal, textFieldWidth+ opt.textFieldHeightAdjust,lineHeight + opt.textFieldHeightAdjust ) @@ -422,7 +427,7 @@ local function initEditField( editField, options ) fontSize=opt.editFontSize, align = opt.align}) fakeTextField.anchorX = 0; - fakeTextField.x = textLabelX + labelWidth + opt.fakeLabelXOffset ; + fakeTextField.x = textLabelX + labelWidth + opt.fakeLabelXOffset + opt.spacing; fakeTextField.y = yCenter + opt.fakeLabelYOffset ; fakeTextField:setFillColor(unpack(opt.editFontColor)); fakeTextField._viewTextField = viewTextField; @@ -439,7 +444,6 @@ local function initEditField( editField, options ) editField._textField = viewTextField editField._textLabelX = textLabelX - editField.submitOnClear = opt.submitOnClear; editField.maxChars = opt.maxChars; editField.allowedChars = opt.allowedChars; editField._isModified = false @@ -470,8 +474,8 @@ local function initEditField( editField, options ) editField:updateFakeContent("") editField._textField._originalText = "" event.target = editField; - if editField.submitOnClear and editField._onSubmit then - event.phase = "submitted" + if editField._onSubmit then + event.phase = "cleared" editField._onSubmit(event); end end; @@ -902,7 +906,6 @@ function M.new( options, theme ) opt.labelWidth = customOptions.labelWidth opt.listener = customOptions.listener opt.onSubmit = customOptions.onSubmit - opt.submitOnClear = customOptions.submitOnClear or false; opt.editFontColor = customOptions.editFontColor or themeOptions.editTextColor or {0,0,0,1} opt.editHintColor = customOptions.editHintColor or {0.5,0.5,0.5,1} From ed696fdc026bd62039c3493a1f26ab47e9eb9386 Mon Sep 17 00:00:00 2001 From: atanasster Date: Fri, 31 Jan 2014 03:03:49 -0500 Subject: [PATCH 43/55] added device --- widgetLibrary/editfield_calibrationdb.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/widgetLibrary/editfield_calibrationdb.lua b/widgetLibrary/editfield_calibrationdb.lua index ed1a93b..dbb640d 100644 --- a/widgetLibrary/editfield_calibrationdb.lua +++ b/widgetLibrary/editfield_calibrationdb.lua @@ -57,6 +57,14 @@ textFieldYOffset = 0, labelXoffset = 3, labelYoffset = 1, }, +["device-X10i"] = { +fontScale = 1, +textFieldHeightAdjust = 12, +textFieldXOffset = 0, +textFieldYOffset = -1, +labelXoffset = 4, +labelYoffset = 0, +}, } return M From 5456bf796a957525babd51185037318ce64aaa54 Mon Sep 17 00:00:00 2001 From: atanasster Date: Sun, 2 Feb 2014 19:00:43 -0500 Subject: [PATCH 44/55] Fixes Added galaxy S2 to calibration Fixed issue with scrolling of text in iPhone5 --- widgetLibrary/editfield_calibrationdb.lua | 8 ++++++++ widgetLibrary/widget_editfield.lua | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/widgetLibrary/editfield_calibrationdb.lua b/widgetLibrary/editfield_calibrationdb.lua index dbb640d..13ab95e 100644 --- a/widgetLibrary/editfield_calibrationdb.lua +++ b/widgetLibrary/editfield_calibrationdb.lua @@ -65,6 +65,14 @@ textFieldYOffset = -1, labelXoffset = 4, labelYoffset = 0, }, +["device-GT-I9100"] = { +fontScale = 1, +textFieldHeightAdjust = 14, +textFieldXOffset = -4, +textFieldYOffset = -1, +labelXoffset = 0, +labelYoffset = 0, +}, } return M diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 070a51d..808a540 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -366,7 +366,7 @@ local function initEditField( editField, options ) end --calculate textheight for selected font local tmpField = display.newText("W",0,0,opt.editFont,opt.editFontSize) - local lineHeight = tmpField.contentHeight; + local lineHeight = tmpField.contentHeight + 2; tmpField:removeSelf(); editField._xOriginal = textLabelX - opt.textFieldHeightAdjust/2 + labelWidth + opt.textFieldXOffset + opt.spacing From 567f481260a7d9fe364f7092f43bf185bc612bfb Mon Sep 17 00:00:00 2001 From: atanasster Date: Tue, 4 Feb 2014 00:54:16 -0500 Subject: [PATCH 45/55] font alignment Font scaling and font alignment does not need the calibration db anymore --- widgetLibrary/editfield_defaults.lua | 46 ++++++++++++++-------------- widgetLibrary/widget_editfield.lua | 11 ++++--- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/widgetLibrary/editfield_defaults.lua b/widgetLibrary/editfield_defaults.lua index 7dcf90c..bc92d28 100644 --- a/widgetLibrary/editfield_defaults.lua +++ b/widgetLibrary/editfield_defaults.lua @@ -1,38 +1,49 @@ -local clbData = require("widgets.editfield_calibrationdb") local M = {} M.androidKeyboardHeight = 350 if "Android" == system.getInfo("platformName") then - M.textFieldYOffset = 0 - M.textFieldXOffset = 0 - M.fakeLabelYOffset = 2 - M.fakeLabelXOffset = 3 - M.textFieldHeightAdjust = 12 -elseif system.getInfo("environment") == "simulator" then + M.textFieldHeightAdjust = 18 + M.textLineAdjust = 0 + M.textFieldYOffset = - (M.textFieldHeightAdjust / 3) + M.textFieldXOffset = -1 + M.fakeLabelYOffset = 0 + M.fakeLabelXOffset = 0 + +elseif "simulator" == system.getInfo("environment") then + M.textLineAdjust = 0 M.textFieldYOffset = -1 M.textFieldXOffset = 0 M.fakeLabelYOffset = 0 M.fakeLabelXOffset = 1 M.textFieldHeightAdjust = 0; else + M.textLineAdjust = 0 M.textFieldYOffset = 0 M.textFieldXOffset = 0 - M.fakeLabelYOffset = 0 + M.fakeLabelYOffset = M.textLineAdjust / 2 M.fakeLabelXOffset = 0 M.textFieldHeightAdjust = 0; end function M:calcFontSize() - local sysType = system.getInfo("architectureInfo") local environment = system.getInfo("environment") - --local fontScale = (display.pixelWidth / display.contentWidth) * display.contentScaleX; + --default scaing for simulator local fontScale = (( display.contentWidth - (display.screenOriginX * 2) ) / display.contentScaleX) / display.contentWidth - if system.getInfo("platformName") == "Android" then + if system.getInfo("platformName") == "Android" then + --default font scaling for all versions fontScale = (display.pixelWidth / display.contentWidth) * 0.5; + --check if its an Android version 2 device + local osVersion = system.getInfo("platformVersion") + if osVersion then + local pos = string.find(osVersion,"2.") + if pos == 1 then + fontScale = 1 + end + end elseif environment == "simulator" then --in Corona simulator, check if its a tall device, which is probably Zoomed out - if display.pixelHeight > 1000 then + if display.pixelHeight > 800 then fontScale = fontScale * .5 end else @@ -127,17 +138,6 @@ end M.fontScale = M:calcFontSize() -local calibration = clbData[system.getInfo( "environment").."-".. system.getInfo("model")] -if calibration then - M.fontScale = calibration.fontScale - M.textFieldHeightAdjust = calibration.textFieldHeightAdjust - M.textFieldYOffset = calibration.textFieldYOffset - M.textFieldXOffset = calibration.textFieldXOffset - M.fakeLabelYOffset = calibration.labelYoffset - M.fakeLabelXOffset = calibration.labelXoffset - - -end return M diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 808a540..f7d9a4a 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -365,8 +365,8 @@ local function initEditField( editField, options ) - 2* opt.spacing; end --calculate textheight for selected font - local tmpField = display.newText("W",0,0,opt.editFont,opt.editFontSize) - local lineHeight = tmpField.contentHeight + 2; + local tmpField = display.newText("qÖ",0,0,opt.editFont,opt.editFontSize) + local lineHeight = tmpField.contentHeight + efDefaults.textLineAdjust; tmpField:removeSelf(); editField._xOriginal = textLabelX - opt.textFieldHeightAdjust/2 + labelWidth + opt.textFieldXOffset + opt.spacing @@ -697,9 +697,10 @@ local function initEditField( editField, options ) local sText = event.text; local textLen = string.len(sText); if editField.allowedChars and event.newCharacters then - if not string.match(editField.allowedChars, event.newCharacters) then - --remove the offending character - event.target.text = string.gsub(sText, event.newCharacters,""); + if not string.find(editField.allowedChars, event.newCharacters,1,true) then + --remove escape characters + local plainChars = string.gsub(event.newCharacters,"(%W)","%%%1") + event.target.text = string.gsub(sText, plainChars, "") end end if editField.maxChars > 0 then From e18edc025f56f1e6adaf6ec835b1a7ea285aadf9 Mon Sep 17 00:00:00 2001 From: atanasster Date: Tue, 4 Feb 2014 00:56:14 -0500 Subject: [PATCH 46/55] Delete editfield_calibrationdb.lua calibration db not needed anymore --- widgetLibrary/editfield_calibrationdb.lua | 79 ----------------------- 1 file changed, 79 deletions(-) delete mode 100644 widgetLibrary/editfield_calibrationdb.lua diff --git a/widgetLibrary/editfield_calibrationdb.lua b/widgetLibrary/editfield_calibrationdb.lua deleted file mode 100644 index 13ab95e..0000000 --- a/widgetLibrary/editfield_calibrationdb.lua +++ /dev/null @@ -1,79 +0,0 @@ -local M = - -{ -["device-SAMSUNG-SGH-I896"] = { -fontScale = 1, -textFieldHeightAdjust = 12, -textFieldXOffset = 0, -textFieldYOffset = 0, -labelXoffset = 4, -labelYoffset = 1 -}, -["device-SGH-I727R"] = { -fontScale = 1, -textFieldHeightAdjust = 12, -textFieldXOffset = -1, -textFieldYOffset = 0, -labelXoffset = 3, -labelYoffset = 0, -}, -["device-SM-N900W8"] = { -fontScale = 1.12, -textFieldHeightAdjust = 13, -textFieldXOffset = 0, -textFieldYOffset = 0, -labelXoffset = 3, -labelYoffset = 2, -}, -["device-GT-I9000"] = { -fontScale = 1, -textFieldHeightAdjust = 12, -textFieldXOffset = 0, -textFieldYOffset = 1, -labelXoffset = 4, -labelYoffset = 2, -}, -["device-SAMSUNG-SGH-I777"] = { -fontScale = 1, -textFieldHeightAdjust = 12, -textFieldXOffset = 0, -textFieldYOffset = 0, -labelXoffset = 5, -labelYoffset = 0, -}, -["device-KFOT"] = { -fontScale = 1.9, -textFieldHeightAdjust = 12, -textFieldXOffset = 1, -textFieldYOffset = -4, -labelXoffset = 0, -labelYoffset = 0, -}, -["device-GT-I9300"] = { -fontScale = 1.12, -textFieldHeightAdjust = 12, -textFieldXOffset = 0, -textFieldYOffset = 0, -labelXoffset = 3, -labelYoffset = 1, -}, -["device-X10i"] = { -fontScale = 1, -textFieldHeightAdjust = 12, -textFieldXOffset = 0, -textFieldYOffset = -1, -labelXoffset = 4, -labelYoffset = 0, -}, -["device-GT-I9100"] = { -fontScale = 1, -textFieldHeightAdjust = 14, -textFieldXOffset = -4, -textFieldYOffset = -1, -labelXoffset = 0, -labelYoffset = 0, -}, -} - -return M - From 509a20f842cab9ee7676b5271f33abc8b8ca6b0d Mon Sep 17 00:00:00 2001 From: atanasster Date: Tue, 4 Feb 2014 02:05:56 -0500 Subject: [PATCH 47/55] event.target Updated event.target to point to the edit field when buttons pressed or clicked --- widgetLibrary/widget_editfield.lua | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index f7d9a4a..54ae773 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -305,19 +305,34 @@ local function initEditField( editField, options ) end else + local onPress + if button.onPress then + onPress = function (event) + event.target = editField + button.onPress(event) + end + end + local onRelease + if button.onRelease then + onRelease = function (event) + event.target = editField + button.onRelease(event) + end + end + btn = _widget.newButton( {sheet = button.imageSheet or imageSheet, defaultFrame = button.defaultFrame or themeData:getFrameIndex( opt.themeOptions[ button.style] ), overFrame = button.overFrame or themeData:getFrameIndex( opt.themeOptions[tostring( button.style).."_over"] ), defaultFile = button.defaultFile, overFile = button.overFile, - onPress = button.onPress, + onPress = onPress, label = button.label, labelColor = button.labelColor, fontSize = button.fontSize, width = button.width, height = button.height, - onRelease = button.onRelease + onRelease = onRelease } ) end @@ -625,6 +640,7 @@ local function initEditField( editField, options ) if editField._onClick == nil then editField:_swapFakeField( false ) else + event.target = editField editField._onClick(event) end elseif ( "ended" == phase or "off" == phase or "cancelled" == phase ) then From 6e46d288bcfce6b5154650413c9d7858e894aae1 Mon Sep 17 00:00:00 2001 From: atanasster Date: Thu, 6 Feb 2014 02:19:55 -0500 Subject: [PATCH 48/55] :getVersion added getVersion function --- widgetLibrary/widget_editfield.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 54ae773..78a376d 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -32,6 +32,7 @@ local _widget = require( "widget" ) local _storyboard = require("storyboard") local efDefaults = require("widgets.editfield_defaults") +local version = "1.01" local M = { @@ -830,7 +831,9 @@ local function initEditField( editField, options ) return self._isModified; end - + function editField:getVersion() + return version + end -- Finalize function function editField:_finalize() From 4e68a315b348c9a631afc93506b490083e1a8b35 Mon Sep 17 00:00:00 2001 From: Renato Cordeiro Date: Thu, 27 Feb 2014 11:40:08 -0800 Subject: [PATCH 49/55] added "..." to the text inserted when the text is bigger than the editField space --- widgetLibrary/widget_editfield.lua | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 78a376d..a7770ec 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -504,6 +504,23 @@ local function initEditField( editField, options ) ---------------------------------------------------------- -- PUBLIC METHODS ---------------------------------------------------------- + + + local function adjustTextSize(textObject, limit) + local text = textObject.text + local extraWidth = textObject.width - limit + if extraWidth > 0 then + while extraWidth > 0 do + local percentReduction = limit / textObject.width + local totalChars = text:len() + local charactersToRemove = math.ceil(totalChars * (1-percentReduction) + 3) + text = text:sub(1,totalChars-charactersToRemove) .. "..." + textObject.text = text + extraWidth = textObject.width - limit + end + end + end + function editField:updateFakeContent(value) if self._fakingIt then local fakeTextField = self._fakeTextField; @@ -517,8 +534,17 @@ local function initEditField( editField, options ) end if self.isSecure then fakeTextField.text = string.rep("•", string.len(text)); - else - fakeTextField.text = text; + else + local widthMax = fakeTextField.contentWidth + print("widthMax=", widthMax) + --fakeTextField.text = text; + + local tempText = display.newText{text=text, font=opt.editFont, fontSize=opt.editFontSize} + adjustTextSize(tempText,widthMax ) + fakeTextField.text = tempText.text; + display.remove(tempText) + print("fakeTextField.contentWidth=", fakeTextField.contentWidth) + end else if not self.calibrating then From 69d2db6bc89daf7bc7fca895a4dbab3158dd812a Mon Sep 17 00:00:00 2001 From: Renato Cordeiro Date: Tue, 1 Apr 2014 14:05:47 -0700 Subject: [PATCH 50/55] added support to textBox (just use flag "isTextBox = true" in the params); improved iPhone5 aligned --- widgetLibrary/editfield_defaults.lua | 58 ++++++++++++++++++++-- widgetLibrary/widget_editfield.lua | 72 +++++++++++++++++++++++----- 2 files changed, 114 insertions(+), 16 deletions(-) diff --git a/widgetLibrary/editfield_defaults.lua b/widgetLibrary/editfield_defaults.lua index bc92d28..c5de076 100644 --- a/widgetLibrary/editfield_defaults.lua +++ b/widgetLibrary/editfield_defaults.lua @@ -57,10 +57,62 @@ function M:calcFontSize() end else fontScale = (display.pixelHeight / display.contentHeight) * 0.5; + end + + end + + return fontScale + +end + +function M:renatoCalcFontSize() + local environment = system.getInfo("environment") + --default scaing for simulator + local fontScale = (( display.contentWidth - (display.screenOriginX * 2) ) / display.contentScaleX) / display.contentWidth + if system.getInfo("platformName") == "Android" then + --default font scaling for all versions + fontScale = (display.pixelWidth / display.contentWidth) * 0.5; + --check if its an Android version 2 device + local osVersion = system.getInfo("platformVersion") + if osVersion then + local pos = string.find(osVersion,"2.") + if pos == 1 then + fontScale = 1 + end + end + elseif environment == "simulator" then + --in Corona simulator, check if its a tall device, which is probably Zoomed out + --print("display.pixelHeight=", display.pixelHeight) + --print("display.contentScaleY=", display.contentScaleY) + fontScale = fontScale * display.contentScaleY +-- if display.pixelHeight > 800 then -- this was not working on iPad Retina Simulator, that need to be multplied by .25 +-- fontScale = fontScale * .5 +-- end + + else + if string.match(system.getInfo("model"),"iPa") then + --iPads + if display.pixelHeight == 2048 then + --iPad retina + fontScale = (display.pixelHeight / display.contentHeight) * 0.5; + else + fontScale = 1 / display.contentScaleY + end + else + fontScale = (display.pixelHeight / display.contentHeight) * 0.5; + + -- checking what type of scalling mode used by the user + local config = require "config" -- this makes the config content be available on the _G.application variable + local configContent = _G.application.content + local configContentScale = configContent.scale + print("configContent.scale=", configContentScale) + if configContentScale == "letterBox" then -- if letterBox was used on a iPhone contentScalling, no need to have fontScale. If used, the fontScale calculated above, it will make the inputFontSize bigger than the fakeText font Size + fontScale = 1 + end + end end - return fontScale end @@ -136,8 +188,8 @@ function M:mpappasCalcFontSize() end -M.fontScale = M:calcFontSize() - +--M.fontScale = M:calcFontSize() +M.fontScale = M:renatoCalcFontSize() return M diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index a7770ec..34fff85 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -388,10 +388,22 @@ local function initEditField( editField, options ) editField._xOriginal = textLabelX - opt.textFieldHeightAdjust/2 + labelWidth + opt.textFieldXOffset + opt.spacing editField._yOriginal = yCenter + opt.textFieldHeightAdjust/2 + opt.textFieldYOffset if opt.native then - viewTextField = native.newTextField(editField._xOriginal, editField._yOriginal, textFieldWidth+ opt.textFieldHeightAdjust,lineHeight + opt.textFieldHeightAdjust ) - viewTextField.placeholder = opt.hint; + if opt.isTextBox then -- this option op.native with isTextBox was not tested. Please report any bug + editField._xOriginal = editField._xOriginal - 2 + viewTextField = native.newTextBox( editField._xOriginal, editField._yOriginal, (xEnd-xStart)+2, opt.height) + else + viewTextField = native.newTextField(editField._xOriginal, editField._yOriginal, textFieldWidth+ opt.textFieldHeightAdjust,lineHeight + opt.textFieldHeightAdjust ) + viewTextField.placeholder = opt.hint; + end + else - viewTextField = native.newTextField( -1000, -1000, textFieldWidth+ opt.textFieldHeightAdjust,lineHeight + opt.textFieldHeightAdjust ) + if opt.isTextBox then + editField._xOriginal = editField._xOriginal - 2 + viewTextField = native.newTextBox( editField._xOriginal, editField._yOriginal, (xEnd-xStart)+2, opt.height) + else + viewTextField = native.newTextField( -1000, -1000, textFieldWidth+ opt.textFieldHeightAdjust,lineHeight + opt.textFieldHeightAdjust ) + end + end viewTextField.anchorX = 0; @@ -419,9 +431,12 @@ local function initEditField( editField, options ) editField.fontScale = opt.fontScale; editField.editFontColor = opt.editFontColor; editField.editHintColor = opt.editHintColor; + --print("opt.editFontSize=", opt.editFontSize) + --print("opt.fontScale=", opt.fontScale) viewTextField.font = native.newFont( opt.editFont ) viewTextField.size = opt.editFontSize * opt.fontScale --deviceScale + --print("viewTextField.size=", viewTextField.size) viewTextField.align = opt.align if system.getInfo("platformName") == "Android" then viewTextField:setTextColor(opt.editFontColor[1]*255, opt.editFontColor[2]*255, @@ -432,13 +447,39 @@ local function initEditField( editField, options ) end local fakeTextField if not opt.native then + + local fakeTextHeight = lineHeight + + if opt.isTextBox then + + local mobileOS = system.getInfo("platformName") -- "Android", "iPhone OS",... + if mobileOS == "iPhone OS" then + opt.fakeLabelXOffset = opt.fakeLabelXOffset + 3 -- +3 is small adjustment to make the display.newText be aligned with the native.textBox + opt.fakeLabelYOffset = opt.fakeLabelYOffset + 8 -- +8 is small adjustment to make the display.newText be aligned with the native.textBox + + if string.match(system.getInfo("model"),"iPa") and display.pixelHeight == 2048 then + opt.fakeLabelXOffset = opt.fakeLabelXOffset - 3 + opt.fakeLabelYOffset = opt.fakeLabelYOffset - 4 + end + + elseif mobileOS == "Android" then + opt.fakeLabelXOffset = opt.fakeLabelXOffset - 2 -- +3 is small adjustment to make the display.newText be aligned with the native.textBox + opt.fakeLabelYOffset = opt.fakeLabelYOffset + 9 + else + -- this is where Windows, HTML5,... will fall. Probably will need some adjustments also... + + end + + fakeTextHeight = viewTextField.contentHeight --- opt.fakeLabelYOffset + end + fakeTextField = display.newText( {parent=editField, text="", x=0, y=0, width=textFieldWidth -2*opt.fakeLabelXOffset+2*opt.textFieldXOffset, - height=lineHeight, + height=fakeTextHeight, font=opt.editFont, fontSize=opt.editFontSize, align = opt.align}) @@ -466,6 +507,7 @@ local function initEditField( editField, options ) viewTextField._editField = editField; + viewTextField._isTextBox = opt.isTextBox; if "function" == type(opt.onClick) then editField._onClick = opt.onClick; @@ -536,15 +578,17 @@ local function initEditField( editField, options ) fakeTextField.text = string.rep("•", string.len(text)); else local widthMax = fakeTextField.contentWidth - print("widthMax=", widthMax) - --fakeTextField.text = text; - - local tempText = display.newText{text=text, font=opt.editFont, fontSize=opt.editFontSize} - adjustTextSize(tempText,widthMax ) - fakeTextField.text = tempText.text; - display.remove(tempText) - print("fakeTextField.contentWidth=", fakeTextField.contentWidth) - + + if viewTextField._isTextBox then + fakeTextField.text = text; + else + local tempText = display.newText{text=text, font=opt.editFont, fontSize=opt.editFontSize} + adjustTextSize(tempText,widthMax ) + fakeTextField.text = tempText.text; + display.remove(tempText) + --print("fakeTextField.contentWidth=", fakeTextField.contentWidth) + end + end else if not self.calibrating then @@ -933,6 +977,8 @@ function M.new( options, theme ) end; + opt.isTextBox = customOptions.isTextBox + opt.id = customOptions.id opt.hint = customOptions.hint or ""; opt.inputType = customOptions.inputType or "default" From 2677b6dd534d29dc2886b2c5fc5e0ab31dbfa15d Mon Sep 17 00:00:00 2001 From: Renato Cordeiro Date: Wed, 2 Apr 2014 13:28:38 -0700 Subject: [PATCH 51/55] add param "useMoreTextIndicator = true" to make fakeText adds a "..." to the end of the text when it has more text than being showed; improved textBox fakeText position on iPhone 4; --- widgetLibrary/widget_editfield.lua | 64 ++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 34fff85..1bd88d3 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -429,6 +429,8 @@ local function initEditField( editField, options ) editField.calibrating = opt.calibrating editField.native = opt.native; editField.fontScale = opt.fontScale; + editField.editFont = opt.editFont; + editField.editFontSize = opt.editFontSize; editField.editFontColor = opt.editFontColor; editField.editHintColor = opt.editHintColor; --print("opt.editFontSize=", opt.editFontSize) @@ -454,16 +456,25 @@ local function initEditField( editField, options ) local mobileOS = system.getInfo("platformName") -- "Android", "iPhone OS",... if mobileOS == "iPhone OS" then + + --adjustments for iPhone 5 opt.fakeLabelXOffset = opt.fakeLabelXOffset + 3 -- +3 is small adjustment to make the display.newText be aligned with the native.textBox opt.fakeLabelYOffset = opt.fakeLabelYOffset + 8 -- +8 is small adjustment to make the display.newText be aligned with the native.textBox + -- extra adjustment for iPad Retina if string.match(system.getInfo("model"),"iPa") and display.pixelHeight == 2048 then opt.fakeLabelXOffset = opt.fakeLabelXOffset - 3 opt.fakeLabelYOffset = opt.fakeLabelYOffset - 4 + + -- extra adjustment for iPhone 4S + elseif string.match(system.getInfo("model"),"iPhone") then + opt.fakeLabelXOffset = opt.fakeLabelXOffset + 3 --2 + opt.fakeLabelYOffset = opt.fakeLabelYOffset + 1 + end elseif mobileOS == "Android" then - opt.fakeLabelXOffset = opt.fakeLabelXOffset - 2 -- +3 is small adjustment to make the display.newText be aligned with the native.textBox + opt.fakeLabelXOffset = opt.fakeLabelXOffset - 2 opt.fakeLabelYOffset = opt.fakeLabelYOffset + 9 else -- this is where Windows, HTML5,... will fall. Probably will need some adjustments also... @@ -508,6 +519,7 @@ local function initEditField( editField, options ) viewTextField._editField = editField; viewTextField._isTextBox = opt.isTextBox; + viewTextField._useMoreTextIndicator = opt.useMoreTextIndicator; if "function" == type(opt.onClick) then editField._onClick = opt.onClick; @@ -547,18 +559,19 @@ local function initEditField( editField, options ) -- PUBLIC METHODS ---------------------------------------------------------- - - local function adjustTextSize(textObject, limit) + -- reduces a newText obj to fit a max width/height and adds a "..." to the end of the text + local function adjustTextSize(textObject, limit, limitingDimension) -- limitingDimension = "width" or "height" + limitingDimension = limitingDimension or "width" local text = textObject.text - local extraWidth = textObject.width - limit - if extraWidth > 0 then - while extraWidth > 0 do - local percentReduction = limit / textObject.width + local extraWidthOrHeight = textObject[limitingDimension] - limit + if extraWidthOrHeight > 0 then + while extraWidthOrHeight > 0 do + local percentReduction = limit / textObject[limitingDimension] local totalChars = text:len() local charactersToRemove = math.ceil(totalChars * (1-percentReduction) + 3) text = text:sub(1,totalChars-charactersToRemove) .. "..." textObject.text = text - extraWidth = textObject.width - limit + extraWidthOrHeight = textObject[limitingDimension] - limit end end end @@ -576,19 +589,28 @@ local function initEditField( editField, options ) end if self.isSecure then fakeTextField.text = string.rep("•", string.len(text)); - else - local widthMax = fakeTextField.contentWidth - - if viewTextField._isTextBox then - fakeTextField.text = text; - else - local tempText = display.newText{text=text, font=opt.editFont, fontSize=opt.editFontSize} - adjustTextSize(tempText,widthMax ) + else + if viewTextField._useMoreTextIndicator then + local limitingDimension + local limitingSize + local tempText + if viewTextField._isTextBox then + limitingDimension = "height" + limitingSize = fakeTextField.height + tempText = display.newText{text=text, font=editField.editFont, fontSize=editField.editFontSize, width = fakeTextField.width} + else + limitingDimension = "width" + limitingSize = fakeTextField.contentWidth + tempText = display.newText{text=text, font= editField.editFont, fontSize=editField.editFontSize} + end + adjustTextSize(tempText,limitingSize, limitingDimension) fakeTextField.text = tempText.text; - display.remove(tempText) - --print("fakeTextField.contentWidth=", fakeTextField.contentWidth) + display.remove(tempText) + + else + fakeTextField.text = text; end - + end else if not self.calibrating then @@ -977,8 +999,8 @@ function M.new( options, theme ) end; - opt.isTextBox = customOptions.isTextBox - + opt.isTextBox = customOptions.isTextBox -- makes the widget use textBox (which is multi-line) instead of textField + opt.useMoreTextIndicator = customOptions.useMoreTextIndicator -- when set to true, adds "..." to the end of the inserted text to indicate that there is more text there opt.id = customOptions.id opt.hint = customOptions.hint or ""; opt.inputType = customOptions.inputType or "default" From ce742a3436287907b72cead0cfcb1c13d63560f4 Mon Sep 17 00:00:00 2001 From: Renato Cordeiro Date: Wed, 2 Apr 2014 21:29:21 -0700 Subject: [PATCH 52/55] adding textOnly support (requested by Kerem) --- widgetLibrary/widget_editfield.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 1bd88d3..81739d8 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -333,6 +333,7 @@ local function initEditField( editField, options ) fontSize = button.fontSize, width = button.width, height = button.height, + textOnly = button.textOnly, onRelease = onRelease } ) From 836c4bcefe3eee12db20d22a487f21511c6cb727 Mon Sep 17 00:00:00 2001 From: Renato Cordeiro Date: Wed, 2 Apr 2014 22:31:44 -0700 Subject: [PATCH 53/55] updated fakeText position of textBox for iPhone 5 --- widgetLibrary/widget_editfield.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua index 81739d8..7a3baef 100644 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -468,8 +468,8 @@ local function initEditField( editField, options ) opt.fakeLabelYOffset = opt.fakeLabelYOffset - 4 -- extra adjustment for iPhone 4S - elseif string.match(system.getInfo("model"),"iPhone") then - opt.fakeLabelXOffset = opt.fakeLabelXOffset + 3 --2 + elseif string.match(system.getInfo("model"),"iPhone") and display.pixelHeight == 960 then + opt.fakeLabelXOffset = opt.fakeLabelXOffset + 3 opt.fakeLabelYOffset = opt.fakeLabelYOffset + 1 end From e1c1fca31f86b6edd6d029fb8049c9291a5d9640 Mon Sep 17 00:00:00 2001 From: atanasster Date: Fri, 9 May 2014 11:06:03 -0400 Subject: [PATCH 54/55] Nexus 7 Added Nexus 7 calibration Fixed keyboard sliding issue --- widgetLibrary/editfield_calibrationdb.lua | 15 +++++++++++++++ widgetLibrary/editfield_defaults.lua | 11 +++++++++++ widgetLibrary/widget_editfield.lua | 20 ++++++++++++++------ 3 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 widgetLibrary/editfield_calibrationdb.lua mode change 100644 => 100755 widgetLibrary/editfield_defaults.lua mode change 100644 => 100755 widgetLibrary/widget_editfield.lua diff --git a/widgetLibrary/editfield_calibrationdb.lua b/widgetLibrary/editfield_calibrationdb.lua new file mode 100644 index 0000000..0886a98 --- /dev/null +++ b/widgetLibrary/editfield_calibrationdb.lua @@ -0,0 +1,15 @@ +local M = + +{ +["device-Nexus 7"] = { +fontScale = 1.77, +textFieldHeightAdjust = 18, +textFieldXOffset = 3, +textFieldYOffset = -7, +labelXoffset = 0, +labelYoffset = 0, +}, +} + +return M + diff --git a/widgetLibrary/editfield_defaults.lua b/widgetLibrary/editfield_defaults.lua old mode 100644 new mode 100755 index bc92d28..59030c4 --- a/widgetLibrary/editfield_defaults.lua +++ b/widgetLibrary/editfield_defaults.lua @@ -1,4 +1,6 @@ +local clbData = require("widgets.editfield_calibrationdb") + local M = {} M.androidKeyboardHeight = 350 @@ -138,6 +140,15 @@ end M.fontScale = M:calcFontSize() +local calibration = clbData[system.getInfo( "environment").."-".. system.getInfo("model")] +if calibration then + M.fontScale = calibration.fontScale + M.textFieldHeightAdjust = calibration.textFieldHeightAdjust + M.textFieldYOffset = calibration.textFieldYOffset + M.textFieldXOffset = calibration.textFieldXOffset + M.fakeLabelYOffset = calibration.labelYoffset + M.fakeLabelXOffset = calibration.labelXoffset +end return M diff --git a/widgetLibrary/widget_editfield.lua b/widgetLibrary/widget_editfield.lua old mode 100644 new mode 100755 index 78a376d..b8b5100 --- a/widgetLibrary/widget_editfield.lua +++ b/widgetLibrary/widget_editfield.lua @@ -535,13 +535,19 @@ local function initEditField( editField, options ) function editField:slideBackKeyboard() local slideGroup = self.slideGroup + local function onSlideComplete(event) + slideGroup._restorePosition = nil + + end if slideGroup then --check if we are in a scrollview if self == slideGroup._slidingField then - self:setSlideGroupPosition(slideGroup._originalSlideY) - slideGroup._slidingField = nil + slideGroup._restorePosition = slideGroup._originalSlideY + self:setSlideGroupPosition(slideGroup._originalSlideY, onSlideComplete) + slideGroup._slidingField = nil slideGroup._originalSlideY = nil + else end end @@ -550,7 +556,9 @@ local function initEditField( editField, options ) function editField:getSlideGroupPosition() local slideGroup = self.slideGroup; local xGroup, yGroup - if slideGroup.getContentPosition and slideGroup.scrollToPosition then + if slideGroup._restorePosition then + yGroup = slideGroup._restorePosition + elseif slideGroup.getContentPosition and slideGroup.scrollToPosition then xGroup, yGroup = slideGroup:getContentPosition() else yGroup = slideGroup.y; @@ -558,12 +566,12 @@ local function initEditField( editField, options ) return yGroup end - function editField:setSlideGroupPosition(yGroup) + function editField:setSlideGroupPosition(yGroup, onSlideComplete) local slideGroup = self.slideGroup; if slideGroup.getContentPosition and slideGroup.scrollToPosition then - slideGroup:scrollToPosition({y=yGroup,time = self.keyboardSlideTime}) + slideGroup:scrollToPosition({y=yGroup,time = self.keyboardSlideTime, onComplete = onSlideComplete}) else - transition.to(slideGroup,{y = yGroup,time=self.keyboardSlideTime} ) + transition.to(slideGroup,{y = yGroup,time=self.keyboardSlideTime, onComplete = onSlideComplete} ) end end From 23c1233a491e0189f0a77a69d9c3f33912d6fdc6 Mon Sep 17 00:00:00 2001 From: atanasster Date: Sat, 10 May 2014 17:45:44 -0400 Subject: [PATCH 55/55] Resolve conflicts --- widgetLibrary/editfield_defaults.lua | 59 +--------------------------- 1 file changed, 1 insertion(+), 58 deletions(-) diff --git a/widgetLibrary/editfield_defaults.lua b/widgetLibrary/editfield_defaults.lua index d6eb750..59030c4 100755 --- a/widgetLibrary/editfield_defaults.lua +++ b/widgetLibrary/editfield_defaults.lua @@ -59,62 +59,10 @@ function M:calcFontSize() end else fontScale = (display.pixelHeight / display.contentHeight) * 0.5; - end - - end - - return fontScale - -end - -function M:renatoCalcFontSize() - local environment = system.getInfo("environment") - --default scaing for simulator - local fontScale = (( display.contentWidth - (display.screenOriginX * 2) ) / display.contentScaleX) / display.contentWidth - if system.getInfo("platformName") == "Android" then - --default font scaling for all versions - fontScale = (display.pixelWidth / display.contentWidth) * 0.5; - --check if its an Android version 2 device - local osVersion = system.getInfo("platformVersion") - if osVersion then - local pos = string.find(osVersion,"2.") - if pos == 1 then - fontScale = 1 - end - end - elseif environment == "simulator" then - --in Corona simulator, check if its a tall device, which is probably Zoomed out - --print("display.pixelHeight=", display.pixelHeight) - --print("display.contentScaleY=", display.contentScaleY) - fontScale = fontScale * display.contentScaleY --- if display.pixelHeight > 800 then -- this was not working on iPad Retina Simulator, that need to be multplied by .25 --- fontScale = fontScale * .5 --- end - - else - if string.match(system.getInfo("model"),"iPa") then - --iPads - if display.pixelHeight == 2048 then - --iPad retina - fontScale = (display.pixelHeight / display.contentHeight) * 0.5; - else - fontScale = 1 / display.contentScaleY - end - else - fontScale = (display.pixelHeight / display.contentHeight) * 0.5; - - -- checking what type of scalling mode used by the user - local config = require "config" -- this makes the config content be available on the _G.application variable - local configContent = _G.application.content - local configContentScale = configContent.scale - print("configContent.scale=", configContentScale) - if configContentScale == "letterBox" then -- if letterBox was used on a iPhone contentScalling, no need to have fontScale. If used, the fontScale calculated above, it will make the inputFontSize bigger than the fakeText font Size - fontScale = 1 - end - end end + return fontScale end @@ -190,7 +138,6 @@ function M:mpappasCalcFontSize() end -<<<<<<< HEAD M.fontScale = M:calcFontSize() local calibration = clbData[system.getInfo( "environment").."-".. system.getInfo("model")] @@ -202,10 +149,6 @@ if calibration then M.fakeLabelYOffset = calibration.labelYoffset M.fakeLabelXOffset = calibration.labelXoffset end -======= ---M.fontScale = M:calcFontSize() -M.fontScale = M:renatoCalcFontSize() ->>>>>>> FETCH_HEAD return M