Create responsive Qooxdoo HBox layout where widgets don't show without enough space - qooxdoo

How can I create with Qooxdoo a user resizeable Window where the content is made out of a few widgets (e.g. Labels) where the display of some is disabled when the space isn't enough?
Example:
I have the three labels "unimportant" (right aligned), "very important" (left aligned) and "must have" (right) in the HBox. Any extra space should go just right of the left most label to keep the alignment requirements.
In ASCII art this would look like:
--------------------------------------------------------
|very important| |unimportant|must have|
--------------------------------------------------------
-----------------------------------------------
|very important| |unimportant|must have|
-----------------------------------------------
--------------------------------------
|very important|unimportant|must have|
--------------------------------------
-------------------------------
|very important| |must have|
-------------------------------
<-- making the window smaller
--------------------------
|very important|must have|
--------------------------
-------------------
| |must have|
-------------------
-----------
|must have|
-----------
The minimal width of the Window would be the space that "must have" requires.
Bonus question: the "unimportant" would actually be a label for "must have" which can be a widget that takes more vertical space. So both should be centered to each other, something that an Atom with those two might be normally used for.

Don't like implementation but it does work as intended:
const mainBar = new qx.ui.container.Composite(new qx.ui.layout.HBox());
// sub bar for right and center labels
const subBar = new qx.ui.container.Composite(new qx.ui.layout.HBox());
subBar.setMinWidth(0);// this line is important
// left static label
const left = new qx.ui.basic.Atom("very important");
subBar.add(left);
// center label has a minor priority
const center = new qx.ui.container.Composite(new qx.ui.layout.HBox());
const dummy = new qx.ui.basic.Atom();
center.add(dummy, {flex: 1});
const centerLabel = new qx.ui.basic.Atom("unimportant");
center.add(centerLabel);
subBar.add(center, {flex: 1});
mainBar.add(subBar, {flex: 1});
const right = new qx.ui.form.Button("must have");
mainBar.add(right);
const win = new qx.ui.window.Window().set({width: 600, height: 100});
win.setLayout(new qx.ui.layout.Grow());
win.add(mainBar);
win.setUseResizeFrame(false);
win.open();
const defaultLeftWidth = left.getSizeHint().width;
const defaultCenterWidth = center.getSizeHint().width;
win.addListener("resize", function(){
this.info(center.getBounds().width, defaultCenterWidth);
if (center.getBounds().width <= defaultCenterWidth){
centerLabel.setVisibility("hidden");
} else {
centerLabel.setVisibility("visible");
}
if (subBar.getBounds().width < defaultLeftWidth){
left.setVisibility("hidden");
} else {
left.setVisibility("visible");
}
}, this);
// Document is the application root
const doc = this.getRoot();
// Add button to document at fixed coordinates
doc.add(win,
{
left : 100,
top : 50
});

Related

Making a form goto a random position and staying within the screen size - Windows forms

Hi I'm making a subliminal message program where I have a form that appears then disappears very quickly.
I am now trying to figure out how I can make it so each time it pops up, that it's in a random location but most importantly what I'm struggling with is making it so it stays within the borders of someone's screen size.
I have been struggling to find the relevant code and also seen something about using Width to set the control but I can't find out what is meant by the control either.
Hoping to be pointed in the right direction
Thanks.
If you want to set the form size programmatically, set the form's StartPosition property to Manual.
You can get the screen size with
Rectangle screen = Screen.PrimaryScreen.WorkingArea;
You also need a Random object. Make sure to only create it once, e.g. by making it static and read-only.
private static readonly Random _random = new Random();
Now you can get random positions and open the form with
var frm = new MySubliminalForm();
int x = _random.Next(screen.Width - frm.Width); // range [0 .. screen width - form width].
int y = _random.Next(screen.Height - frm.Height); // range [0 .. screen height - form height].
frm.Location = new Point(x, y);
frm.Show();
This shows the screen (big rectangle) and the window (small rectangle) at its maximum position. As you can see, the window's X-position is the screen width minus the window width and the Y-position is the screen height minus the window height.
+------------------screen width------------+
| : |
| : |
| screen : |
| y = Hscr - Hwin |
| : |
| V |
| .....x = Wscr - Wwin ...> o-window width-+
| | |
| | window |
| | |
+---------------------------+--------------+

Dynamically generated FlowLayoutPanel, has different output

