csharp: Add bindable factory parts support

Summary:
This commit makes parts that implement `Efl.IContent` use BindFactory
instead of property binding.

```
var factory = new Efl.Ui.ItemFactory<Efl.Ui.ListDefaultItem>();
var iconFactory = new Efl.Ui.ImageFactory(null);
iconFactory.PropertyBind("filename", "modelProperty");
factory.IconPart().BindFactory(iconFactory);
```

Fixes T7628

Reviewers: cedric, felipealmeida, SanghyeonLee

Reviewed By: felipealmeida

Tags: #efl

Maniphest Tasks: T7628

Differential Revision: https://phab.enlightenment.org/D9653
This commit is contained in:
Lauro Moura 2019-08-23 14:12:08 -03:00 committed by Felipe Magno de Almeida
parent 1aa05ab41b
commit f3d9238e15
4 changed files with 46 additions and 3 deletions

View File

@ -263,7 +263,8 @@ struct property_extension_method_definition_generator
}
// Do we need BindablePart extensions for this class?
if (!helpers::inherits_from(cls, "Efl.Ui.LayoutPart"))
// IContent parts are handled directly through BindableFactoryParts
if (!helpers::inherits_from(cls, "Efl.Ui.LayoutPart") || helpers::inherits_from(cls, "Efl.IContent"))
return true;
if (property.setter.is_engaged())

View File

@ -47,12 +47,19 @@ struct part_extension_method_definition_generator
/* auto unit = (const Eolian_Unit*) context_find_tag<eolian_state_context>(context).state; */
/* auto klass = get_klass(part.klass, unit); */
std::string bindableClass = "Efl.BindablePart";
// Efl.Content parts should be bound only throught FactoryBind
attributes::klass_def c(get_klass(part.klass, cls.unit), cls.unit);
if (helpers::inherits_from(c, "Efl.IContent"))
bindableClass = "Efl.BindableFactoryPart";
if (!as_generator(
scope_tab << "public static Efl.BindablePart<" << part_klass_name << "> " << name_helpers::managed_part_name(part) << "<T>(this Efl.Ui.ItemFactory<T> fac, Efl.Csharp.ExtensionTag<"
scope_tab << "public static " << bindableClass << "<" << part_klass_name << "> " << name_helpers::managed_part_name(part) << "<T>(this Efl.Ui.ItemFactory<T> fac, Efl.Csharp.ExtensionTag<"
<< name_helpers::klass_full_concrete_or_interface_name(cls)
<< ", T> x=null) where T : " << name_helpers::klass_full_concrete_or_interface_name(cls) << "\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "return new Efl.BindablePart<" << part_klass_name << ">(\"" << part.name << "\" ,fac);\n"
<< scope_tab << scope_tab << "return new " << bindableClass << "<" << part_klass_name << ">(\"" << part.name << "\" ,fac);\n"
<< scope_tab << "}\n"
).generate(sink, attributes::unused, context))
return false;

View File

@ -82,6 +82,31 @@ public class BindablePart<T>
public string PartName { get; private set; }
/// <summary>The binder that will be used to bind the properties.</summary>
public Efl.Ui.IPropertyBind Binder { get; private set; }
}
/// <summary>Represents bindable factory parts as used by <see cref="Efl.Ui.ItemFactory&lt;T&gt;" /> instances.
/// </summary>
public class BindableFactoryPart<T>
{
/// <summary>Creates a new bindable factory part with the binder <c>binder</c>.</summary>
public BindableFactoryPart(string partName, Efl.Ui.IFactoryBind binder)
{
this.PartName = partName;
this.Binder = binder;
}
/// <summary>The name of the part this instance wraps.</summary>
public string PartName { get; private set; }
/// <summary>The binder that will be used to bind the properties.</summary>
public Efl.Ui.IFactoryBind Binder { get; private set; }
/// <summary>Binds the given factory to this part.</summary>
public Eina.Error BindFactory(Efl.Ui.IFactory factory)
{
this.Binder.FactoryBind(this.PartName, factory);
return Eina.Error.NO_ERROR;
}
}
namespace Csharp

View File

@ -50,6 +50,16 @@ public static class TestMVVMParts
Test.AssertEquals(error, Eina.Error.NO_ERROR);
}
public static void mvvm_factory_properties()
{
var factory = new Efl.Ui.ItemFactory<Efl.Ui.ListDefaultItem>();
var iconFactory = new Efl.Ui.ImageFactory(null);
iconFactory.PropertyBind("filename", "modelProperty");
var error = factory.IconPart().BindFactory(iconFactory);
Test.AssertEquals(error, Eina.Error.NO_ERROR);
}
}
#endif