Centering a Label with Spec
Hello, I started playing with Spec recently and I generally get good results out of its documentation and a couple of tutorials. However, yesterday I encountered a problem I didn't see mentioned anywhere. Let's say I have a window looking exactly like this one: http://www.bahmanm.com/images/greeter-version-1.png/image The "Hello, Bahman!" label is left-aligned. I'd like it to be centered horizontally. How do I do this? I tried inspecting a Button below - which has its label centered - and discovered AlignmentMorph, but didn't get the time to try to use it. And anyway, I shouldn't need to use Morphic for a thing like this, right? Best regards, Piotr Klibert
Hi Piotr, Iâm happy to learn that generally you get good results from the documentation and the tutorials. If there is anything missing in the documentation do not hesitate to inform using this mailing list. As for your layout question, laying out the different UI elements is (surprisingly) a complicated thing, which in my opinion can still be improved in Spec (although I have no concrete solution). I think that what you are asking for is not possible right now, unless you start using specific coordinates for the different UI elements. You can put all elements in the window at specific places (which may be percentages, offsets or absolute coordinates). For more info have a look at section 4 of the Spec book chapter (latest version at https://ci.inria.fr/pharo-contribution/view/Books/job/PharoBookWorkInProgres... ) Greetings,
On Jan 20, 2015, at 16:56, Piotr Klibert <piotr.klibert@10clouds.com> wrote:
Hello,
I started playing with Spec recently and I generally get good results out of its documentation and a couple of tutorials. However, yesterday I encountered a problem I didn't see mentioned anywhere.
Let's say I have a window looking exactly like this one: http://www.bahmanm.com/images/greeter-version-1.png/image
The "Hello, Bahman!" label is left-aligned. I'd like it to be centered horizontally. How do I do this?
I tried inspecting a Button below - which has its label centered - and discovered AlignmentMorph, but didn't get the time to try to use it. And anyway, I shouldn't need to use Morphic for a thing like this, right?
Best regards, Piotr Klibert
---> Save our in-boxes! http://emailcharter.org <--- Johan Fabry - http://pleiad.cl/~jfabry PLEIAD lab - Computer Science Department (DCC) - University of Chile
Ok, so I investigated a bit and it turns out it really is not possible with pure Spec (and no, absolute positioning is not an answer ;)) and that it is possible with a bit of fiddling with underlying morphs, LayoutFrames and LayoutPolicies. In the beginning I had this window: https://klibert.pl/statics/spec-layout1.png It was (almost) easy to make a single label centered: it turns out columns and rows in Spec set ProportionalLayout as a default layout policy (or maybe it's just the default everywhere) and centering a Morph inside another with this essentially boils down to sending it #hResizing: and #vResizing: messages with #shrinkWrap argument. I had to also make the LabelMorph narrower than the space it had available to trigger centering. So, after inspecting one LabelMorph and executing this code: self hResizing: #shrinkWrap. self width: self minWidth. my window looked like this: https://klibert.pl/statics/spec-layout2.png Now I needed to find a way of executing it for all the LabelMorphs. This was problematic, because they were all representing a single LabelModel and I couldn't get to all of them via label widget widget because this only returned the last LabelMorph. (There was also a little problem when I tried doing some of these things in #initializeWidgets when nothing was rendered yet, but I found #whenBuiltDo: on ComposableModel) I was going to traverse submorphs of a window to select all the LabelMorphs, but that would return also a label used in a title bar. While inspecting models I noticed that I could get to all the LabelMorphs via a "dependents" array on a LabelModel. Using it made me uncomfortable, because I have no idea how the dependency system works at all, but after adding this code self whenBuiltDo: [ (label dependents collect: #widget) do: [ :x | x hResizing: #shrinkWrap; width: x minWidth ] ] to the initializeWidgets method make my window looks like this: https://klibert.pl/statics/spec-layout3.png which is good enough for me. I think that there needs to be support for this case in Spec (actually, it would be good to also support right and left aligning of Morphs, not only centering them), but I have no idea yet where or how to start adding it. I'd be happy if someone could point me in the right direction :) Best regards, Piotr Klibert 2015-01-20 17:46 GMT+01:00 Johan Fabry <jfabry@dcc.uchile.cl>:
Hi Piotr,
Iâm happy to learn that generally you get good results from the documentation and the tutorials. If there is anything missing in the documentation do not hesitate to inform using this mailing list.
As for your layout question, laying out the different UI elements is (surprisingly) a complicated thing, which in my opinion can still be improved in Spec (although I have no concrete solution). I think that what you are asking for is not possible right now, unless you start using specific coordinates for the different UI elements. You can put all elements in the window at specific places (which may be percentages, offsets or absolute coordinates).
For more info have a look at section 4 of the Spec book chapter (latest version at https://ci.inria.fr/pharo-contribution/view/Books/job/PharoBookWorkInProgres... )
Greetings,
On Jan 20, 2015, at 16:56, Piotr Klibert <piotr.klibert@10clouds.com> wrote:
Hello,
I started playing with Spec recently and I generally get good results out of its documentation and a couple of tutorials. However, yesterday I encountered a problem I didn't see mentioned anywhere.
Let's say I have a window looking exactly like this one: http://www.bahmanm.com/images/greeter-version-1.png/image
The "Hello, Bahman!" label is left-aligned. I'd like it to be centered horizontally. How do I do this?
I tried inspecting a Button below - which has its label centered - and discovered AlignmentMorph, but didn't get the time to try to use it. And anyway, I shouldn't need to use Morphic for a thing like this, right?
Best regards, Piotr Klibert
---> Save our in-boxes! http://emailcharter.org <---
Johan Fabry - http://pleiad.cl/~jfabry PLEIAD lab - Computer Science Department (DCC) - University of Chile
This is really great that you found a solution. It will be helpful for me and I think for others tool. Thanks a lot 2015-01-21 22:47 GMT+01:00 Piotr Klibert <piotr.klibert@10clouds.com>:
Ok, so I investigated a bit and it turns out it really is not possible with pure Spec (and no, absolute positioning is not an answer ;)) and that it is possible with a bit of fiddling with underlying morphs, LayoutFrames and LayoutPolicies.
In the beginning I had this window:
https://klibert.pl/statics/spec-layout1.png
It was (almost) easy to make a single label centered: it turns out columns and rows in Spec set ProportionalLayout as a default layout policy (or maybe it's just the default everywhere) and centering a Morph inside another with this essentially boils down to sending it #hResizing: and #vResizing: messages with #shrinkWrap argument. I had to also make the LabelMorph narrower than the space it had available to trigger centering.
So, after inspecting one LabelMorph and executing this code:
self hResizing: #shrinkWrap. self width: self minWidth.
my window looked like this:
https://klibert.pl/statics/spec-layout2.png
Now I needed to find a way of executing it for all the LabelMorphs. This was problematic, because they were all representing a single LabelModel and I couldn't get to all of them via
label widget widget
because this only returned the last LabelMorph.
(There was also a little problem when I tried doing some of these things in #initializeWidgets when nothing was rendered yet, but I found #whenBuiltDo: on ComposableModel)
I was going to traverse submorphs of a window to select all the LabelMorphs, but that would return also a label used in a title bar. While inspecting models I noticed that I could get to all the LabelMorphs via a "dependents" array on a LabelModel. Using it made me uncomfortable, because I have no idea how the dependency system works at all, but after adding this code
self whenBuiltDo: [ (label dependents collect: #widget) do: [ :x | x hResizing: #shrinkWrap; width: x minWidth ] ]
to the initializeWidgets method make my window looks like this:
https://klibert.pl/statics/spec-layout3.png
which is good enough for me.
I think that there needs to be support for this case in Spec (actually, it would be good to also support right and left aligning of Morphs, not only centering them), but I have no idea yet where or how to start adding it. I'd be happy if someone could point me in the right direction :)
Best regards, Piotr Klibert
2015-01-20 17:46 GMT+01:00 Johan Fabry <jfabry@dcc.uchile.cl>:
Hi Piotr,
Iâm happy to learn that generally you get good results from the documentation and the tutorials. If there is anything missing in the documentation do not hesitate to inform using this mailing list.
As for your layout question, laying out the different UI elements is (surprisingly) a complicated thing, which in my opinion can still be improved in Spec (although I have no concrete solution). I think that what you are asking for is not possible right now, unless you start using specific coordinates for the different UI elements. You can put all elements in the window at specific places (which may be percentages, offsets or absolute coordinates).
For more info have a look at section 4 of the Spec book chapter (latest version at https://ci.inria.fr/pharo-contribution/view/Books/job/PharoBookWorkInProgres... )
Greetings,
On Jan 20, 2015, at 16:56, Piotr Klibert <piotr.klibert@10clouds.com> wrote:
Hello,
I started playing with Spec recently and I generally get good results out of its documentation and a couple of tutorials. However, yesterday I encountered a problem I didn't see mentioned anywhere.
Let's say I have a window looking exactly like this one: http://www.bahmanm.com/images/greeter-version-1.png/image
The "Hello, Bahman!" label is left-aligned. I'd like it to be centered horizontally. How do I do this?
I tried inspecting a Button below - which has its label centered - and discovered AlignmentMorph, but didn't get the time to try to use it. And anyway, I shouldn't need to use Morphic for a thing like this, right?
Best regards, Piotr Klibert
---> Save our in-boxes! http://emailcharter.org <---
Johan Fabry - http://pleiad.cl/~jfabry PLEIAD lab - Computer Science Department (DCC) - University of Chile
Hi Piotr, like you already found out, you can use whenBuiltDo: But instead of using #hResizing: , which is not explicit in specs api you can call the method hShrinkWrap (look in AbstractMorphicAdapter, protocol 'protocol'). Here is a small example with centering a label: | ui layout | ui := DynamicComposableModel new. ui title: 'hello'. ui instantiateModels: #( label LabelModel check CheckBoxModel text TextInputFieldModel button ButtonModel ). ui label text:'Hello World'. ui label whenBuiltDo:[: widget |widget widget hShrinkWrap.]. layout := SpecLayout composed newRow: [ :r | r add: #label] height: 25; yourself. ui openWithSpecLayout: layout. the block arguemt for whenBuiltDo: is a WidgetBuilt announcement, that gives you access to the model and the widget (-adapter) that is used. nicolai
participants (4)
-
Johan Fabry -
Mark Rizun -
Nicolai Hess -
Piotr Klibert