Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TextInput (TextBlockTextEditor) throws errors if used in a pop up #999

Closed
SirGordon opened this issue Oct 22, 2014 · 5 comments
Closed

TextInput (TextBlockTextEditor) throws errors if used in a pop up #999

SirGordon opened this issue Oct 22, 2014 · 5 comments
Labels
Milestone

Comments

@SirGordon
Copy link

Using the latest sources from the master branch.
Reproduce steps:
create a class for a pop up:

public class Example extends Panel {

    private var textInput : TextInput;

    override protected function initialize():void {
        super.initialize();
        addChild(textInput = new TextInput());
    }
}

create a popup somewhere like this:

var example : Example = new Example();
PopUpManager.addPopUp(example);

then focus into the text input, type something there.
Next, remove pop up:

PopUpManager.removePopUp(example);

Finally, click on some feathers component for Error.

Another error occures if we are disposing:

PopUpManager.removePopUp(example, true);

Then, to produce the error, you need to continue typing after the popup removed, there will be another error, because the TextInput is still listening for keyboard.

P.S.: this did not help:

FocusManager.focus = null;

Or, maybe I'm doing something wrong..

@joshtynjala joshtynjala added this to the 2.1 milestone Oct 22, 2014
@joshtynjala
Copy link
Member

Thanks. I'll investigate!

@SirGordon
Copy link
Author

If dispose = false, it looks like it's getting focus after being removed from stage, so setting textInput.isFocusEnabled to false before removing the pop up helps to not get Errors.

@joshtynjala
Copy link
Member

I'm not sure how to reproduce this issue. I tried the following code, and everything seemed to be working correctly:

new MetalWorksDesktopTheme();

var button:Button = new Button();
button.label = "Click Me";
button.addEventListener(Event.TRIGGERED, function():void
{
    trace("triggered");
});
this.addChild(button);

var panel:Panel = new Panel();
panel.layout = new VerticalLayout();
var input:TextInput = new TextInput();
input.addEventListener(FeathersEventType.ENTER, function():void
{
    PopUpManager.removePopUp(panel, true);
})
panel.addChild(input);
PopUpManager.addPopUp(panel);

The only thing that wasn't clear to me, from your description, was how or when to remove the pop-up. I decided to remove it when the TextInput dispatches FeathersEventType.ENTER.

@SirGordon
Copy link
Author

In my case, there is a text input and a button in the pop up.
First, we type something into the text input.
Then, we click the button, and in the EVENT.TRIGGERED listener, we call PopUpManager.removePopUp.

@SirGordon
Copy link
Author

I don't think I'm doing anything criminal here, except namespaces..
Anyway, this is how I do it (Sorry, the code might look bad 😆)

