You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@flex.apache.org by Mark Kessler <ke...@gmail.com> on 2013/04/27 04:00:26 UTC

[Example] Enable/Disable buttonbar buttons

Adding in a convenience feature to enable / disable buttons on
buttonbar/tabbars.

Example [1] with view source enabled.
Git hub diffs [2].




[1] http://people.apache.org/~mkessler/examples/FLEX-33524/app.swf
[2]
https://github.com/KesslerConsulting/example/commit/83905cb1a8f80bb6ac156b3d4bc6fed2a00227c2


-Mark

Re: [Example] Enable/Disable buttonbar buttons

Posted by Justin Mclean <ju...@classsoftware.com>.
Hi,

> That does affect the current Single based method, but the array fed one
> will grab duplicates too.

JFYI there's are number of unresolved JIRA issue re duplicates in array collections, data providers and the like. ie generally duplicate objects are a bad idea.

Justin

Re: [Example] Enable/Disable buttonbar buttons

Posted by Mark Kessler <ke...@gmail.com>.
Always open to discussions.


Inline comments...


*> Thanks for looking into various approaches.  What are the scenarios that
> make having an API that requires searching the dataprovider, better than
an
> array that parallels the dataprovider, better than requiring a field on
the
> dataprovider like we do for mx:Menu [1] (see "enabled" property).
*
Well what I envisioned for these convenience methods was to be able to
change certain properties of the buttons directly and adhoc.  Currently in
the example we have a method addressing single buttons and an array fed one
that grab all matching the array.  The reason I didn't have an array
parallel to the dataProvider was it felt like your Option 3 was a better
option for it.  Meaning rather than hosting a separate array of enables
states, just use the dataProvider and have more fields in it.

I had already planned on making a feature to use the dataProvider contain
certain properties (enabled, toolTip, visible, buttongroupings, etc).
Watching for changes to the dataProvider to update the child objects. But I
try to only show small amounts of additions at once.  Was hoping to make it
faster to digest and process them than without having large delays.  But I
do plan on showing the new features for discussion purposes.


*> I honestly don't have an opinion, I just wanted to point out a third
> possibility that has been done before.  Also, instead of providing more
than
> one way, it might be best to settle one one.  One disadvantage to
providing
> multiple was of doing something is that you then have to implement and
order
> of precedence (If I use both APIs, which one overrides the other).*

Well the methods that are in the example now, don't conflict, but adding
that third option would modify take a little consideration.


*> 1) in the MX days, we "disallowed" duplicate entries in the dataprovider.
> In Spark, we do not, so there is a theoretical chance that a label can be
in
> there twice (practically, I can't really think of why anybody would do
that)
> so you have to decide whether to cover such a case or not.*

That does affect the current Single based method, but the array fed one
will grab duplicates too.


*> 2) In a buttonbar of just icons (audio/video playback controls or
something
> like that) can you assume there are distinct labels to search for?*

No. it wouldn't match much without labels.  I could do what I did for the
other features, just pass a field it should use for the search match.  This
will allow a custom field in the dataProvider that would give same
functionality but not pass labels to the buttons themselves.



Thanks for your feedback Alex.  It has good constructive thoughts.


-Mark


On Sun, Apr 28, 2013 at 1:18 AM, Alex Harui <ah...@adobe.com> wrote:

> Hi Mark,
>
> Thanks for looking into various approaches.  What are the scenarios that
> make having an API that requires searching the dataprovider, better than an
> array that parallels the dataprovider, better than requiring a field on the
> dataprovider like we do for mx:Menu [1] (see "enabled" property).
>
> I honestly don't have an opinion, I just wanted to point out a third
> possibility that has been done before.  Also, instead of providing more
> than
> one way, it might be best to settle one one.  One disadvantage to providing
> multiple was of doing something is that you then have to implement and
> order
> of precedence (If I use both APIs, which one overrides the other).
>
> Couple of other things to consider (and again, I don't have an opinion here
> either):
>
> 1) in the MX days, we "disallowed" duplicate entries in the dataprovider.
> In Spark, we do not, so there is a theoretical chance that a label can be
> in
> there twice (practically, I can't really think of why anybody would do
> that)
> so you have to decide whether to cover such a case or not.
>
> 2) In a buttonbar of just icons (audio/video playback controls or something
> like that) can you assume there are distinct labels to search for?
>
>
> [1]
>
> http://help.adobe.com/en_US/FlashPlatform//reference/actionscript/3/mx/contr
> ols/Menu.html
>
>
>
>

