widget.newEditField

Hi Rob,

This is a great example…thanks for putting it out!!

Can you teach me a few things?

Re:

 local deviceScale = (display.pixelWidth / display.contentWidth) * 0.5

 field.textField.font = native.newFont( opt.font )

 field.textField.size = opt.fontSize * deviceScale

Where did you get this math to set fontSize:    opt.height * 0.67

And what’s the point of using “deviceScale” to modify the fontSize on the native field?

Also, is “finalize” something internally supported by Corona, or is that just your personal “cleanup” convention?

Also, I’m assuming you know that function args ARE local vars (ie equally fast), so I’m not sure what advantage you seek by doing this:

function widget.newTextField(options)

    local customOptions = options or {}

    local opt = {}

 

Can you illuminate??  For example, whats wrong with one table instead of 3 to set options on constructed objects?

Oh, I guess you are afraid of overwriting the source table with defaults you set (ie pass-by-reference artifacts & all that)…is that the point?  Wouldn’t two tables suffice?

Thanks again for a great start here.

Dewey

I chose 67% of the boxes overall height for the text height by wanting to leave some white space above and below the text.  This seems to be what’s common on devices.

The deviceScale is part of getting native objects to produce text that’s on the same point size as display.newText.  In Corona since display.newText() objects live in the OpenGL world, they are subject to having their size determined by the content area.  So let’s say you’re app is a 320x480 app and you say you want a 32 point font, it’s going to be 10% of the height (in landscape)  32 points out of 320 points.  Now if your device is really a 640x960 device, Corona SDK automatically adjusts display.newText() to actually make that 32 point font a 64 pixel font on retina phones or a 32 pixel font on an iPhone 3Gs for instance.    On a Retina iPad to maintain the same scale it would need to be a 128 pixel high font (this is why we use content areas and “points” instead of pixels when talking about the content area).  This is great and Corona does what we want.

However for native.newTextField()'s and native.newTextBox()'s, the font’s don’t scale.  So that 32 point font is going to be 32 pixels on a 3GS, 32 pixels on a retina phone and 32 pixels on a retina iPad.   This doesn’t work well.   So the device Scale is a math trick to make the native font’s scale based on the device it’s actually running on.  So if you’re on a device somewhere in between it will maintain the rough percentage of height as display.newText.

Finally… finalize is a Corona SDK feature designed to help people clean up objects when they are being removed.  Let’s say you’re spawning physics objects, you can give each object a finalize event handler that would automatically remove its physics body when its display object is being destroyed for instance.  It’s a pretty cool feature.

Rob

It has been great working with Atanas testing his widget.newEditField. So much progress in such little time. Renato’s feature set sounds great too. Merging these going forward will be great! Thanks for all the efforts. 

Kerem, your help has been invaluable and your passion contagious :slight_smile:

Let me contribute with a couple of items on the todo list that have been on my mind:

  • ability to have a frame for required/validated fields (so the user has a visual cue that he needs to enter values in those fields)

  • ability to move the underlying group automatically up if the field is too low when the field receives focus - I believe Renato has already implemented this?

  • a 9 slice frame would be desirable for most control over the size of the field.

  • try to fix the alignment issues we seem to both have with Renato. I have a couple parameters that you can set in the newEditField to play around - and see what works best on the different devices and resolutions to align the fake label and the textfield:

textFieldYOffset

textFieldXOffset 

fakeLabelShiftY 

fakeLabelShiftX

  • a mode where the textfield/newText are swapped only when a scene change occurs instead of the current way every time the focus is lost. This seems would look more “native”

  • scaling, aligning

I’m coming to this discussion late, so perhaps you guys are already ahead of me, but it seems that all of this needs to be implemented on top of a scrollView so that the whole form moves as a unit and we can move the form/page up to adjust for the keyboard…is that the plan or is that too big of a bite to take??

Just a heads up on placeholders.   Apparently native.newTextField() has a .placeholder attribute that does what you want it to do.  It’s on iOS and OS-X only.  But I was trying to implement my own placeholder and ran into problems, so if you choose to implement your own, don’t call it .placeholder or it will conflict with the native one and the native one wins.

If you’re building something like an iOS settings screen, that’s done in a tableView. But most other apps, the fields are not hand-scrollable so I would just insert them into a display.newGroup() perhaps called “formGroup” and then transition it so that the currently selected field is on screen.

Rob

Rob…the docs say (as of about a week ago) that you CANNOT insert native objects into groups or move them as a unit…has that changed??

Thanks for the tip on .placeholder…that needs to be added to the docs as well…

Your point about “hand scrollable” is lost on me…whether or not “fields” are hand-scrollable, the other display objects on-screen around them certainly are, and you need it all to move as a unit…I’m probably mis-understanding something about what you are saying… please clarify if so.

