List with Border

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

List with Border

peaslee

Hi,

 

This code creates the list and fills it, but it does not show a border.

 

initializeWidgets

               

                transactionList := ListModel new.

                transactionList

                                items: #('one' 'two' 'three').

                transactionList borderWidth: 2; borderColor: Color red.

Reply | Threaded
Open this post in threaded view
|

Re: List with Border

Stephan Eggermont-3
On 12-04-16 18:09, Bruce Peaslee wrote:
> This code creates the list and fills it, but it does not show a border.

Hi Bruce. Indeed, if you look at MorphicListAdapter>buildWidget you'll
notice that it uses a PluggableListMorph that ignores border styling
and just asks the theme for

UITheme>listNormalBorderStyleFor: aList
     "Return the normal borderStyle for the given list"

     ^BorderStyle inset
         width: 1;
         baseColor: aList paneColor

You could subclass the theme you want to use and override
that method to look up exceptions, and register your list in
the exceptions list.

Not ideal, and should be fixed.

Stephan


Reply | Threaded
Open this post in threaded view
|

Re: List with Border

Rob Rothwell
On Tue, Apr 12, 2016 at 3:00 PM, Stephan Eggermont <[hidden email]> wrote:

Not ideal, and should be fixed.

Would you consider this a Priority 4 "Would be nice" like Issue 17743 and 17754? (I have been looking for things at my skill level I might actually be able to track down).

Rob

Reply | Threaded
Open this post in threaded view
|

Re: List with Border

Stephan Eggermont-3
On 12/04/16 21:58, Rob Rothwell wrote:
> Would you consider this a Priority 4 "Would be nice" like Issue 17743
> and 17754? (I have been looking for things at my skill level I might
> actually be able to track down).

All pluggable morphs behave badly with this. They all
are themed ignoring manual overrides. They are also used all over the
UI, so you'd probably need to work with subclasses to avoid
breaking the system. I think it should be a level 3/2 problem,
and is too large to be achievable before the release of Pharo 5.
It definitely is a more difficult problem than the one you fixed,
and is also a very annoying one, so would be very welcome to be fixed.

Stephan



Reply | Threaded
Open this post in threaded view
|

Re: List with Border

peaslee
Stephen,

I do not understand your answer. I am too new at this.
Reply | Threaded
Open this post in threaded view
|

Re: List with Border

Stephan Eggermont-3
On 14-04-16 16:53, peaslee wrote:
> I do not understand your answer. I am too new at this.
>
ListModel is a subclass of AbstractWidgetModel.
AbstractWidgetModel defines borderWidth: and borderColor:,
so one would expect all its subclasses to implement it.

The mapping in Spec from the model to the actual widget
is in MorphicListAdapter, that is a subclass of AbstractMorphicAdapter.

The implementation is
AbstractMorphicAdapter>borderColor: color

     self widget ifNotNil: [ :w | w borderColor: color ]

and
AbstractMorphicAdapter>borderWidth: width

     self widget ifNotNil: [ :w | w borderWidth: width ]

To find out how the widget is created, we need to take a look
at its superclass AbstractAdapter, which has

AbstractAdapter class >adapt: aComposableModel

     ^ self new
         adapt: aComposableModel;
         yourself

and on the instance side
AbstractAdapter>adapt: aComposableModel

     model := aComposableModel.
     aComposableModel addDependent: self.

     widget := self buildWidget.

buildWidget is then overridden for each concrete subclass
MorphicListAdapter>buildWidget

     ^ PluggableListMorph new
         model: self;
         getListSizeSelector: #listSize;
         autoDeselect: self autoDeselect;
         getIndexSelector: #getIndex;
         setIndexSelector: #setIndex:;
         getSelectionListSelector: #getSelectionStateFor:;
         setSelectionListSelector: #setSelectionStateFor:at:;
         backgroundColoringBlockOrSelector: #backgroundColorFor:at: ;
         getListElementSelector: #listElementAt: ;
         resetListSelector: #resetListSelection;
         getMenuSelector: #menu:shifted: ;
         setMultipleSelection: self multiSelection;
         wrapSelector: #wrapItem:index: ;
         setBalloonText: self help;
         dragEnabled: self dragEnabled;
         dropEnabled: self dropEnabled;
         hResizing: #spaceFill;
         vResizing: #spaceFill

