How to set a component visible true or false when another component do a action - litho

Now what I'm trying to do is that when my CustomCheckboxSpec component in the onCheckboxClicked event sends a true or false value for the isChecked parameter, it calls the CustomText component and through the setVisible function and by the parameters I can locate which CustomText elements I want to put visually true or false.
With what function I can search for the elements in CustomText?
How can I change the visibility for that element?
//CustomCheckboxSpec class
#LayoutSpec
public class CustomCheckboxSpec {
...`enter code here`
#OnEvent(ClickEvent.class)
static void onCheckboxClicked(
ComponentContext c, #FromEvent View view
, #Prop OnCheckboxClickListener listener, #State boolean isChecked
, #Prop int idPregunta, #Prop int idRespuesta) {
listener.onCheckboxClick(!isChecked, idPregunta, idRespuesta);
CustomCheckbox.updateCheckboxAsync(c);
}
}
//MainActivity class
CustomCheckbox.create(componentContext).listener(new CustomCheckboxSpec.OnCheckboxClickListener() {
#Override
public void onCheckboxClick(boolean valor, int idPregunta, int idRespuesta)
{
/*call the component CustomTextSpec and in function
#OnUpdateState
static void setVisible(someParams) {
//with params search for child
//change child visibility
}*/
}

Related

Libgdx | Custom Action

How can I create a custom action for an actor in libgdx? If I can't, than is there at least an action to run a custom piece of code (eg. call a method action)? Thanks.
EDIT:
I created this class :
class GapSizeAction extends TemporalAction {
private float newSize;
private Blocker blocker;
public static GapSizeAction getRotateAction(float newSize, float duration) {
return new GapSizeAction(newSize, duration);
}
public GapSizeAction(float newSize, float duration) {
super(duration);
System.out.println("Construct");
this.blocker = (Blocker)target;
this.newSize = newSize;
}
private float start, end;
protected void begin() {
System.out.println("Begin");
start = blocker.gap;
}
protected void update(float percent) {
blocker.gap = (start + (end - start) * percent);
}
}
The problem is that I am using a custom actor with a gap member (float). I try to cast the target to a blocker so that I can access the gap member variable, but gap ends up being null. I can confirm that gap is not null, I initialize it in the constructor. The blocker (Custom actor) is not null either. Am I going about this wrong?
Your problem is the line this.blocker = (Blocker)target; in your constructor. When the constructor is called, the action hasn't been set on a target yet, so target is null (and so will be blocker). Also, since you're changing a single float, you can extend FloatAction and save yourself some code. I would write your class as below. The constructor should be empty to support easy pooling, and you can set it up in your static factory method.
class GapSizeAction extends FloatAction {
public static GapSizeAction getRotateAction(float newSize, float duration){
GapSizeAction action = Actions.action(GapSizeAction.class);
action.setEnd(newSize);
action.setDuration(duration);
return action;
}
protected void begin () {
if (target instanceof Blocker)
setStart(((Blocker)target).gap);
else
Gdx.app.logError("Target is not a blocker: " + target.toString());
super.begin();
}
protected void update (float percent) {
super.update(percent);
if (target instanceof Blocker)
((Blocker)target).gap = getValue();
}
}
Fade In Action for example :
actor.AddAction(Actions.fadeIn(2.0f));

Construction of generic type parameter in Haxe

I'm trying to instantiate a class based on a function type parameter.
Although the documentation says it is possible, I can't make it work.
Consider the following code:
// Dialog base class
// Every dialog in my application will derive from this
class Dialog
{
public function new()
{
// do some stuff here
}
}
// One of the possible dialogs in the application
// Extends Dialog
class TestDialog extends Dialog
{
public function new()
{
super();
// do some more stuff
}
}
// A simple class that tries to instantiate a specialized dialog, like TestDialog
class SomeAppClass
{
public function new()
{
var instance = create(TestDialog);
}
#:generic
function create<T:Dialog>(type:Class<T>):T
{
return new T();
}
}
This doesn't work with the following error:
create.T does not have a constructor
Clearly, I'm doing something wrong, but what?
SpecialDialog could have a different constructor than Dialog.
So you have to constraint it and then also constraint to Dialog.
Code # Try Haxe
package;
typedef Constructible = {
public function new():Void;
}
// Dialog base class
// Every dialog in my application will derive from this
class Dialog
{
public function new()
{
trace("dialog");
}
}
class SuperDialog extends Dialog
{
public function new()
{
super();
trace("super dialog");
}
}
// A simple class that tries to instantiate a specialized dialog, like TestDialog
class SomeAppClass
{
public function new()
{
var dialog = create(Dialog);
var superDialog = create(SuperDialog);
}
#:generic
public static function create<T:(Constructible,Dialog)>(type:Class<T>):T
{
return new T();
}
}
class Test {
static public function main() {
new SomeAppClass();
}
}

Bind an Action to a property of a UserControl in XAML

I have a user control which has a button and a dependency property for the action the button is to execute. The page which contains the control sets the action in XAML.
MyUserControl.cs
A Button, and dependency property ButtonAction, of type Action. When the button is clicked it executes the ButtonAction.
MainPage.xaml.cs
Action Action1
Action Action2
MainPage.xaml
Present an instance of MyUserControl, with ButtonAction=Action1
The problem: The ButtonAction property is not assigned from the XAML
MyUserControl.cs
public sealed partial class MyUserControl : UserControl
{
public Action ButtonAction {
get { return (Action)GetValue(ButtonActionProperty); }
set { SetValue(ButtonActionProperty, value); }
}
public static readonly DependencyProperty ButtonActionProperty =
DependencyProperty.Register("ButtonAction", typeof(Action), typeof(MyUserControl), new PropertyMetadata(null,ButtonAction_PropertyChanged));
private static void ButtonAction_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
Debug.WriteLine("ButtonAction_PropertyChanged");
// Is not called!
}
public MyUserControl() {
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e) {
if (ButtonAction != null) {
// Never reaches here!
ButtonAction();
}
}
}
MyUserControl.xaml
<Grid>
<Button Click="Button_Click">Do The Attached Action!</Button>
</Grid>
MainPage.xaml.cs
Action Action1 = (
() => { Debug.WriteLine("Action1 called"); });
Action Action2 = (() => { Debug.WriteLine("Action2 called"); });
MainPage.xaml
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<local:MyUserControl x:Name="myUserControl" ButtonAction="{Binding Action1}"/>
</Grid>
It does work if in the code-behind for MainPage (MainPage.xaml.cs) I assign the action in the Loaded event.
private void Page_Loaded(object sender, RoutedEventArgs e) {
this.myUserControl.ButtonAction = Action1;
}
In this case the PropertyChanged callback in the user control is also called. (This handler is provided only for diagnostic purposes. I can't see how it can be used to support the property in practice).
The issue is in your data binding. The Action1 in ButtonAction="{Binding Action1}" should be a public property while you defined it as a private variable.
Also, you cannot just declare a normal property directly in the code behind like that. You will need either a dependency property, or more commonly, a public property inside a viewmodel which implements INotifyPropertyChanged.
If we go with the second approach, we will need to create a viewmodel class like the following with an Action1 property. Note the OnPropertyChanged stuff is just the standard way of implementing INotifyPropertyChanged.
public class ViewModel : INotifyPropertyChanged
{
private Action _action1;
public Action Action1
{
get { return _action1; }
set
{
_action1 = value;
OnPropertyChanged("Action1");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
And then you just need to assign this to the DataContext of your main page.
public MainPage()
{
this.InitializeComponent();
var vm = new ViewModel();
vm.Action1 = (() =>
{
Debug.WriteLine("Action1 called");
});
this.DataContext = vm;
}
With these two changes, your ButtonAction callback should be firing now. :)

How to Override Constants in ActionScript 3

I have the two following classes:
public class Parent{
static internal const _name:String = "Parent";
public function get name():String{
return _name;
}
}
public class Child{
static internal const _name:String = "Child";
}
If I create an instance of class Child and call its name() getter, since it will call the name() method it inherits from Parent, it returns "Parent". I could, of course, override the name() method:
public class Child{
static internal const _name:String = "Child";
override public function get name():String{
return _name;
}
}
That returns "Child". However, it seems silly to have to copy the exact same code of the method from the parent. Is there any simpler way to do this?
I would take a different approach by making the "name" property a requirement for the parent's constructor:
public class Parent
{
static internal var _name : String;
public function Parent(name : String = "Parent") {
_name = name;
}
public function get name() : String {
return _name;
}
}
Child Class:
public class Child extends Parent
{
public function Child() {
super("Child");
}
}
Firstly, you cannot override static methods or properties - they are not inherited, so no override for them.
Secondly, if you declared a constant to be of a complex type, it is not really a constant. I.e. if it is an object, then you can change its keys / values, if it is an array, you can add / remove members and so on.
But the desire to make this functionality more generic is understandable. So, what I'd do:
Have some property outside both parent and child, let say in class X, or package Y. Let it be package Y. So, you'd create a dictionary in package Y, let it be Y.names and in your name getter you'd do:
import Y.names;
. . .
public function get name() {
return names[(this as Object).constructor];
}
your names variable would be:
package Y {
public var names:Dictionary = generateNames();
internal function generateNames():Dictionary {
var result:Dictionary = new Dictionary();
result[ChildClass] = "child";
result[ParentClass] = "parent";
. . .
return result;
}
}
This way it would be sufficient to only implement name getter in super-class, and all inheriting classes will be able to use super-class code as is, no need to change anything. However, this means that some (maybe important) information pertaining to this class will be stored elsewhere (may be difficult to find, this is not the common way people program in AS3).
your implementation of get name should look like this, then the getter is one and each of the new classes needs to have it's own public static var _name defined:
//in the base class
public function get name():String
{
var _sName:String;
if ((this as Object).constructor._name)
{
_sName = (this as Object).constructor._name;
}
else
{
try
{
var o:Object = getSuperClass(this);
while (o)
{
if (o._name)
{
_sName = o._name;
break;
}
o = getSuperClass(o);
}
}
catch (e:*)
{}
}
return _sName;
}
//as found here: http://www.actionscriptdeveloper.co.uk/getting-the-class-of-an-object-in-as3/
public static function getSuperClass(o: Object): Object
{
var n: String = getQualifiedSuperclassName(o);
if (n == null)
return(null);
return getDefinitionByName(n);
}
the static members can be accessed only via class reference which we can get from constructor object, "this" will point to the current class in the inheritance chain so you can call this in parent class and it will point to a Child in a Child class.
[EDIT]
I've modified it so it tests for existance of the public static property _name if not found on "this" instance then in a loop the parent class is checked until one is found - like inheritance:)
I'm using this feature to create clone method: constructor as helper in clone method implementation
best regards
Why don't you store such a constant within a corresponding function instead of declaring an inaccessible constant?
class Parent {
...
public function get name():String { return 'Parent'; }
}
class Child extends Parent {
...
override public function get name():String { return 'Child'; }
}
By the way, if your Parent class is a descendant of DisplayObject, you should be careful with name property, as it's needed sometimes by operating code, e.g. getChildByName().
I have found something that seems to work. Any feedback is greatly appreciated:
public class Parent{
prototype._name = "Parent";
public function get name():String{
return this["_name"];
}
}
public class Child{
prototype._name = "Child";
}

How can I set "maxChars" of the TextInput in an editable ComboBox?

I want to set the maxChars property of the TextInput of an editable ComboBox. I am currently trimming the text to a set number of characters using a change Event:
private function nameOptionSelector_changeHandler(event:ListEvent):void
{
nameOptionSelector.text = nameOptionSelector.text.substr(0, MAX_LENGTH);
}
This feels like overkill. There's got to be a better way to do this....
My alternative is to use the protected textInput directly. This approach allows the "maxChars" property to be set in the GUI builder or code, just as you would for a normal TextField. Note that zero is a valid value for maxChars and indicates unlimited characters. The override of .childrenCreated() is needed to avoid attempting to set maxChars before the TextInput object exists.
package my.controls
{
import mx.controls.ComboBox;
public class EditableComboBox extends ComboBox
{
public function EditableComboBox()
{
super();
}
private var _maxChars:int = 0;
override protected function childrenCreated():void
{
super.childrenCreated();
// Now set the maxChars property on the textInput field.
textInput.maxChars = _maxChars;
}
public function set maxChars(value:int):void
{
_maxChars = value;
if (textInput != null && value >= 0)
textInput.maxChars = value;
}
public function get maxChars():int
{
return textInput.maxChars;
}
}
}
You could extend ComboBox and override the default maxChars value for the internal TextInput. If you need to set it dynamically, you could add a public method to set the property on the extended class.
Using the suggestion of Stiggler, here is the full solution I implemented:
package
{
import mx.controls.ComboBox;
public class ComboBoxWithMaxChars extends ComboBox
{
public function ComboBoxWithMaxChars()
{
super();
}
private var _maxCharsForTextInput:int;
public function set maxCharsForTextInput(value:int):void
{
_maxCharsForTextInput = value;
if (super.textInput != null && _maxCharsForTextInput > 0)
super.textInput.maxChars = _maxCharsForTextInput;
}
public function get maxCharsForTextInput():int
{
return _maxCharsForTextInput;
}
override public function itemToLabel(item:Object):String
{
var label:String = super.itemToLabel(item);
if (_maxCharsForTextInput > 0)
label = label.substr(0, _maxCharsForTextInput);
return label;
}
}
}