Re: [Example] Enable/Disable buttonbar buttons

Posted by Mark Kessler <ke...@gmail.com>.
Max,
   Inline comments...


> I guess my main argument in favour of the array attribute was the
convenience of being able to enable/disable buttons purely through MXML +
data binding.

I seem to understand you better now.  These features I'm working on are for
AS ATM.  But I'm not against adding some mxml+data binding functionality in
addition too.



> But I have other arguments ;)  I'm not sure why having another
"dataProvider" would be inconvenient. The `selectedItems` property for
instance is an example of an existing attribute that serves a similar
purpose (it selects/deselects items in a List). > It would make sense to me
as a developer that similar functionality would be exposed through a
similar, consistent API; in this case e.g. a `disabledItems` attribute
which would enable/disable items in the List.
> I say List (not ButtonBar) because I think it would make sense to expose
this feature at that level, rather than for ButtonBar only, so that all
subclasses of List can reap the benefits.

The selectedItems is the same the selectedIndexes for the most part, it
doesn't actually keep the selecteItems, it translates them into a new
Vector<int> to store the selectedIndexes.  So that means you would like a
getter/setter to access an array of indexes for enabled/disabled buttons.
It's doable, but will have to be done separately from this current
features.  It's a bit more of an effort to have an additional
vector.<int>.  It will need to update with any change to the dataProvider
(add/remove/reset/refresh).


We could move someone functionality up to Listbase, but I'm not sure what
benefit that would have overall since only the ButtonBar / TabBar seem to
change properties on a per item bases.  Although let me know if you find an
example for it.

ButtonBar
ComboBox
DropDownList
List
SpinnerList
TabBar



> Alex' suggestion of an mx:Menu-like API makes sense too. That's actually
how I work around the issue at the moment. But it has the inconvenience of
being less discoverable: you /have /to read the docs to now about it. I
tend to discover a component's API by letting my IDE suggest attributes or
methods (e.g. I start typing "dis" to see if there's something I can use to
disable items and the IDE will tell me there's an attribute called
`disabledItems` that does the job).
> Also this aproach makes more sense for components that will usually have
a more static model (Menus, ButtonBars and the like), but less so for those
that usually have a more dynamic model (List, DropDownList, ComboBox,
etc.): you'd have to > add presentational properties to your value objects
or wrap them all in presentation model objects. So if you want to expose
this feature for all List-based components, I'm not entirely sure that's
the best solution. Besides, not all Menus have a static model and not all
Lists have a dynamic model.

I was planning on trying to address this with having it watch the
dataProvider for changes to additional properties (enabled, tooltip,
visible). This would probably the place to squeeze in a disabledItems
styled getter/setter property.


-Mark



On Tue, Apr 30, 2013 at 4:23 PM, RIAstar <ma...@riastar.net> wrote:

> Sorry for the delay.
> I guess my main argument in favour of the array attribute was the
> convenience of being able to enable/disable buttons purely through MXML +
> data binding.
>
> But I have other arguments ;)  I'm not sure why having another
> "dataProvider" would be inconvenient. The `selectedItems` property for
> instance is an example of an existing attribute that serves a similar
> purpose (it selects/deselects items in a List). It would make sense to me
> as a developer that similar functionality would be exposed through a
> similar, consistent API; in this case e.g. a `disabledItems` attribute
> which would enable/disable items in the List.
> I say List (not ButtonBar) because I think it would make sense to expose
> this feature at that level, rather than for ButtonBar only, so that all
> subclasses of List can reap the benefits.
>
> Alex' suggestion of an mx:Menu-like API makes sense too. That's actually
> how I work around the issue at the moment. But it has the inconvenience of
> being less discoverable: you /have /to read the docs to now about it. I
> tend to discover a component's API by letting my IDE suggest attributes or
> methods (e.g. I start typing "dis" to see if there's something I can use to
> disable items and the IDE will tell me there's an attribute called
> `disabledItems` that does the job).
> Also this aproach makes more sense for components that will usually have a
> more static model (Menus, ButtonBars and the like), but less so for those
> that usually have a more dynamic model (List, DropDownList, ComboBox,
> etc.): you'd have to add presentational properties to your value objects or
> wrap them all in presentation model objects. So if you want to expose this
> feature for all List-based components, I'm not entirely sure that's the
> best solution. Besides, not all Menus have a static model and not all Lists
> have a dynamic model.
>
> Those were my thougts ;)
> Max
>

