Since my first attempts at using MUI, I've been having very UNsatisfactory results trying to just display a block of text. I've tried TextObject, FloattextObject & even TextEditorObject in read-only mode, but none of them work very well.
At Deniil's suggestion I've recently tried a List(view)Object. This involved a lot more effort than the other objects (.e.g. I had to manually parse a string into individual lines), but has given a *slightly* better end-result.
If there is anyone here with experience, then I will detail exactly what I am trying to achieve, and what results I am actually seeing with those Objects.
It would definitely help if you could explain a bit more detailed how you expect the text to look like. In how far does a simple text object not suite your needs?
(N)Floattext already does exactly the same as you did using the list. It splits a long text into separate lines, inserts some spaces to produce an aligned text and displays them.
The TextEditor class in read-only does more or less the same like Floattext, but with the ability to apply different styles and coloring apart from the standard MUI text engine. Furthermore it allows to let the user edit the text in read-write mode. YAM makes heavy use of it in both modes to show and edit the mails.
MUI definitely is no crap, otherwise other systems wouldn't have chosen it as their fundamental GUI system/framework.
@tboeckel Thanks for your interest. I want a "text box" which is automatically large enough to display it's FULL initial contents... but which I can subsequently update with more lines (that can be read using a scroll bar). BTW, the behaviour below was from tests inside a Group_PageMode, but I recall (probably) similar behaviour without that.
If I use a TextObject, then it has the FULL initial size... but if I append extra lines then these are not visible (although a bug causes it to write outside of itself!). The only way to get it to enlarge for the new text is to iconise & then uniconise the MUI window. Also, the text is not word-wrapped.
If I use FloattextObject or TextEditorObject, then no matter the initial contents, the initial size is always 3 lines of text (which is the minimum space needed by the scrollbar + arrows), but it is at least vertically scrollable. Also, the text is word-wrapped.
If I use a List(view)Object, then there are two cases:
1. If I leave "MUIA_List_AdjustHeight" at it's default (FALSE), then the list only gets 3 lines (for the scrollbar & arrows), whatever the initial content. As a bonus the window can be vertically resized, and the list auto-adjusts to show more contents in the available space.
2. If I set it to TRUE, then it does get the full initial contents height BUT IT IS STILL SCROLLABLE when larger content is added. This SOUNDS like exactly what I wanted, but there is a catch! The list now has a FIXED height, which (in general) means that the window also has a fixed height. So IF the initial contents is empty, then the initial height will be 3 lines (even if the window has room to spare), and the window cannot be made any taller.
BTW, a side-effect of using List(view)Object is that the text is not word-wrapped (since I don't know where it should be wrapped!). But I actually consider this preferable (although being able to word-wrap might be handy).
If I use a TextObject, then it has the FULL initial size... but if I append extra lines then these are not visible (although a bug causes it to write outside of itself!). The only way to get it to enlarge for the new text is to iconise & then uniconise the MUI window. Also, the text is not word-wrapped.
You must not modify the text as long as it is "in use" by the object. MUI will calculate the required dimensions on basis of the given text and expects it to be constant. If you really need to change the text, then you must set() it again after the modification. This will let MUI do a relayout to display all of the new text.
But this will work to a certain extend only, namely when the complete text's height becomes larger than the window's maximum height. If you need to display larger texts, then the object should be placed into a Scrollgroup object like this:
ScrollgroupObject,
MUIA_Scrollgroup_AutoBars, TRUE,
MUIA_Scrollgroup_Contents, VGroupV,
Child, TextObject,
MUIA_Text_Contents, "insert your text here",
MUIA_Text_Copy, TRUE,
End,
End,
End,
The attribute MUIA_Scrollgroup_AutoBars will let the scrollgroup show the scrollbars only if they are really needed, i.e. the contents' dimensions are larger than the scrollgroup's dimensions. This attribute is available in MUI4 only, MUI3 will silently ignore it and always show the scrollbars.
Second, the attribute MUIA_Text_Copy instructs Text.mui to keep a copy of your text. This makes it possible to free() the text given to MUIA_Text_Contents after object creation of after set() and it also allows you to modify the text without risking any graphical glitches due to redraw operations while the text is still modified.
However, your text will always be displayed exactly as you specify it. This means that you need to insert line breaks yourself.
Quote:
If I use FloattextObject or TextEditorObject, then no matter the initial contents, the initial size is always 3 lines of text (which is the minimum space needed by the scrollbar + arrows), but it is at least vertically scrollable. Also, the text is word-wrapped.
Since Floattext.mui inserts line breaks itself you cannot expect a variable height, because the text's height depends on the object's width. You can enforce a certain object height by using something like MUIA_FixHeightTxt, "\n\n\n\n". This will give you a fixed height of 4 lines while respecting the object's font.
Quote:
If I use a List(view)Object, then there are two cases:
1. If I leave "MUIA_List_AdjustHeight" at it's default (FALSE), then the list only gets 3 lines (for the scrollbar & arrows), whatever the initial content. As a bonus the window can be vertically resized, and the list auto-adjusts to show more contents in the available space.
2. If I set it to TRUE, then it does get the full initial contents height BUT IT IS STILL SCROLLABLE when larger content is added. This SOUNDS like exactly what I wanted, but there is a catch! The list now has a FIXED height, which (in general) means that the window also has a fixed height. So IF the initial contents is empty, then the initial height will be 3 lines (even if the window has room to spare), and the window cannot be made any taller.
Read the Autodocs and you will notice that this is a documented behaviour.
Quote:
BTW, a side-effect of using List(view)Object is that the text is not word-wrapped (since I don't know where it should be wrapped!). But I actually consider this preferable (although being able to word-wrap might be handy).
Of course the text is not wrapped. This is what Floattext.mui is meant for. Normal lists may contain lines of arbitrary length and even more than one column.
(TextObject) If you really need to change the text, then you must set() it again after the modification.
That is what I *am* doing! Why did you think I wasn't?
I'll give your ScrollgroupObject suggestion a try, but I would have thought I'd have tried something similar before (without success)...
Quote:
Quote:
If I use FloattextObject or TextEditorObject, then no matter the initial contents, the initial size is always 3 lines of text (which is the minimum space needed by the scrollbar + arrows), but it is at least vertically scrollable. Also, the text is word-wrapped.
Since Floattext.mui inserts line breaks itself you cannot expect a variable height, because the text's height depends on the object's width. You can enforce a certain object height by using something like MUIA_FixHeightTxt, "\n\n\n\n". This will give you a fixed height of 4 lines while respecting the object's font.
Perhaps I misunderstand your reply, but it doesn't seem relevant to what I said: I want FloattextObject to show the entire *initial* contents, but it only shows 3 lines (no matter how large the window starts out). If this is the intended behaviour, it seems kind of useless!
Your suggestion of MUIA_FixHeightTxt doesn't seem like it will get me what I want, since the height will still be fixed.
Quote:
(ListObject) Read the Autodocs and you will notice that this is a documented behaviour.
Did I ever say it was not? What I am looking for is ways to change the behaviour.
BTW, the Autodocs (which come with MUI 3.8) are not very good at explaining the implications of various things (they usually assume you know a lot of stuff, so I end up having to guess).
Quote:
Of course the text is not wrapped.
I thought it was obvious I already knew that, because I said "since I don't know where it should be wrapped!". I was merely mentioning all related details, rather than guessing what might be important (or what I might have gotten wrong).
(TextObject) You must not modify the text as long as it is "in use" by the object. MUI will calculate the required dimensions on basis of the given text and expects it to be constant.
I think you are wrong here, because the MUI Autodocs say "The string is copied into a private buffer, you can destroy the original after using this tag." (Of course you still need to use set() to tell MUI you want to change the text! MUI isn't psychic)
(TextObject) If you really need to change the text, then you must set() it again after the modification.
That is what I *am* doing! Why did you think I wasn't?
Because you were telling something about "write outside of itself". I considered this as "text being displayed outside the object's box", because the text was modified externally by your application. That's all.
Quote:
Perhaps I misunderstand your reply, but it doesn't seem relevant to what I said: I want FloattextObject to show the entire *initial* contents, but it only shows 3 lines (no matter how large the window starts out). If this is the intended behaviour, it seems kind of useless!
Floattext.mui is a subclass of List.mui and as such has no restrictions on its dimensions, except you enforce them, i.e. by using MUIA_FixHeightTxt or by subclassing Floattext.mui yourself with a restricting implementation of MUIM_AskMinMax. MUI cannot just resize an object to display the entire inital content, because the content is arbitrary. It may be zero lines, but it may be a million lines. What should the initial size be in this case? Of course you can override MUIM_AskMinMax and return the dimensions which fit you best, but you must be prepared and accept that MUI will adapt the actual dimensions of the object within the limits that your (or the default) MUIM_AskMinMax method returns.
I think you are wrong here, because the MUI Autodocs say "The string is copied into a private buffer, you can destroy the original after using this tag." (Of course you still need to use set() to tell MUI you want to change the text! MUI isn't psychic)
No, I am not wrong. This is why I mentioned the MUIA_Text_Copy attribute. This allows you to override this behaviour, but it is an attribute of MUI 4.x. MUI 3.8 will ignore it.
Furthermore, until your last post you never mentioned that you are referring to MUI 3.8. This has a fixed behaviour in certain respects, but MUI4 very often gives you the choice to change this fixed behaviour. I.e. there is no need to make another copy of a string from a locale catalog which will not vanish until you close the catalog. Thus you have the possibility to let Text.mui use the string directly without copying it.
Because you were telling something about "write outside of itself". I considered this as "text being displayed outside the object's box"
Yes, that is exactly what happens. When I use set().
Quote:
(FloattextObject) It may be zero lines, but it may be a million lines. What should the initial size be in this case?
That's easy. The initial size should be "as large as possible", but if you want more precise: The text box should request the full size (a million lines if necessary), and the Window should try to accomodate that. If the screen is not large enough, then no problem as the text box has scrollbars.
At the moment it seems to take the least useful initial size, which is "as small as possible" (no matter the initial contents). AND WORSE is that it cannot be enlarged beyond the initial size (so the window is also vertically fixed).
I'm afraid the MinMax algorithm gives me a headache, so I don't know if the above is actually possible for MUI, but it would seem kinda silly if it couldn't be made to behave like that.
Quote:
you never mentioned that you are referring to MUI 3.8
Well, I'm probably using 3.9, whatever the latest public version of MUI is on OS4. BTW, I'm not even sure if MUI4 has been announced (erm, before you post here anyway...).
The docs are from 3.8, since that is available for AmigaOS3, and presumably AROS is most compatible with that too.
Quote:
No, I am not wrong.
Your answer worries me. Either the autodocs for MUI 3.8 contain a serious error, or MUI 4 is going to break compatibility with MUI 3.x (programs). Since I assume that MUIA_Text_Copy is a new MUI4 thing, I would have expected it to default to TRUE, so that MUI 3.x programs get the behaviour mentioned in the autodocs.
(TextObject) I'll give your ScrollgroupObject suggestion a try, but I would have thought I'd have tried something similar before (without success)...
I am sorry to report that it makes no difference. The TextObject still prints outside it's boundaries, nor do the scrollbars do anything, and the window still has a fixed vertical size.
Just in case my MUI installation is screwed-up, I tried on a clean OS4.1 install on my Sam440, and I get the same result.
Because you were telling something about "write outside of itself". I considered this as "text being displayed outside the object's box", because the text was modified externally by your application.
Yes, that is exactly what happens. When I use set().
Would be nice if you could set up a tiny demo application which demonstrates exactly this behaviour with MUI 3.x. I'd like to know if this bug is fixed in MUI 4 already.
Quote:
Quote:
(FloattextObject) It may be zero lines, but it may be a million lines. What should the initial size be in this case?
That's easy. The initial size should be "as large as possible", but if you want more precise: The text box should request the full size (a million lines if necessary), and the Window should try to accomodate that. If the screen is not large enough, then no problem as the text box has scrollbars.
Well, that is your personal opinion. I rather like windows which do not cover the whole screen unless I resize them. If an object is resizeable and scrollable there is no need to make it as big as possible. Why should an object consisting one million line be as high as the screen, even if that still is not large enough to display one million lines?
This is why you can specify 3 values during MUIM_AskMinMax: minimum, default and maximum. Just implement this method in your subclass and set the default size to a very large value, but smaller that MUI_MAXMAX (=10000). This will make your object as large as possible.
Quote:
At the moment it seems to take the least useful initial size, which is "as small as possible" (no matter the initial contents).
Again, this is your opinion. Others might think different.
Quote:
AND WORSE is that it cannot be enlarged beyond the initial size (so the window is also vertically fixed).
A plain text object cannot be higher than its text, unless you set MUIA_Text_SetVMax to FALSE (default is TRUE). This will give your object unrestricted height, but the text will be displayed vertically centered, unless you set MUIA_Text_VCenter to FALSE.
Quote:
Quote:
No, I am not wrong.
Your answer worries me. Either the autodocs for MUI 3.8 contain a serious error, or MUI 4 is going to break compatibility with MUI 3.x (programs). Since I assume that MUIA_Text_Copy is a new MUI4 thing, I would have expected it to default to TRUE, so that MUI 3.x programs get the behaviour mentioned in the autodocs.
Specifying the default value again is neither bad nor illegal. Of course MUI4's default behaviour is to copy the text. I never said anything different. Please forgive me if I don't remember the default value for each and every attribute.
Would be nice if you could set up a tiny demo application which demonstrates exactly this behaviour with MUI 3.x. I'd like to know if this bug is fixed in MUI 4 already.
This is a bit difficult, since all my MUI code is auto-generated at run-time by my own GUI abstraction. However, I will see what I can do.
Quote:
(FloattextObject) A plain text object cannot be higher than its text
That isn't the problem. The problem is that a FloattextObject only shows 3 lines (what is required to show the scrollbar+arrows), even if it's initial contents is "a million lines". And it is not possible to enlarge it (nor the window ) to show more than 3 lines. Trying to read a million lines through a (fixed-size!) peep hole is not fun, and I find it hard to believe this is MUI's intended behaviour.
Quote:
A plain text object cannot be higher than its text, unless you set MUIA_Text_SetVMax to FALSE (default is TRUE). This will give your object unrestricted height,
Sadly that makes no difference at all. It is still limited to 3 lines, and not vertically resizable. I tested with a FloattextObject, but did you mean to switch back to talking about a TextObject again? In any case, I'd previously tried that on a TextObject, but it made no difference.
Quote:
Just implement this method in your subclass
At the moment I don't know how to create subclasses, and will only investigate if it turns out there is no other solution to my (various) text problems.
Quote:
Why should an object consisting one million line be as high as the screen, even if that still is not large enough to display one million lines?
I wasn't suggesting that "as large as possible" was the optimum solution, but rather it was just better than "as small as possible", which seems like the worst solution to me: In that case the scrollbar is so small that I have no indication of how much it contains (could be 5 lines or 500), and therefore no indication if I need to enlarge it (nor by how much). It also guarantees that it is showing the least amount of text, when it's whole purpose is to be useful by showing text!
Still, if you think this is debatable, then perhaps it should be an option within MUI Prefs?
BTW, my ideal compromise (solution) would be for the MUI window to be "half way" between it's smallest possible size & it's largest possible size.
Would be nice if you could set up a tiny demo application which demonstrates exactly this behaviour with MUI 3.x. I'd like to know if this bug is fixed in MUI 4 already.
This is a bit difficult, since all my MUI code is auto-generated at run-time by my own GUI abstraction. However, I will see what I can do.
Just extract a portion of your generated code. Is that possible?
Quote:
That isn't the problem. The problem is that a FloattextObject only shows 3 lines (what is required to show the scrollbar+arrows), even if it's initial contents is "a million lines". And it is not possible to enlarge it (nor the window ) to show more than 3 lines. Trying to read a million lines through a (fixed-size!) peep hole is not fun, and I find it hard to believe this is MUI's intended behaviour.
Just take a look at MUI's demo application MUI-Demo. It uses Floattext objects in every single window. For me these are definitely higher than just 3 lines. The source is unchanged since, hm let me think... MUI 3.0? So even an outdated MUI 3.8 SDK should be enough.
Quote:
Still, if you think this is debatable, then perhaps it should be an option within MUI Prefs?
Definitely not, because this is something the user should not need to care about.
Quote:
BTW, my ideal compromise (solution) would be for the MUI window to be "half way" between it's smallest possible size & it's largest possible size.
I am getting more and more the impression that there is no MUI fault, but there is something fishy with you automatically generated code. If resizeable GUIs using MUI would be so hard to accomplish, then i.e. YAM would have a hard time.
OK, I've taken the original (and only) test MUI program I wrote by hand, gutted it, and then put in the pieces of auto-generated code that were causing me problems.
With a bit of fiddling I have been able to produce a test program which shows all the problems I've run into. The program is written in PortablE, but I provide it for interest (MuiTextProblems.e).
I then translated it into C++ code (using PortablE), and spend quite a while cleaning it up into something you should be able to use (MuiTextProblems3.cpp). I also compiled ready for testing (MuiTextProblems3).
When run you should see a window containing a FloattextObject, a TextObject inside a ScrollgroupObject, and two buttons. The FloattextObject contains 5 lines of text, while the TextObject to only contains a tiny piece of text (otherwise the drawing-outside-itself bug does not appear).
The FloattextObject is only 3 lines of text, and cannot resize vertically larger, despite containing 5 lines of text.
Now click on the "Do test" button. This will use SetAttrs() to replace the contents of both text objects with 13 lines of text each.
The TextObject should draw outside of itself (once), although horizontally resizing the window will get rid of the rubbish. The TextObject will behave as if it contains only one line of text (cannot be scrolled or resized to show the other lines).
The FloattextObject can be scrolled fine, but will not vertically resize beyond it's 3 lines.
While there is most likely a good explanation for why FloattextObject will not resize, I can't work out why. OTOH, the behaviour of TextObject definitely seems to be buggy.
The FloattextObject is only 3 lines of text, and cannot resize vertically larger, despite containing 5 lines of text.
An example source is able to reveal lots of misunderstandings! This is an easy one. You have a fixed height label on the left side. Even if the Floattext object is resizable is both directions by nature the fixed height of the left side label forbids a vertical resize. If want to the Floattext object to be resizeable then you must make the label resizeable as well by adding at least one space object above or below the label object like this:
This will give you a top aligned label. Placing the label after the VSpace(0) object will make it bottom aligned. Using VCenter() will give you a vertically centered label. Choose the solution which fits your needs best.
Quote:
The TextObject should draw outside of itself (once), although horizontally resizing the window will get rid of the rubbish. The TextObject will behave as if it contains only one line of text (cannot be scrolled or resized to show the other lines).
This is definitely a bug in MUI. The Text object just redraws itself, but does not cause a relayout due to the changed amount of lines. I will look into this.
EDIT: Ok, found it. The next release will handle changed number of lines correctly and resize/relayout the Text object accordingly. Thanks for the hint!
@tboeckel Thanks for the solution! It works for FloattextObject, but not TextObject (due to the bug). Since most of my resizing experiments would have been with TextObjects, this explains why I was never able to work out how to make it resizable! (And perhaps also why I had such trouble understanding the behaviour of MUI's MinMax size algorithm.)