So we see that the concrete widget is a PluggableListMorph.
That has a method borderStyleToUse which ignores values set to the
individual component:

PluggableListMorph>borderStyleToUse
     "Answer the borderStyle that should be used for the receiver."

     ^self enabled
         ifTrue: [self theme listNormalBorderStyleFor: self]
         ifFalse: [self theme listDisabledBorderStyleFor: self]

If you then look at the different implementors of borderStyleToUse,
you'll notice that there are a lot of them that only ask the theme for
a style.

Stephan




Reply | Threaded
Open this post in threaded view
|

Re: List with Border

stepharo
I wish we could remove this
     self widget ifNotNil:
but this is more complex than I would like.
stef


Le 14/4/16 21:10, Stephan Eggermont a écrit :

> On 14-04-16 16:53, peaslee wrote:
>> I do not understand your answer. I am too new at this.
>>
> ListModel is a subclass of AbstractWidgetModel.
> AbstractWidgetModel defines borderWidth: and borderColor:,
> so one would expect all its subclasses to implement it.
>
> The mapping in Spec from the model to the actual widget
> is in MorphicListAdapter, that is a subclass of AbstractMorphicAdapter.
>
> The implementation is
> AbstractMorphicAdapter>borderColor: color
>
>     self widget ifNotNil: [ :w | w borderColor: color ]
>
> and
> AbstractMorphicAdapter>borderWidth: width
>
>     self widget ifNotNil: [ :w | w borderWidth: width ]
>
> To find out how the widget is created, we need to take a look
> at its superclass AbstractAdapter, which has
>
> AbstractAdapter class >adapt: aComposableModel
>
>     ^ self new
>         adapt: aComposableModel;
>         yourself
>
> and on the instance side
> AbstractAdapter>adapt: aComposableModel
>
>     model := aComposableModel.
>     aComposableModel addDependent: self.
>
>     widget := self buildWidget.
>
> buildWidget is then overridden for each concrete subclass
> MorphicListAdapter>buildWidget
>
>     ^ PluggableListMorph new
>         model: self;
>         getListSizeSelector: #listSize;
>         autoDeselect: self autoDeselect;
>         getIndexSelector: #getIndex;
>         setIndexSelector: #setIndex:;
>         getSelectionListSelector: #getSelectionStateFor:;
>         setSelectionListSelector: #setSelectionStateFor:at:;
>         backgroundColoringBlockOrSelector: #backgroundColorFor:at: ;
>         getListElementSelector: #listElementAt: ;
>         resetListSelector: #resetListSelection;
>         getMenuSelector: #menu:shifted: ;
>         setMultipleSelection: self multiSelection;
>         wrapSelector: #wrapItem:index: ;
>         setBalloonText: self help;
>         dragEnabled: self dragEnabled;
>         dropEnabled: self dropEnabled;
>         hResizing: #spaceFill;
>         vResizing: #spaceFill
>
> So we see that the concrete widget is a PluggableListMorph.
> That has a method borderStyleToUse which ignores values set to the
> individual component:
>
> PluggableListMorph>borderStyleToUse
>     "Answer the borderStyle that should be used for the receiver."
>
>     ^self enabled
>         ifTrue: [self theme listNormalBorderStyleFor: self]
>         ifFalse: [self theme listDisabledBorderStyleFor: self]
>
> If you then look at the different implementors of borderStyleToUse,
> you'll notice that there are a lot of them that only ask the theme for
> a style.
>
> Stephan
>
>
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: List with Border

peaslee

> PluggableListMorph>borderStyleToUse
>     "Answer the borderStyle that should be used for the receiver."
>
>     ^self enabled
>         ifTrue: [self theme listNormalBorderStyleFor: self]
>         ifFalse: [self theme listDisabledBorderStyleFor: self]
>
> If you then look at the different implementors of borderStyleToUse,
> you'll notice that there are a lot of them that only ask the theme for
> a style.
>
Stephan


This last bit solved my problem for now. I had no luck with the subclass, etc., but I changed this method to dropListNormalBorderStyleFor:    That gives me a border. ;>)