Fix width label with dynamic font size - qml

Is there a way in cascades to get font size for a given text and fixed width?
I was trying with:
TextField{
autoFit: TextAutoFit.FitToBounds
}
But the text always appear left align. The requirement is to center align text with variable font size label render in fixed rect.

If you want just to center align text, you'd need to use textStyle.textAlign property like that:
textStyle.textAlign: TextAlign.Center
In order to center align text with variable font size label render in fixed rect, you basically need to specify the desired width and height of that rectangle for a Label use textStyle.textAlign property mentioned above and choose the font size via respective textStyle.fontSize Label property. Text aligning will be done by Cascades automatically (of course, if your text couldn't be fit in specified width/height it'd be cut off):
import bb.cascades 1.0
Page {
Container {
layout: DockLayout {}
horizontalAlignment: HorizontalAlignment.Fill
verticalAlignment: VerticalAlignment.Fill
Label {
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
maxWidth: 300
minWidth: maxWidth
maxHeight: 100
minHeight: maxHeight
multiline: true
text: "Some very very very very very long text here"
textStyle.textAlign: TextAlign.Center
textStyle.fontSize: FontSize.XLarge
}
}
}
I'd recommend this approach for achieving the goal set.
However, if you really want to get absolute values of font being used in a widget, use textStyle.fontSize property for this (TextStyle official documentation).

There are no font metrics in BB10 Cascades at the moment so you won't be able to find out if the font does not fit in the label and resize it.
You can use sort of hack with layoutUpdateHandler to get some rough resizing, but I wouldn't recommend it. If the text changes frequently you will see flickering, but if it's only set once then it might be okay. Change the text set in "onCreationCompleted" to see if the text resizes for you.
Container {
id: root
implicitLayoutAnimationsEnabled: false
background: Color.Cyan
property int width: 500
property string text: ""
property double textSize: 20
layout: DockLayout {
}
attachedObjects: [
LayoutUpdateHandler {
onLayoutFrameChanged: {
if (layoutFrame.width > root.width) {
root.textSize = root.textSize - 1
}
}
}
]
Label {
implicitLayoutAnimationsEnabled: false
maxWidth: root.width
text: root.text
textStyle {
fontSize: FontSize.PointValue
fontSizeValue: root.textSize
}
}
Label {
implicitLayoutAnimationsEnabled: false
text: root.text
opacity: 0
textStyle {
fontSize: FontSize.PointValue
fontSizeValue: root.textSize
}
}
onCreationCompleted: {
root.text = "Hello World AAAAAAAA"
}
}

Related

QML - How to correctly set an implicitWith to a GridLayout

I'm using Qml 5.12 and basically trying to set an implicitWidth to a GridLayout.
For that, I have a purple rectangle and set the rectangle's width to the GridLayout.
The red rectangle fit with the GridLayout so I can see the width of my GridLayout.
Here's my code:
Rectangle { anchors.fill: gl; color: "red"; opacity: 0.22 }
Rectangle { id: rect; width: 350; height: 30; color: "purple"; }
GridLayout
{
id: gl
y: 35
implicitWidth: rect.width
columns: 2
Label { text: "This is a test" }
SpinBox { Layout.alignment: Qt.AlignRight }
}
If I run the code, I expect to have my both rectangle with the same width.
But the actual result is that the red rectangle is smaller. So the implicitWidth was not considerate.
Can anybody tell my why ?
Thank's !
The GridLayout compute its own implicitWidth based on its children's implicitWidth. So the value you set gets overwritten by the computed one.
implicitWidth is the width an Item wants to have (and the one it would have if no width is explicitely set). Setting it based on something else than its children or some internal value makes little sense.
Here you want the GridLayout to be the exact size of your Rectangle so just set its width property.

Resize rectangle with Text