Re: [Example] Enable/Disable buttonbar buttons

Posted by RIAstar <ma...@riastar.net>.
Sorry for the delay.
I guess my main argument in favour of the array attribute was the 
convenience of being able to enable/disable buttons purely through MXML 
+ data binding.

But I have other arguments ;)  I'm not sure why having another 
"dataProvider" would be inconvenient. The `selectedItems` property for 
instance is an example of an existing attribute that serves a similar 
purpose (it selects/deselects items in a List). It would make sense to 
me as a developer that similar functionality would be exposed through a 
similar, consistent API; in this case e.g. a `disabledItems` attribute 
which would enable/disable items in the List.
I say List (not ButtonBar) because I think it would make sense to expose 
this feature at that level, rather than for ButtonBar only, so that all 
subclasses of List can reap the benefits.

Alex' suggestion of an mx:Menu-like API makes sense too. That's actually 
how I work around the issue at the moment. But it has the inconvenience 
of being less discoverable: you /have /to read the docs to now about it. 
I tend to discover a component's API by letting my IDE suggest 
attributes or methods (e.g. I start typing "dis" to see if there's 
something I can use to disable items and the IDE will tell me there's an 
attribute called `disabledItems` that does the job).
Also this aproach makes more sense for components that will usually have 
a more static model (Menus, ButtonBars and the like), but less so for 
those that usually have a more dynamic model (List, DropDownList, 
ComboBox, etc.): you'd have to add presentational properties to your 
value objects or wrap them all in presentation model objects. So if you 
want to expose this feature for all List-based components, I'm not 
entirely sure that's the best solution. Besides, not all Menus have a 
static model and not all Lists have a dynamic model.

Those were my thougts ;)
Max

Re: [Example] Enable/Disable buttonbar buttons

Posted by Mark Kessler <ke...@gmail.com>.
Ok Max, I've created two new methods to enable/disable based on an array.
I've rehosted the example in the same spot [1].  I will prob get around to
renaming the methods tomorrow morning... they were just tossed on for now.

Not sure the getter/setter hosting an array of disable buttons.  Then we
have two dataproviders of button data.


[1] http://people.apache.org/~mkessler/examples/FLEX-33524/app.swf

-Mark



On Sat, Apr 27, 2013 at 8:19 AM, Mark Kessler
<ke...@gmail.com>wrote:

> Well I definitely want to keep the single ones, but I can add an array
> based ones too.  I'll put together an a new base method and then add the
> two array based enable/disable methods later on tonight.  We can go over
> the array ones then.
>
>
>
> On Sat, Apr 27, 2013 at 3:29 AM, RIAstar <ma...@riastar.net> wrote:
>
>> Hi Mark,
>>
>> Interesting idea. I was thinking: wouldn't it be more convenient to let
>> all that happen through one property of type Array?
>> Lets' call it `disabledButtons:Array`; it would disable the items in the
>> Array en enable those not in the Array.
>>
>> That way this code from your test app
>>
>>             if (dgTestData.isFirstRow == true)
>>             {
>>                 bbTest.buttonDisable("First");
>>                 bbTest.buttonDisable("**Previous");
>>             }
>>             else
>>             {
>>                 bbTest.buttonEnable("First");
>>                 bbTest.buttonEnable("Previous"**);
>>             }
>>
>> would become
>>
>>             if (dgTestData.isFirstRow == true)
>>                 bbTest.disabledButtons = ["First", "Previous"];
>>
>> and as another plus, you could use binding on that property through MXML.
>> Something like:
>>
>>             <s:ButtonBar disabledButtons="{**disabledButtonsArray}"/>
>>
>> What do you think?
>> Max
>>
>
>

Re: [Example] Enable/Disable buttonbar buttons

Posted by Alex Harui <ah...@adobe.com>.
Hi Mark,

Thanks for looking into various approaches.  What are the scenarios that
make having an API that requires searching the dataprovider, better than an
array that parallels the dataprovider, better than requiring a field on the
dataprovider like we do for mx:Menu [1] (see "enabled" property).

I honestly don't have an opinion, I just wanted to point out a third
possibility that has been done before.  Also, instead of providing more than
one way, it might be best to settle one one.  One disadvantage to providing
multiple was of doing something is that you then have to implement and order
of precedence (If I use both APIs, which one overrides the other).

