SwiftUI, How to set Text width correctly? - text

I have a very simple ContentView, The Text's width set to 68
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, world!")
.frame(width: 68)
}
.padding()
}
}
But in Debug View Hierarchy I can see the Text's width is not 68 at all, instead, the wrapper width of the Textis 68. Did I miss something?

Text isn't greedy by default and won't take all the space it's got available to it unless it's needed. Due to the extra width not being needed, it won't use it.
The width of the VStack is 68 as it's sized based on the size of it's child views, in this case it's only child view is explicitly saying it's width is 68, so the width of the VSTack will be 68 and since the Text isn't greedy in this case, it'll only take up the horizontal space that it needs. This leads to the width of the Text being less than the width of the VSTack.
If you don't explicitly set the width of the Text you will see that the width of the VStack will match the width of the view it contains.

The frame is 68 wide but the Text inside it doesn't need that much so there is a gap. View modifiers usually wrap what's inside in an outer view, e.g.
myView.frame() is essentially doing:
FrameView {
myView
}
If you want bigger text you could increase the font size ;-)

Related

Rounded corners not shown for QPushButton in Qt Designer

I want to the corners to be rounded and hover for a QPushButton in Qt designer. Changing the style sheet has no effect. What am doing wrong?
QPushButton#pushButton_3{
background: rgb(170, 170, 255);
border: 2px solid rgb(0, 170, 255);
border-style: outset;
border-width: 2px;
border-radius: 20px;
color: white;
}
QPushButton:hover#pushButton_3{
background-color: rgb(0, 255, 255);
border: 2px solid (0, 255, 255);
}
This is what I get when the above style sheet is set:
TL;DR
Use smaller values for border-radius, usually half of a standard font size (2 <= radius <= 10).
Further explanation
The QSS border radius must have a reasonable value.
The private QStyleSheetStyle normalizes the border radius (or, better, all four border radii) based on the bounding rect of the widget, which includes the border size(s).
Whenever any border radius exceeds the size related to its corner, all radius are ignored.
For instance, if the rectangle of a widget has height 10, the sum of its top-left and bottom-left radii must be equal or less than 10, otherwise the left corner will be squared.
Note that widgets normally consider the border only for their size hint, not their minimum size hint, and that behavior also can change depending on the current style.
A button is normally created using the current style's pixelMetric() and fontMetrics(), and since a pretty standard height of a button is ~30 pixels, considering the above, the border-radius specified is excessive: the sum of any corner component is always greater than the widget height, so the radii are ignored, and the border will be squared.
So, how to set a proper border radius?
The easy answer is: use "small" values, normally no more than twice or four times the border width.
The actual answer is more complex, as we need to consider that widgets often have some displayed text, and any modern OS supports both font scaling and high DPI screens.
QSS support various types of lengths other than the standard px:
px: pixels (normally, physical pixels, AFAIK, the actual value depends on the OS and their implementation of High DPI);
pt: the size of one point (based on the screen DPI, AFAIK, only used for text properties and ignored for widget/border sizes);
em: the em width of the font (based on the displayed font);
ex: the x-height of the font (as above);
If you want to properly support any modern OS, you probably need to use any of the last two values, and that's another reason for which is important to set a global style sheet for the application: as long as the app is created, you can know the default (or imported) fonts, and eventually set a main style sheet with formatted widths or sizes based on the current device pixel ratios and font metrics.

Constant stroke width rectangle with FabricJS

Is there any way to draw rectangles using FabricJs with constant width strokes?
On every example I could find, you can set the stroke width but when you resize the rectangle, the stroke is scaled together with the shape.
I'm late to the game here but I wanted to document this somewhere. The fiddle from davidtorroija (http://jsfiddle.net/davidtorroija/nawLjtn8/) shared in the above comment was nearly a perfect solution for me, but it has a big issue. Fabric uses values called "cacheWidth" and "cacheHeight", and without changing those as well, you can end up with some dodgy rendering not matching the specified height and widths:
Without changing the cached values:
https://i.gyazo.com/6cc1223444309cd55715bd81aa9dcb39.gif
With changing the cached values:
https://i.gyazo.com/e842b57af255460fcdbdc3533a6793e6.gif
Something like this should do the trick
// Existing code
this.width *= this.scaleX
this.height *= this.scaleY
// New code
this.cacheWidth = this.width
this.cacheHeight = this.height

Size JointJS Rect shape based on text?

Usually, when we create a Rect shape in JointJS, we specify a size.
var cell = new joint.shapes.basic.Rect({
size: size,
attrs: {
text: {
text: text
}
}
});
graph.addCell(cell);
Is there a way to not provide a size property, but have the shape take on the dimensions required to fit the text?
I am aware of joint.util.breaktext, but I do not wish to break text in this case.

how to auto-adjust the height of an rectangle to contain the text inside it in d3 tree

Hi guys i got an update in my problem........
the problem with the auto adjust of height is already solve
but another problem exist as you can see in my sample if click the node that adjust the height its child overlap it.... we can use this jsfiddle for reference http://jsfiddle.net/elviz/Ge58Q/13/
also i need to cut my text if it exceed 120 characters the other will occupy the adjusted height of a node.....
this is how i adjust the height
nodeEnter.append("rect")
.attr("y", -barHeight / 2)
.attr("height", function(d){
if(d.name.length < 120){
return barHeight;
}else if(d.name.length > 120 ){
return barHeight * 2;
}
})
.attr("width", barWidth)
.style("fill", color)
.on("click", click);
It depends on how you want your text formatted inside the bar. I'll go for a naive way.
You want to make the bar larger, and the amount of extra height depends on how long your string actually is.
Find out what your max width for a bar is, and how many characters will fit into it. Add extra height (a multiple of your original height), depending on how much text you have.
Use overflow-wrap, like in this question to fit the text inside the div.
This is a little involved, so I hope the above gives you some ideas about how to fix your problem. I apologize in advance for not including code to solve it.

How does one get the height/width of an SVG group element?

I need to know the width and height of a SVG element? Im trying to use the following:
$('g#myGroup').height()
...but the result is always zero?
svg <g> elements don't have explicit height and width attributes, they auto size to whatever they contain. You can get their actual height/width by calling getBBox on the element though:
var height = document.getElementById("myGroup").getBBox().height;
If you're really into jquery you could write it as
$('g#myGroup').get(0).getBBox().height;
according to Reed Spool
I wasn't able to get any of the answers above to work, but did come across this solution for finding it with d3:
var height = d3.select('#myGroup').select('svg').node().getBBox().height;
var width = d3.select('#myGroup').select('svg').node().getBBox().width;
getBBox() here will find the actual width and height of the group element. Easy as that.
Based on the above answer, you can create jQuery functions .widthSVG() and .heightSVG()
/*
* .widthSVG(className)
* Get the current computed width for the first element in the set of matched SVG elements.
*/
$.fn.widthSVG = function(){
return ($(this).get(0)) ? $(this).get(0).getBBox().width : null;
};
/*
* .heightSVG(className)
* Get the current computed height for the first element in the set of matched SVG elements.
*/
$.fn.heightSVG = function(){
return ($(this).get(0)) ? $(this).get(0).getBBox().height : null;
};

Resources