I want to create a custom drop-down box with text inside. The problem is, when I resize my Rectangle to fold it the Text stays on screen.
Rectangle {
id: dropdown
height: 200
width: 200
color: "red"
Behavior on height {
NumberAnimation {
duration: 1000;
easing.type: Easing.InQuad
}
}
Text {
id: text
anchors.left: parent.left
anchors.top: parent.top
text: "foobar"
}
}
How to solve this?
Ok. I have it thanks to jbache.
I need to put clip:true inside dropdown. According to the documentation of clip:
This property holds whether clipping is enabled. The default clip value is false.
If clipping is enabled, an item will clip its own painting, as well as the painting of its children, to its bounding rectangle.
Hence, by setting the property to true, I can ensure that also the child Text will be correctly hidden on drop-down dismiss.

Measure text in titanium

I'm writing an app and need to paint text, It must to measure text to get point to paint. But in my knowledge, titanium don't support it. How can I do that
Measure text as in length of the text string? If your text is in a textfield you can get the .value out of it and then use string lengths to get out it's length.
I feel like this is what you want;
var label1 = Ti.UI.createLabel({
color: '#900',
font: { fontSize:48 },
text: 'A simple label',
textAlign: Ti.UI.TEXT_ALIGNMENT_CENTER,
top: 30,
width: Ti.UI.SIZE, height: Ti.UI.SIZE
});
win.add(label1);
label1.addEventListener('postlayout', function(e) {
var label1_height = e.source.rect.height;
var label1_width = e.source.rect.width;
Ti.API.info(label1_height, label1_width);
});
Change the window name to yours, then run it. Should do the trick. Print the width and height of your label.

QML - How to change TextField font size

How can I set the font size of a TextField element in QML? wanna change size of the placeholderText and also for the text which the user enters.
I tried with a lot of ways without luck!
TextField {
id: name_TextField; horizontalAlignment: Text.AlignHCenter;
Layout.preferredWidth: parentCLayer.width * 0.90; Layout.preferredHeight: 50
style: TextFieldStyle {
font.pixelSize: 20 // This doesn't seem to work either
}
placeholderText: qsTr("Your name here")
}
You can use the style property to customize your TextField. For example:
TextField {
style: TextFieldStyle {
font.pixelSize: 14
}
}
I tried it and it works like a charm
Using the font member of TextField
The TextField type itself has a member font which contains an instance of the QML basic type font. It's sufficient to change the values of the inner-members of the font member of TextField to make the changes you want to see. Note that the color is provided by the TextField itself, not the font type.
TextField {
font.pointSize: 20
font.bold: true
font.family: "Times New Roman"
textColor: "red"
}
Default Style
Custom Style
Using the style member of TextField
If you want to do more in-depth styling of the TextField you can attach a TextFieldStyle to the style member of the TextField. The TextFieldStyle instance also has a font member, though in the IDE it will complain that font has no members if you reference them with dot notation, this may be bug QTCREATORBUG-11186. I believe the proper way to assign values is using group notation by referencing the font property with inner-items as such:
TextField {
style: TextFieldStyle {
background: Rectangle {
color: "red"
radius: 10
}
font {
bold: true
pointSize: 22
}
textColor: "white"
}
}
It could be that bug #11186 is a genuine bug, or maybe by design the font property is TextFieldStyle is null; someone with better Qt/QML knowledge could provide a clearer answer as to that part of the question.
This guide on styling may help: http://wiki.qt.io/Qml_Styling

QML - Control border width and color on any one side of Rectangle element

