I would like to determine if a widget is touching another widget, so far I have the following offset - Positions of widgets. However, this is a single point rather the a contained area.
Offset(48.8, 425.6) <- Box 1
Offset(70.0, 456.0) <-- Box 2
What is the best way to determine if Box 1 is near box 2 ( Box 2 would be scaled out by xx number to improve the matching )
I am using GlobalKeys to determine position like below
RenderBox box1 = box1Key.currentContext.findRenderObject();
Offset box1Pos = box1.localToGlobal(Offset.zero);
RenderBox box2 = box2Key.currentContext.findRenderObject();
Offset box2Pos = box2.localToGlobal(Offset.zero);
You could use the class Rect to define the boundings of one of your widgets and then use the method contains
https://api.flutter.dev/flutter/dart-ui/Rect/contains.html
The Rect class also has the method intersect which can be better suited for your question.
https://api.flutter.dev/flutter/dart-ui/Rect/intersect.html
Related
I've got a game object (InfoBox) with a..
Vertical Layout Group (Padding 20 on all sides, Control Child Size Height active)
an image
a Content Size Fitter (Vertical Fit set to Preferred Size, Horizontal Unconstrained)
Inside this InfoBox is a Text-Element and every time I update the text, I want the InfoBox to expand or collapse, but to the bottom only. Right now my InfoBox always expands or collapses to both top and bottom, but I don't want that to happen. How can I achieve that? I added some screenshots to better visualise this.
These are my settings for the InfoBox:
And these are my settings for the text:
And this is what happens when I use for example less text, the box collapses from bottom and top, but I want it to stay fixed at the top (on the same line as the green box next to it) and only collapse on the bottom:
Any help is really appreciate!
You main issues looks like you are using a ContentSizeFitter also on the parent object. So it depends how this parent object is aligned with its according parent.
This sentence sounds strange I know but what you did is basically shifting up the alignment responsibility to the parent.
=> Make your UI element aligned to the top and grow downwards.
All you need to do for this is either set
Anchors Min y -> 1
Anchors Max y -> 1
Pivot y -> 1
or simply go to the RectTransform Inspector, open the alignment tool and hold Shift + Alt and click on the top alignment:
For the second instead of using the ContentSizeFitter I prefer to have my own script that only does what it should and nothing more.
You can get the preferredHeight which is exactly the value you are looking for.
The following script simply always applies the preferred height to the text rect. Using [ExecuteAlways] this also works in edit mode. Simply attach it on the same GameObject as the UI.Text component
[ExecuteAlways]
[RequireComponent(typeof(Text))]
[RequireComponent(typeof(RectTransform))]
public class TextHeightFitter : MonoBehaviour
{
[SerializeField] private RectTransform _rectTransform;
[SerializeField] private Text _text;
private void Update()
{
if (!_text) _text = GetComponent<Text>();
if (!_rectTransform) _rectTransform = GetComponent<RectTransform>();
var desiredHeight = _text.preferredHeight;
var size = _rectTransform.sizeDelta;
size.y = desiredHeight;
_rectTransform.sizeDelta = size;
}
}
I'm using flutter
I'm having 2 widget A and B with position like photo above.
How can I move widget B overlay widget A when touch or swipe-up from widget B and back when swipe-down?
Make a GestureDetector and give it a stack as a child. Create a variable in your class thats called y or whatever name you want.
In your stack make 2 positioned widgets.
positioned(
top: 0
left: 0
),
positioned(
top: y
left: 0
)
make your two Widgets A and B childs of the positioned. Widget B has to be in the second positioned for it to overlay the first.
Make an AnimationController in your class and set its start value to 0 and its end value to the y. Use the onVerticalDragDownmethod of the GestureDetector to detect vertical swipes and check if it was from top to bottom or from bottom to top. If it was from bottom to top call animationController.reverse();, if it was from top to bottom call animationController.forward();. In the animationController Listener call setState((){y = animationController.value}). If you dont want it to be animated just set y to the values that you need.
Stack Learn about => https://api.flutter.dev/flutter/widgets/Stack-class.html
A widget that positions its children relative to the edges of its box.
This class is useful if you want to overlap several children in a
simple way, for example having some text and an image, overlaid with a
gradient and a button attached to the bottom.
I am trying to free text Annotation string align in center of rectangle but always set in top left corner
PdfContentByte pcb = stamper.getOverContent(page);
PdfAnnotation annotation = PdfAnnotation.createFreeText(stamper.getWriter(), rectangle, "Mayank Pandey", pcb);
annotation.put(PdfName.Q, new PdfNumber(PdfFormField.Element.ALIGN_MIDDLE));
Text showing left top corner in pdf:
You set
annotation.put(PdfName.Q, new PdfNumber(PdfFormField.Element.ALIGN_MIDDLE));
The constant Element.ALIGN_MIDDLE is defined as
/**
* A possible value for vertical alignment.
*/
public static final int ALIGN_MIDDLE = 5;
But the value of Q in free text annotations is specified as:
Q
integer
(Optional; PDF 1.4) A code specifying the form of quadding (justification) that shall be used in displaying the annotation’s text:
0 Left-justified
1 Centered
2 Right-justified
Default value: 0 (left-justified).
Thus, value 5 you used is not a valid Quadding value at all!
Furthermore, FreeText Quadding does not even support what you want to achieve, to align in center of rectangle, it only allows to select horizontal alignment, not vertical alignment.
For your objective, therefore, you'll have to use a custom appearance (which takes precedence if present).
My code
VerticalText vt = new VerticalText(writer.getDirectContent());
vt.setVerticalLayout(marginLeft + squareHeight, 1191.0f - marginTop, squareHeight, 3, 20);
vt.setAlignment(Element.ALIGN_CENTER);
Paragraph p = new Paragraph(imgr.getText(), fontV);
p.setLeading(10);
vt.addText(p);
vt.go();
The result : Text is middle in vertical mode.
I want to display text is center in horizontal mode as below link:
How to solve this problem ?
As documented, left, center and right align has a different meaning in the context of VerticalText. Left is top, center is middle and right is bottom.
With class VerticalText, you always write from right to left. There is currently no way to align the text as shown in the screen shot to the right.
However, you could work around this problem by adding the vertical text in simulation mode first and then calculate the number of lines that have been written.
See for instance the VerticalText1 example from my book. I have adapted the code of that example like this:
BaseFont bf = BaseFont.createFont(
"KozMinPro-Regular", "UniJIS-UCS2-V", BaseFont.NOT_EMBEDDED);
Font font = new Font(bf, 20);
VerticalText vt = new VerticalText(writer.getDirectContent());
vt.setVerticalLayout(390, 570, 540, 12, 30);
vt.addText(new Chunk(MOVIE, font));
vt.go();
System.out.println(vt.getMaxLines());
vt.addText(new Phrase(TEXT1, font));
vt.go();
System.out.println(vt.getMaxLines());
vt.setAlignment(Element.ALIGN_RIGHT);
vt.addText(new Phrase(TEXT2, font));
vt.go();
System.out.println(vt.getMaxLines());
The output of the System.out calls is:
11
4
1
These numbers are the number of lines that are available after each go().
We start with 12 lines as defined in the setVerticalLayout() method.
We add MOVIE and there are 11 lines left. We've defined a leading of 30, which means we've already consumed (12 - 11) x 30pt = 30pt.
Then we add TEXT1 which is distributed over 7 lines, which take 7 * 30pt in width. In total we now have consumed (12 - 4) x 30pt = 240pt.
Finally we add TEXT2 which is distributed over 3 lines. Only 1 line is left. The total horizontal width of all the text is 330pt (we had only 30pt left).
Now that you know this math, you can execute the go() method in simulation mode, calculate the width that was consumed and use that info to add your text for real at the desired position.
can someone please explain to me how FormData on FormLayout works? I'm trying to understand the FormAttachment constructors and its parameters (numerator, offset, denominator). When do you need only one of them, two of them or all of the parameters... Also, if i have a group (or a composite) which will add widgets like buttons and labels which will need to be resized as per resolution using FormData, does the Group need to have a FormLayout also? I tried specifying a width of a group with form layout but no change
FormAttachment has several different constructors, I generally use two typically:
new FormAttachment (int numerator, int offset) - If there's only two integer parameters then the first parameter represents the percentage from the edge of the parent. Which edge is determined by which slot in the FormData object you insert the FormAttachment into: FormData.top, data.bottom, data.left, and FormData.right.
new FormAttachment (Control control, int offset) - Instead of positioning the object against the parent, this positions the object next to another child object. This works in conjunction with the previous constructor so that you effectively "anchor" one element against the parent, then build your layout by positioning other elements relative to the anchor. This also allows you to easily move and insert elements into the overall layout without having to rebuild the entire layout.
The others are variations on the themes of these two. FormAttachment (int numerator, int denominator, int offset) is the same as the FormAttachment with two integer parameters, but with two the denominator just becomes "100", i.e. it turns the numerator into a percentage. But you could say something like (1, 2, 0) for 1/2 of the way across or (1, 3, 0) for 1/3 of the space.
I'm not sure what you mean about whether the Group will need to have a layout defined but in general every parent Composite must have a layout defined on it to display children elements. If you want elements to resize as the parent resizes, one option is to attach the child to both the left and right sides of the element:
FormData formData = new FormData();
formData.left = new FormAttachment (0, 0); // Attach at the 0% left with 0 offset
formData.right = new FormAttachment (100, 0); // Attach at the 100% right with 0 offset
The Eclipse site has a lot of good snippets showing FormLayout, check out:
http://www.eclipse.org/swt/snippets/
Scroll down to the FormLayout section.