No you cannot insert native objects into display groups.  This has not changed and is not going to.  However, the work being discussed here is based on a tutorial we did a couple of weeks ago as well as the native.newSearchBox() API that we never surfaced.  In this case, we draw a native.newTextField() with no background over top of a display object.  Its that display object that gets put in the display group.   In my example, I used a runtime event listener to keep the native and display fields in sync with each other.

Rob

In addition to the existing amazing achievements and the to-do lists, may I also suggest the following : 

  • Numerical text entry mode - Only numbers and one decimal point allowed.
  • Currency entry mode… Almost same as above but with a prefix currency symbol of choice (ie $, euro etc) attached to display text only. Value entered should be retained as a proper number without the currency symbol attached.
  • Keyboard mode - It is possible to control which keyboard is triggered when we enter the native.inputField. We could bring this back into the widget.newEditField options

Thanks for all the hard work. Happy holidays to you all. 

Dg, you are certainly not late - at least my code is early beta version and still trying out many thing. Kerem - excellent list of additional features. For t Validation, it would greatly help if we have a beforeedit event to control what characters are allowed without having a flickering (we could return true/false) and let know if a typed char should be allowed. For the keyboard type - do you have in mind the basic inputType parameter that we already have or to have completely custom keyboards that we pop up? Rob - I used the same name placeholder as the newTextField for consistency, but internally its only used to display text in the fake label when not in focus. I dont think it conflicts with the newTextField placeholder. However a better name would be hint, right? Thanks Atanas

Rob - do you know of a way to make newTextField invisible instead of moving it off screen?

Sorry for not being clear. I was trying to say the Return key on the keyboard being controllable in addition to inputType. Something like a 

    keyboardType = “search”, – in your widget paramaneter

which goes into the following in the widget : 

    field.textField:setReturnKey(opt.keyboardType)  

Allowable values are documented at : http://docs.coronalabs.com/api/type/TextField/setReturnKey.html

Have you tried setting isVisible or .alpha = 0 on it?  (I don’t know if it works or not)

If you move it off screen, you won’t be able to move the cursor in the middle of the field.  This is the reason why I went the route I did (as well as why Alex did the same with his search field.)

.alpha = 0 worked for me in my Search Bar as in IOS Mail App sample. 

IsVisible is not available unfortunately, that’s why I asked. I tried alpha = 0, but you can still select the field when a scene is on top of it Rob, can you explain about the cursor in the middle? Can you give a spin to my editField when you have some time -you just need the part of widgetext.lua that creates somewhere in your project : 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;

Hmm, why is it when I use the forums to post from my IPad all the new lines are taken out?

Kerem, returnKey is already an option in the constructor

When you use a native text field, the user can touch in the middle of the string and edit from there.  If you move the native.newTextField() off screen and just have it constantly update a display.newText(), then you would have no way of allowing people to touch the display.newText() and know where in the string they are touching.  The display.newText() is a rendered graphic and without knowing the font metrics you would have no way of knowing what character they are trying to select.   Then you have the issue of building in support for Select/Select All/Copy/Cut/Paste features that you get with the native.newTextField.

Your best bet is to move the native.newTextField off screen and put a touch handler on the box that moves the native.newTextField() back on screen if you want to go that route.

Rob

Ah, ok.

Currently, the first touch activates the field and a second touch can be used to display the magnifier glass and select text in the middle of the textfield. Its not like the real thing, but then we do need editFields, so I would go with a hack as long as it gives the feature.

Here is what I was thinking would give the most “native” feel - its to move the textFields offscreen only when the scenes are changed - if a scene with edit fields receives an exitScene, it moves all its textFields offscreen and replaces them with the fake labels. 

When a scene with edit fields receives an enterScene, it moves back all the text fields that are on it onscreen

This way the user will have a “native” experience with the active scene (will not have to use one extra touch to activate the fields) and we can still have a workable solution to display overlays and scenes on top of other scenes. 

I have started subclassing storyboard to maintain internally a list of editFields on each scene, and to automatically hide/show the textfields and will upload it later.

I don’t really get your suggestion with the touch handler on the label and then how to send a touch event to the native.textField that is offscreen?

Anyone any other ideas?

Atanas

Aaaah, now I see you what you were saying about offscreen and update the label from the textField. But thats not how newEditField is implemented currently as it would be really unnatural feeling - currently the textFields are moved on-screen as soon as the user touches the fake label and the focus is set to the textField so the keyboard shows right away. When the textField loses focus, its immediately removed offscreen and replaced by the label.

So I guess the current implementation is the same as your suggestion. The only drawback is that the magnifier glass shows only on a second tap by the user.

I thought your suggestion was to send touch events to the TextField to set the magnifier glass at a specific position from the first touch.