I'm trying to dynamically generate 2 FlowLayoutPanels with a couple of buttons.
private void DrawButtons() {
tlpButtons.Controls.Clear();
foreach (var type in Globals.ThisAddIn.TicketTypes.OrderBy(x => x.Name)) {
tlpButtons.Controls.Add(new Label() { Text = type.Name, Dock = DockStyle.Fill });
var container = new FlowLayoutPanel() { Dock = DockStyle.Fill, AutoSize = true, AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly, BackColor = Color.Yellow, FlowDirection = FlowDirection.LeftToRight };
foreach (var skill in Globals.ThisAddIn.Skills.OrderBy(x => x.Name)) {
container.Controls.Add(new Button() { Text = skill.Name });
MessageBox.Show(tlpButtons.RowCount.ToString());
}
tlpButtons.Controls.Add(container);
}
}
This is what it outputs:
Let me explain what you're seeing.
I have TableLayoutPanel tlpOuter (pink) with 1 column (100%) and 2 rows. Row 1: AutoSize, Row 2: 100%
In the first row I have another TableLayoutPanel tplButtons (orange) with 1 column (100%) and 1 row (AutoSize, GrowStyle: Rows)
Now I can't figure out why the 2nd FlowLayoutPanel (yellow) is so large. It shouldn't be. It is exactly the same as the first panel (it's in a foreach) and yet, it adds all this whitespace (yellowspace).
What I found, when debugging line-by-line, is that the second panel grows as the buttons are added (as if it thinks they get a new line instead being placed side-side if it can) while it does not do that while adding the buttons to the first panel.
UPDATE:
So I removed the docking from the flowLayoutPanels and I can now see the problem is actually the TableLayoutPanel tlpButtons!
From what I can gather, it is sizing the Table as if the controls inside had no docking. Look:
So the question remains, why does this TableLayoutPanel not account for the docking of the FLP's?

How can I add text to a Checkbox I create using iTextSharp?

Derived from Jeff S's methodology found here, I can add a "Checkbox" to a PDF page like so:
PdfPTable tblFirstRow = new PdfPTable(5);
tblFirstRow.SpacingBefore = 4f;
tblFirstRow.HorizontalAlignment = Element.ALIGN_LEFT;
. . . // code where textboxes are added has been elided for brevity
PdfPCell cell204Submitted = new PdfPCell()
{
CellEvent = new DynamicCheckbox("checkbox204Submitted", "204 Submitted or on file")
};
tblFirstRow.AddCell(cell204Submitted);
doc.Add(tblFirstRow);
The DynamicCheckbox class, based on Jeff S's CustomCellLayout class, is:
public class DynamicCheckbox : IPdfPCellEvent
{
private string fieldname;
private string cap;
public DynamicCheckbox(string name, String caption)
{
fieldname = name;
cap = caption;
}
public void CellLayout(PdfPCell cell, Rectangle rectangle, PdfContentByte[] canvases)
{
PdfWriter writer = canvases[0].PdfWriter;
RadioCheckField ckbx = new RadioCheckField(writer, rectangle, fieldname, "Yes");
ckbx.CheckType = RadioCheckField.TYPE_CHECK;
ckbx.Text = cap;
PdfFormField field = ckbx.CheckField;
writer.AddAnnotation(field);
}
}
My problem is that the checkbox's text (the string assigned to ckbx.Text) is not displaying. The checkbox (outsized) occupies the last cell in the table row, but there is no (visible) accompanying text.
What's missing from my code?
Note: I tried to reduce the size of the checkbox by doing this:
Rectangle tangle = new Rectangle(20, 20);
//RadioCheckField ckbx = new RadioCheckField(writer, rectangle, fieldname, "Yes");
RadioCheckField ckbx = new RadioCheckField(writer, tangle, fieldname, "Yes");
...but that attempt failed - with that code, I can't even "find" the checkbox in the generated PDF file - clicking willy-nilly in column 5 conjures up no checkbox...
Others have answered the label part. The Rectangle that you have called "tangle" needs to be calculated off of the rectangle that comes into the event handler, similar to
Rectangle tangle = new Rectangle(
rectangle.Left,
rectangle.Top - PDFStyle.boxsize - 4.5f,
rectangle.Left + PDFStyle.boxsize,
rectangle.Top - 4.5f
);
Where PDFStyle.boxsize is the width/height of the checkbox and 4.5f is the padding the edge of the cell. Basically the rectangle isn't relative to the cell, but absolute to the page.
As described in ISO-32000-1, a check box is a field of type Button. If you define text for a button, you want to define the text that is displayed on the button. However: in the case of a check box, there is no such text! Instead, you have two appearances, one for the Off value and one for the Yes value.
An educated guess made by an attentive reader would be that you don't want to add text (to the button), but that you want to add a label (for a checkbox). Again you should consult ISO-32000-1 and you'll discover that the spec doesn't say anything about labels for check boxes. The concept just doesn't exist at the level of an AcroForm.
This doesn't mean the concept doesn't exist in general. Many PDF tools allow you to define check boxes that are preceded by a label. When you look inside the PDF, you'll discover that this label is just part of the content, whereas the check box is represented by a widget orientation.
Let's take a look at the official documentation instead of frustrating ourselves searching on every place of the web except on the official web site. More specifically: let's take a look at the Buttons example from Chapter 7 of my book. You'll see that one can set text for a real button:
PushbuttonField button = new PushbuttonField(writer, rect, "Buttons");
button.setText("Push me");
This isn't possible with check boxes (for the obvious reason that the appearance of a check box is completely different). If we want to add a label, we can add it for instance like this:
checkbox = new RadioCheckField(writer, rect, LANGUAGES[i], "Yes");
field = checkbox.getCheckField();
field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", onOff[0]);
field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Yes", onOff[1]);
writer.addAnnotation(field);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT,
new Phrase(LANGUAGES[i], font), 210, 790 - i * 40, 0);
You can find the C# version of these examples here: http://tinyurl.com/itextsharpIIA2C07
Creating a checkbox, and then accompanying text to its right, can be done like this:
PdfPCell cell204Submitted = new PdfPCell()
{
CellEvent = new DynamicCheckbox("checkbox204Submitted")
};
tblFirstRow.AddCell(cell204Submitted);
// . . . Chunks and an anchor created; that code has been elided for brevity
Paragraph parCkbxText = new Paragraph();
parCkbxText.Add(Chunk204SubmittedPreamble);
parCkbxText.Add(ChunkBoldNote);
parCkbxText.Add(Chunk204Midsection);
parCkbxText.Add(anchorPayeeSetup204);
PdfPCell cellCkbxText = new PdfPCell(parCkbxText);
cellCkbxText.BorderWidth = PdfPCell.NO_BORDER;
tblFirstRow.AddCell(cellCkbxText);
public class DynamicCheckbox : IPdfPCellEvent
{
private string fieldname;
public DynamicCheckbox(string name)
{
fieldname = name;
}
public void CellLayout(PdfPCell cell, Rectangle rectangle, PdfContentByte[] canvases)
{
PdfWriter writer = canvases[0].PdfWriter;
RadioCheckField ckbx = new RadioCheckField(writer, rectangle, fieldname, "Yes");
ckbx.CheckType = RadioCheckField.TYPE_CHECK;
ckbx.BackgroundColor = BaseColor.ORANGE;
ckbx.FontSize = 6;
ckbx.TextColor = BaseColor.WHITE;
PdfFormField field = ckbx.CheckField;
writer.AddAnnotation(field);
}
}