Couple of other things to consider (and again, I don't have an opinion here
either):  

1) in the MX days, we "disallowed" duplicate entries in the dataprovider.
In Spark, we do not, so there is a theoretical chance that a label can be in
there twice (practically, I can't really think of why anybody would do that)
so you have to decide whether to cover such a case or not.

2) In a buttonbar of just icons (audio/video playback controls or something
like that) can you assume there are distinct labels to search for?


[1] 
http://help.adobe.com/en_US/FlashPlatform//reference/actionscript/3/mx/contr
ols/Menu.html


On 4/27/13 5:19 AM, "Mark Kessler" <ke...@gmail.com> wrote:

> Well I definitely want to keep the single ones, but I can add an array
> based ones too.  I'll put together an a new base method and then add the
> two array based enable/disable methods later on tonight.  We can go over
> the array ones then.
> 
> 
> 
> On Sat, Apr 27, 2013 at 3:29 AM, RIAstar <ma...@riastar.net> wrote:
> 
>> Hi Mark,
>> 
>> Interesting idea. I was thinking: wouldn't it be more convenient to let
>> all that happen through one property of type Array?
>> Lets' call it `disabledButtons:Array`; it would disable the items in the
>> Array en enable those not in the Array.
>> 
>> That way this code from your test app
>> 
>>             if (dgTestData.isFirstRow == true)
>>             {
>>                 bbTest.buttonDisable("First");
>>                 bbTest.buttonDisable("**Previous");
>>             }
>>             else
>>             {
>>                 bbTest.buttonEnable("First");
>>                 bbTest.buttonEnable("Previous"**);
>>             }
>> 
>> would become
>> 
>>             if (dgTestData.isFirstRow == true)
>>                 bbTest.disabledButtons = ["First", "Previous"];
>> 
>> and as another plus, you could use binding on that property through MXML.
>> Something like:
>> 
>>             <s:ButtonBar disabledButtons="{**disabledButtonsArray}"/>
>> 
>> What do you think?
>> Max
>> 

-- 
Alex Harui
Flex SDK Team
Adobe Systems, Inc.
http://blogs.adobe.com/aharui


Re: [Example] Enable/Disable buttonbar buttons

Posted by Mark Kessler <ke...@gmail.com>.
Well I definitely want to keep the single ones, but I can add an array
based ones too.  I'll put together an a new base method and then add the
two array based enable/disable methods later on tonight.  We can go over
the array ones then.



On Sat, Apr 27, 2013 at 3:29 AM, RIAstar <ma...@riastar.net> wrote:

> Hi Mark,
>
> Interesting idea. I was thinking: wouldn't it be more convenient to let
> all that happen through one property of type Array?
> Lets' call it `disabledButtons:Array`; it would disable the items in the
> Array en enable those not in the Array.
>
> That way this code from your test app
>
>             if (dgTestData.isFirstRow == true)
>             {
>                 bbTest.buttonDisable("First");
>                 bbTest.buttonDisable("**Previous");
>             }
>             else
>             {
>                 bbTest.buttonEnable("First");
>                 bbTest.buttonEnable("Previous"**);
>             }
>
> would become
>
>             if (dgTestData.isFirstRow == true)
>                 bbTest.disabledButtons = ["First", "Previous"];
>
> and as another plus, you could use binding on that property through MXML.
> Something like:
>
>             <s:ButtonBar disabledButtons="{**disabledButtonsArray}"/>
>
> What do you think?
> Max
>

Re: [Example] Enable/Disable buttonbar buttons

Posted by RIAstar <ma...@riastar.net>.
Hi Mark,

Interesting idea. I was thinking: wouldn't it be more convenient to let 
all that happen through one property of type Array?
Lets' call it `disabledButtons:Array`; it would disable the items in the 
Array en enable those not in the Array.

That way this code from your test app

             if (dgTestData.isFirstRow == true)
             {
                 bbTest.buttonDisable("First");
                 bbTest.buttonDisable("Previous");
             }
             else
             {
                 bbTest.buttonEnable("First");
                 bbTest.buttonEnable("Previous");
             }

would become

             if (dgTestData.isFirstRow == true)
                 bbTest.disabledButtons = ["First", "Previous"];

and as another plus, you could use binding on that property through 
MXML. Something like:

             <s:ButtonBar disabledButtons="{disabledButtonsArray}"/>

What do you think?
Max