Currently i had a requirement of drawing a delegate rectangle with the help of ListView control. I was able to draw a series of rectangle either horizontal or vertical within the list view but the problem is with the border of the rectangle. The border width at the intersect point of the adjacent rectangle is of twice the width.
The delegate rectangle is nothing but a Qt Quick Rectangle element.
Is it possible to limit the border width on any one side of the rectangle alone?
Is it possible to change the color on any one side? (Something similar to QLineEdit - Where we can control the border width and color with respect to the sides)
Regards,
Santhosh.
You can make a custom border element like this :
CustomBorder.qml
import QtQuick 1.0
Rectangle
{
property bool commonBorder : true
property int lBorderwidth : 1
property int rBorderwidth : 1
property int tBorderwidth : 1
property int bBorderwidth : 1
property int commonBorderWidth : 1
z : -1
property string borderColor : "white"
color: borderColor
anchors
{
left: parent.left
right: parent.right
top: parent.top
bottom: parent.bottom
topMargin : commonBorder ? -commonBorderWidth : -tBorderwidth
bottomMargin : commonBorder ? -commonBorderWidth : -bBorderwidth
leftMargin : commonBorder ? -commonBorderWidth : -lBorderwidth
rightMargin : commonBorder ? -commonBorderWidth : -rBorderwidth
}
}
main.qml
import QtQuick 1.0
Rectangle
{
width: 500
height: 500
color: "grey"
Rectangle
{
anchors.centerIn: parent
width : 300
height: 300
color: "pink"
CustomBorder
{
commonBorderWidth: 3
borderColor: "red"
}
}
Rectangle
{
anchors.centerIn: parent
width : 200
height: 200
color: "green"
CustomBorder
{
commonBorder: false
lBorderwidth: 10
rBorderwidth: 0
tBorderwidth: 0
bBorderwidth: 0
borderColor: "red"
}
}
Rectangle
{
anchors.centerIn: parent
width : 100
height: 100
color: "yellow"
CustomBorder
{
commonBorder: false
lBorderwidth: 0
rBorderwidth: 0
tBorderwidth: 10
bBorderwidth: 10
borderColor: "blue"
}
}
}
In this example I have used the custom element to make different rectangles which have border on all, one or two sides.
The simplest solution for a ListView is to give your delegate a 1 pixel border and then use a spacing of -1 to get each cell to overlap the other by 1 pixel:
ListView {
spacing: -1
delegate: Rectangle {
height: 40
width: parent.width
border.width: 1
border.color: "black"
z: listView.currentIndex === model.index ? 2 : 1
...
}
...
}
It should work the same for other border widths.
EDIT: Added a nice enhancement from comment below that makes sure the selected item's border is always above all others so that if you change it to indicate selection it's not obscured by its neighbor delegates.
If you're trying to add borders between items in ListView, you should use the given property 'spacing' to establish a common border between each item. Then you could potentially add a background to the ListView to customize border colors.
Example:
ListView {
spacing: 1 // or whatever you want the border to be
}
...But if you really want a specific border you could always use Rectangles to make your own borders:
Item { // this is your 'rectangle'
Rectangle { // the main thing
id: rec
anchors.fill: parent
anchors.leftMargin: 2
anchors.rightMargin: 5
// etc
}
Rectangle { // a border example
anchors.right: rec.right
height: parent.height
width: 5
color: "red"
// etc
}
}
A bit late to answer but the accepted solution draws the border outside the geometry of the rectangle which can be problematic in some cases.
Another way to do this is to do something like:
// CustomBorderRect.qml
import QtQuick 2.12
Item
{
property alias color: innerRect.color
property alias borderColor : borderRect.color
property int borderWidth: 0
property int lBorderwidth : borderWidth
property int rBorderwidth : borderWidth
property int tBorderwidth : borderWidth
property int bBorderwidth : borderWidth
Rectangle
{
id: borderRect
anchors.fill: parent
Rectangle
{
id: innerRect
anchors {
fill: parent
leftMargin: lBorderwidth
rightMargin: rBorderwidth
topMargin: tBorderwidth
bottomMargin: bBorderwidth
}
}
}
}
This can then be used like this:
CustomBorderRect
{
width : 50
height: 30
color: "lightseagreen"
lBorderwidth: 0
rBorderwidth: 5
tBorderwidth: 5
bBorderwidth: 0
borderColor: "lightyellow"
}
This way the border is drawn with the given geometry.