How can I exchange the Extjs panel contents?

In my application there are two panels -A and B.
I am using "border" layout, the panel A is in center region and panel B is in south region which have height 200.
The "panel A" have lot of items like grid, toolbar etc. also "panel B" have some items.
My question is, How can I exchange the contents of A to B and B to A.
Note: I am using "Extjs 3.2"
Regards,
Mohammed Shafeek
Panels in center and south region of border layout have to be wrapped by container component. Then you can easily get content of each container, clear the container and add to it content from second container.
So function for switch panels should looks like this:
function switchPanels() {
southContainer = Ext.getCmp('southContainer');
centerContainer = Ext.getCmp('centerContainer');
southContainerItems = southContainer.items.getRange();
centerContainerItems = centerContainer.items.getRange();
southContainer.removeAll(false);
centerContainer.removeAll(false);
for (var i = 0; i < southContainerItems.length; i++) {
centerContainer.add(southContainerItems[i]);
};
for (var i = 0; i < centerContainerItems.length; i++) {
southContainer.add(centerContainerItems[i]);
};
centerContainer.doLayout();
southContainer.doLayout();
}
For complete live example look at this fiddle: https://fiddle.sencha.com/#fiddle/2iv

Windows Phone 7 overflow clipping

I have a grid within a grid and i want the content of the second to move about without encroaching on the first grid.
Much like the panorama view but can move left or right as well as up and down.
I can get this working but unfortunately when you move down the top overflows into the outer grid overlapping any controls within it.
Is there a way to hide the overflow almost like CSS overflow:hidden?
Any help would be really appropriated.
Thank you
Andrew
Possible solution:
var gridWidth = (this.tilesize * (this.gridSize - 1)) / 2;
var top = -(((-offsetY + tileY) * this.tilesize) - gridWidth);
var left = -(((-offsetX + tileX) * this.tilesize) - gridWidth);
this.Container.Margin = new Thickness(left, top, 0, 0);
var clipSection = new RectangleGeometry();
clipSection.Rect = new Rect(-1 * left, -1 * top, 480, 400);
this.Container.Clip = clipSection;
this.Container.Dispatcher.BeginInvoke(new ThreadStart(delegate
{
this.Container.Clip = clipSection;
}));
You could do this by putting something in the cells of the "outer" grid and seeing a higher ZIndex than the elements you are moving around. The elements with the higher ZIndex appear above the lower ones.

Resources