package {
import feathers.controls.Alert;
import feathers.controls.Button;
import feathers.controls.LayoutGroup;
import feathers.controls.List;
import feathers.controls.Panel;
import feathers.controls.TextInput;
import feathers.core.PopUpManager;
import feathers.data.ListCollection;
import feathers.layout.HorizontalLayout;
import feathers.layout.VerticalLayout;
import feathers.layout.VerticalLayoutData;

import flash.utils.Dictionary;

import starling.events.Event;

public class MapOpenSaveUI extends Panel {

    public namespace mode_open;
    public namespace mode_save;

    private var _modeNs : Namespace;
    private var proxy : MapEditorProxy;
    private var deletedObjectsMap : Dictionary;

    private var cancelButton : Button;
    private var bottomButtonsGroup : LayoutGroup;

    private var mapList : List;
    private var openButton : Button;

    private var mapNameTextInput : TextInput;
    private var saveButton : Button;

    public function MapOpenSaveUI(modeNameSpace:Namespace, proxy:MapEditorProxy, deletedObjectsMap:Dictionary) {
        _modeNs = modeNameSpace;
        this.proxy = proxy;
        this.deletedObjectsMap = deletedObjectsMap;
    }

    private function mapSavedHandler(event:MapEditorEvent):void {
        close();
    }

    private function mapListReceivedHandler(event:MapEvent):void {
        mapList.dataProvider = new ListCollection(event.maps);
        if(mapList.dataProvider.length > 0) {
            mapList.selectedIndex = 0;
            openButton.isEnabled = true;
        }
    }

    override protected function initialize():void {
        super.initialize();

        layout = new VerticalLayout();
        VerticalLayout(layout).horizontalAlign = VerticalLayout.HORIZONTAL_ALIGN_RIGHT;
        VerticalLayout(layout).gap = 8;

        bottomButtonsGroup = new LayoutGroup();
        bottomButtonsGroup.layout = new HorizontalLayout();
        HorizontalLayout(bottomButtonsGroup.layout).gap = 8;

        _modeNs::init();

        addChild(bottomButtonsGroup);

        bottomButtonsGroup.addChild(cancelButton = new Button());
        cancelButton.label = "Cancel";
        cancelButton.addEventListener(Event.TRIGGERED, close);
    }

    private function close(event : Event = null) : void {
        dispatchEvent(new MapListUIEvent(MapListUIEvent.CANCEL));
        // Workaround to not get errors like https://github.com/joshtynjala/feathers/issues/999
        if(mapNameTextInput)
            mapNameTextInput.isFocusEnabled = false;
        PopUpManager.removePopUp(this);
        cancelButton.removeEventListener(Event.TRIGGERED, close);
        _modeNs::destructor();
    }

    mode_open function init() : void {
        headerProperties.title = "Open Map";

        width = 640;
        height = 480;

        addChild(mapList = new List());
        mapList.layoutData = new VerticalLayoutData(100, 100);
        mapList.itemRendererProperties.labelField = "name";

        bottomButtonsGroup.addChild(openButton = new Button());
        openButton.label = "Open";
        openButton.addEventListener(Event.TRIGGERED, openButtonHandler);
        openButton.isEnabled = false;

        proxy.addEventListener(MapEvent.MAP_LIST_RECEIVED, mapListReceivedHandler);
        proxy.getMapList();
    }

    private function openButtonHandler(event:Event):void {
        proxy.openMap(mapList.selectedItem);
        close();
    }

    mode_save function init() : void {
        headerProperties.title = "Save Map As";

        addChild(mapNameTextInput = new TextInput());
        mapNameTextInput.text = proxy.currentMapName;
        mapNameTextInput.width = 256;

        bottomButtonsGroup.addChild(saveButton = new Button());
        saveButton.label = "Save";
        saveButton.addEventListener(Event.TRIGGERED, saveButtonHandler);

        proxy.addEventListener(MapEditorEvent.MAP_SAVED, mapSavedHandler);
    }

    private function saveButtonHandler(event:Event):void {
        if(mapNameTextInput.text == "Basic") {
            Alert.show(
                    "Unable to overwrite Basic map. It is prohibited.",
                    "Error: unable to save map",
                    new ListCollection([
                        {label: "Got it"}
                    ])
            );
        }
        else if(mapNameTextInput.text == proxy.currentMapName)
            proxy.saveMap(deletedObjectsMap);
        else
            proxy.saveMapAs(mapNameTextInput.text);
    }

    mode_save function destructor() : void {
        saveButton.removeEventListener(Event.TRIGGERED, saveButtonHandler);
        proxy.removeEventListener(MapEditorEvent.MAP_SAVED, mapSavedHandler);
    }

    mode_open function destructor() : void {
        openButton.removeEventListener(Event.TRIGGERED, openButtonHandler);
        proxy.removeEventListener(MapEvent.MAP_LIST_RECEIVED, mapListReceivedHandler);
    }
}
}

P.S.: namespace passed to the constructor is one of the public namespaces described in this class. Proxy is just a model class with data.

joshtynjala added a commit that referenced this issue Sep 8, 2015
…ildren as a pop-up wouldn't properly set the focus manager on the children (closes #999)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants