Set width of sap.m.MenuButton - css

I have a MenuButton https://openui5.hana.ondemand.com/explored.html#/entity/sap.m.MenuButton/samples
in a bar with long text property value.
I would like to set width of the MenuButton in order to show all the text.
If I set width property, I can set (reduce) length (2px, 5px, 15px...) but increasing over a threshold the button remain to a fixed max size.

It's kind of an overkill but if you want to avoid using custom CSS classes, you could wrap the MenuButton with a flexbox control (with renderType="Bare") and override max-width (or set min-width) by using FlexItemData as a layoutData.
<HBox renderType="Bare">
<MenuButton text="Hello World" width="600px">
<layoutData>
<FlexItemData maxWidth="100%"/>
</layoutData>
</MenuButton>
</HBox>
PS: The max-width of sap.m.MenuButton was indeed not documented. After filing an issue, the API reference now mentions that it has a max-width.
As per visual design this width can be maximum of 12rem (192px)

Related

JavaFX : Adapt component height to its children height?

I'm trying to develop a desktop app using javaFX (2.2), and I'm experiencing some difficulties to really get it to behave like I would like it to. Being a new user of the framework, I might not be using it as it should be...
What I want is a kind of dashbord, with several JavaFX or custom controls inside a ScrollPane. I currently have several views that look like this :
<AnchorPane id="userContent" xmlns:fx="http://javafx.com/fxml" fx:controller="squalp.view.OrgViewController">
<children>
<ScrollPane fx:id="scrollPane" styleClass="transparent" hbarPolicy="NEVER" vbarPolicy="AS_NEEDED" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<content>
<VBox fx:id="vBox" styleClass="transparent" alignment="TOP_LEFT" focusTraversable="true">
<children>
<Label text="Label" />
<Button fx:id="bTest" text="Test" onAction="#test"/>
<TreeView fx:id="orgTree" focusTraversable="true" />
</children>
</VBox>
</content>
</ScrollPane>
</children>
</AnchorPane>
As long as I keep using simple controls, no problem, items are correctly placed one after another in th VBox.
But when using TreeViews or TableViews, I can only get my controls to have fixed height, meaning extra space on the bottom, or new scroll bars, in addition to the main one. What I would like to achieve is to adapt my controls to their current content height.
Qt's QML, for exemple, has a childrenHeight property, and it's kind of what I'm looking for. I figure this content height must be calculated somehow, since components scrollbars do adapt to the content.
I had to use a workaround for tableviews :
table.setPrefHeight(list.size() * rowHeight + headerHeight);
but I couldn't find a way to track displayed items on a treeview.
Has anyone an idea of what I could be doing to handle this issue ? Or I am really not using the framework as I should ?
Thanks in advance.
EDIT : Visual description of the problem :
Case 1
Here my treeview's height is set to a default value. There are not enough items to fill the treeview : if I want to put another component below, there'll be a gap; if my scene is not big enough, the ScrollPane's scrollbar appears, even though all the displayable content is visible.
Case 2
If if expand my treeview's items, there are now too many of them. They are not all visible at once, and the treeview's scrollbar appears, even though I already have a scrollable view with the scrollpane.
What I would like is my TreeView to adapt to its content height (reduced height if items are collapsed, bigger height if they are expanded), in order to be able to put several components one after another and to scroll through them all using the ScrollPane's scrollbar.
Since the TreeView component has itself a scrollbar, its visible content's height must be calculated at some point (since scrollbars basically use ratios based on contentHeight/componentHeight). This information doesn't seem to be available in the public API, but I wonder if, developping a custom class that expands TreeView, there could be a way to bind my component to its "visible height".
There maybe a proper way to achieve your goal, but I can suggest the approach similar to tableview's.
orgTree.prefHeightProperty().bind(orgTree.impl_treeItemCountProperty()
.multiply(treeRowHeight)); // treeRowHeight maybe 24.
Note that this is only a workaround where the deprecated and internal use-only method is used, which maybe removed in future releases.
I was looking for way to make TreeView auto-resize to fit its content, e.g. when a node is expanded or collapsed. Here's what I eventually do. Note the Platform.runLater() is required, thus simple property binding would not work here. Also note the cellHeight is the height of a tree node. It's beyond the scope of the question here how to get that.
treeView.expandedItemCountProperty().addListener((obs, oldV, newV) -> {
Platform.runLater(() -> {
treeView.setPrefHeight(newV.intValue() * cellHeight);
});
});
You can use the binding property of the view to the childs height property. By this, whenever the height of the Parent changes, childs height will automatically change ! This is not automatic height adaption, like you want, but a forced adaption, which will help you !
Width property is also available
Basically this is a snippet that will help you :
pane.heightProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> arg0,
Number oldValue, Number newValue) {
table.setPrefHeight(newValue - 200);/*The difference of height between
parent and child to be maintained*/
}
});

