How to make fixed width of column with Helvetica font? - c++

Usually, I use iomanip and setw to make a column with a fixed width for output.
But it seems to be that it doesn't work with Helvetica font.
What to do with it here?

Helvetica is a proportional font which means that the letters have different widths.
BTW, for most GUIs, you'll need something more specialized than std::cout.
In order to make a fixed width column you will need to pad to get to the next column. This means adding up the widths of the characters and the spacing. Subtract this from the column width and this becomes your padding.
Many GUIs have functions for determining the pixel widths of a string of text.
An easier route, IMHO, is to use a grid type widget in your GUI. These have column capabilities that can be adjusted. Some have functions that will resize a column based on its contents. You only need to put the text into that column.
Another GUI technique is to use vertical "boxes" (sizers) for each column. Place your text into the box. Let the box figure out its alignment and padding.

Related

Motif How to calculate or retrieve the font pixel size?

I am trying to write code in Motif to change a dialog warning box to resize size it if the box is not wide enough. The width and height is always being set by the calling classes and its not always wide enough for the message being displayed and the end of the line is truncated off. Instead of fixing everywhere to use auto sizing (i.e. width is 0 or not set at all) they want to figure out what the pixel width size is for a character in the dialog. They can then multiple the longest line X pixels width to get the lines length in pixels. Then we would see if the dialog declared width needs to be reset to stop the truncation. Only dialogs that are too short will be changed (dialogs too wide are not to be changed).
However; I can't find any example on how get the character width in pixels anywhere. I remember years ago I was on a project where they created some type of widget, inserted a character into it, and then did a XtGetValues to get the width and height so I think it can be done. So does anyone know how to do this?
That was a long time ago, but if memory serves, Xt doesn't have any specific support for fonts, it relies on plain libx11. You will need to call XQueryFont or XLoadQueryFont to get the XFontStruct describing your font, then grovel through the per_char array to find the extents of individual glyphs.

Remove Row Padding In QTableWidget?

After filling a QTableWidget table I call:
table->resizeRowsToContents();
This makes the rows narrower but there is still a lot of padding between each row, as you can see here:
Looking at the documentation I found I could set the hight of each row with:
table->verticalHeader()->setDefaultSectionSize(16);
This removes the padding and gives me the tight spacing I want:
However, I'm concerned about using an absolute size in pixels. If the the system font is set to something large the text might not fit in the row.
Is there a way to remove the padding between rows while ensuring the text will always fit?
Use a custom delegate with the QAbstractItemDelegate::sizeHint() method implemented in a way that it will return a correct size according to the font used.
To compute a correct height, you can use a QFontMetrics provided with the option parameter of the sizeHint() method.
int height = option.fontMetrics.height();
or more precisely
int height = option.fontMetrics.boundingRect(index.data().toString()).height();
EDIT: How to use a delegate:
CMyDelegate* delegate = new CMyDelegate(tableView);
tableView->setItemDelegate(delegate);

How to get correct position in the std::string?

I am creating a custom single line edit control, with a custom font in win32 api on windows 7, the font is not a fixed width font, and I need to move caret according to the mouse click, The edit control is not empty and if I know the horizontal position of the mouse click within the window, how do I calculate the number of characters after which I need to move caret to ?
I really am out of ideas, if it was a fixed width font, I would have divided the horizontal mouse click position with average character width, that would have been simpler, doing the same with not a fixed width font, is prone to errors.
Given that it's a single-line control, you probably don't plan on working with immensely long input (at least normally). That being the case, one possibility would be to just store the character positions in an array (or vector, etc.) Then you can use (for example) a binary search in that array to find character positions. Of course, you can do the same even for longer strings--though it can increase storage requirements quite a bit.
This is a familiar problem. You are in essence trying to do hit testing on text and for that you need the location on the screen of each character of the text.
My preferred strategy is to calculate an array of RECT, one for each character of displayed text. The array needs to be updated when text is added or deleted, but it easily handles single or multiple lines. The function GetCharWidth32 retrieves all the widths for a string of text in a particular font selected into a DC. For single line one call is enough, and calculating the array of RECTs is simple. It's not much harder to do multiline.
Handle the mouse down message, loop through the array and find the right character. A brute force search is plenty fast enough.
This method is simple and easily generalises to a range of similar problems.

How to provide a custom column width calculation for CListCtrl?

I'm using a CListCtrl with my own "DrawItem" to draw some custom graphics into the first column, in front of the text. The text is moved ~20 pixels to the right for this. That part works.
If the user double-clicks the column divider in the header, Windows calculates the best column width. But of course Windows doesn't know my custom drawing. So the result is ~20 pixels too small for the first column.
How can I correct that?
Found a workaround:
I can trick MFC into thinking that the list control uses checkboxes:
pMyList->SetExtendedStyle(pMyList->GetExtendedStyle() | LVS_EX_CHECKBOXES);
The user will never ever see the system's checkboxes (because of my custom drawing), but this gives me just the space that I need.

How to set minimum width for the first column of the QFormLayout?

How to set minimum width for the first column of the QFormLayout? I can do it for QGridLayout by using QGridLayout::setColumnMinimumWidth(int, int), but cannot find a method to do that for QFormLayout.
It's pretty simple to do. Just set a minimum width on any of the widgets that you've inserted into the first column.
How to set minimum width for the first column of the QFormLayout?
You cannot (off-hand). It was not designed for that as this sounds more like a QGridLayout feature. You could either refactor your design to use QGridLayout, or you could potentially set the size for the rows as you wish, but you would execute that on the row content rather than the layout itself.