flex mobile: cropped delete icon on ipado on textInput component

here is my CSS for textInput
s|TextInput{
skinClass: ClassReference("spark.skins.mobile.TextInputSkin");
contentBackgroundColor:#FFFFFF;
focusAlpha:0;
showPromptWhenFocused:false;
}
and I use simple:
<s:TextInput id="id1" />
<s:TextInput id="id1" height="40" />
<s:TextInput id="id1" height="60 />
On iphone/ipad: the close icon appears top cropped:
Any idea how to fix that ? (or even how to remove that X icon) ?
The icon is a set height and, at least in Flex, doesn't adjust its size. The cropping is from the height of the textfield (read: not the TextInput component, but the actual field the text goes in). Because that field is not as tall as the icon, the icon gets cropped.
There are two solutions:
The obvious one is to increase the height on the TextInput field until that icon is no longer cropped. You could just take your screenshot and measure out the pixels being cropped, if you want.
You get that icon because TextInput uses StageText. StageText uses native text rendering as opposed to Flash text rendering. In ideal situations, StageText is perfect. However, the situation is rarely ideal. To get around this, you simply apply the mobile TextInput skin skinClass="spark.skins.mobile.TextInputSkin" to your TextInput component(s). As www.Flextras.com pointed out to me yesterday, this reverts the TextInput back to its behavior prior to Flex 4.6, which introduced StageText.
Either one of those solutions should work for you. You just need to choose which is best. I prefer Option #2 because, as I mentioned, there are other issues with StageText (such as getting displayAsPassword to function correctly) that switching to that skin fixes
I would try editing the skin, because that is where the icon crop is happening

Flex: Find the width of text in a spark label

Suppose I have a (Spark) label. What is the best way to find the length of the text in it? I looked at the myLable.measureText("bla bla") method but it says:
To measure text in Spark components, get the measurements of a spark.components.Label or spark.components.RichText
After looking around I cannot find what this is refering to. I tried myLabel.measureWidth() but this does not return anything usefull (it frequently returns zero).
Note: I am explicitly setting the width like this:
<s:Lable width="{globalWidthVariable"} .../>
If the text overflows I would like to increse the globalWidthVariable to the size of the text.
Using the width attribute will work as long as you never set the width attribute. (Setting the width attribute turns off auto sizing.) To avoid setting the width attribute I: read from the width addribute and placed a buffer beside the text box like this:
<hbox>
<label id="myLable" ... />
<spacer width="{globalWidthVariable - myLabel.width}" />
</hbox>
The spacer cannot make the label smaller than globalWidthVariable but it can expand it (only functionality I require).

Flex custom button component

I want my custom button to look like the button sample below.
More specifically, I want the width of the button to be determined by the width of the largest word in the label (i.e. width of "Elongated" in my example). The label must wrap, not truncate.
And I want only one pixel between the top edge of the icon and my button's top edge.
I have tried lots of things but to no avail so far. I have reduced the horizontalGap and verticalGap to zero and padding to zero. But still nothing. Please help.
Here's what I have right now:
<mx:Button top="0" cornerRadius="2" paddingLeft="0" paddingRight="0" leading="0" letterSpacing="0" paddingTop="0" paddingBottom="0" verticalGap="0" horizontalGap="0" textAlign="center" labelPlacement="bottom" icon="{MyIcon}" height="60" width="75" label="Elongated Label" fontSize="10" />
That's not at all simple.
You will need to create your own button,
public class Mybutton extends Button {...}
override createChildren and set the word wrap of the IUITextField used for the label to true.
override measure and use your own line metrics to determine the width that the button should be. If you get the measure right, the button will lay itself out properly.
I don't have a dev environment in front of me at the moment, but something along these lines should work:
Set truncateToFit property of the Label to false (OR use a TextField with wordWrap set to true - I think this should keep the words together as much as possible).
I haven't had the need to use any of the above yet, and hopefully you haven't tried them yet because it would be an easy solution to a part of your problem. Without any code, I'm not sure why padding didn't work, but maybe it's something to do with the word truncation.
As an alternative, why not use a Button, embed or specify a source for your icon and decide where to place the text by specifying the object's labelPlacement property?
EDIT: Since there's no property in Button about wordWrap, as they would recommend in the Adobe Flex forums for such questions regarding sizing based on content where there is no automatic feature to do that, you have to find the longest word and adjust the width of the button (i.e.: in the creationComplete event). Experimenting to find the font to pixel ratio would be my best bet (or you can use a Monospace font where all the characters are given the same space thereby simplifying the estimation):
creationComplete="event.target.width=returnMyWidth();"
As for the padding, it may be related to the custom width that you had set or it may be from embedding the image automatically setting a padding by being included - I'm not really sure, so it would be good if someone can offer a comment based on experience with this.

Multi line text in Flex doesnt recalculate when runtime css is changed

For loading time considerations I am using a runtime css file in my Flex Application.
I am having a problem with a multi line text control :
<mx:Text id="txtDescription" selectable="false"
styleName="imageRolloverButtonTextDark" width="100%" textAlign="center"
text="{_rolloverText}"/>
When my CSS stylesheet has loaded the text style correctly changes, but the height is not recalculated. It appears to be just a single line field.
FYI: The control is not actually visible, and triggered by a rollover. So I dont really care if the stylesheet hasnt loaded and they get standard system text. I jsut want it to be the correct height when it has been loaded.
Per the Adobe documentation for Text
Sizing a Text control
Flex sizes the
Text control as follows:
If you specify a pixel value for both
the height and width properties, any
text that exceeds the size of the
control is clipped at the border.
If you specify an explicit pixel
width, but no height, Flex wraps the
text to fit the width and calculates
the height to fit the required number
of lines.
If you specify a percentage-based
width and no height, Flex does not
wrap the text, and the height equals
the number of lines as determined by
the number of Return characters.
If you specify only a height and no
width, the height value does not
affect the width calculation, and Flex
sizes the control to fit the width of
the maximum line.
As a general rule, if you have long
text, you should specify a pixel-based
width property. If the text might
change and you want to ensure that the
Text control always takes up the same
space in your application, set
explicit height and width properties
that fit the largest expected text.
So the trick I've used to deal with this is to have the Text get its width via a binding expression from whatever container limits it's width, typically the immediate parent.
e.g.
<mx:Canvas id="box" width="100%" backgroundColor="Red">
<mx:Text width="{box.width}" text="{someReallyLongString}" />
</mx:Canvas>
For any one else who has this problem, The solution I found was to create a custom component extending the mx.controls.Text
and then override the styleChange() Method, and explicitly call the invalidateDisplayList() method for the text field once the style has been applied.
It should be called automatically when the styleis changed but no...for some reason in flex 3.5 it is not.
public class TextObject extends Text { //...
override public function styleChanged(styleProp:String):void { invalidateDisplayList(); }
}
Hope that save some one all the time I lost on it.
Could you use a fixed pixel width instead of 100%? I've had issues with 100% being wrongly calculated on dynamic text controls before.

Resources