When using setInputMask the text-cursor width changes. Due to that I can't place the cursor between two characters but it selects the whole character.
Is there a way to bypass this behaviour?
Related
I've got this sfml window that displays a text and now I want to make it markable so that you can copy the text.
Any ideas how to do that?
If you just want to copy everything then just use
sf::Clipboard::setString(your_string_here);
If you want more features, here are some I implemented when I programmed a Code Editor in SFML.
I stored two indexes, the first is where the selection begins, and the second is where the section ends.
So in the string Hello World!, if you wanted to select World you would set the begin index to 6, and the end index to 10 or 11 (depending on whether you include the final character or not).
I render this using an sf::RectangleShape, since my editor supported multiple line selection boxes the code is more complicated, but for your example you would want to get the position of each character. I used my own text renderer, but SFML's sf::Text::findCharacterPos() should be able to help with that.
Next the copy part, this is just
sf::Clipboard::setString(getSelected());
where getSelected() is
return std::string::substr(selection_begin, selection_end - selection_begin);
If you want pasting as well then it is also simple:
eraseSelected();
insertStringAtCursor(sf::Clipboard::getString());
Which are both simple string operations as well (std::string::erase and reset the selection indexes, and std::string::insert).
Finally, to let the user change what is selected, either holding shift and pressing the arrow keys or clicking and dragging are both common ways, the former being easier than the latter.
For the former, check if shift is held and then if left or right is pressed update the indexes.
For the latter, you will need to handle mouse events and dragging. When dragging begins, set one of the indexes, whilst the mouse is moving and is dragging set the other index.
QPainterPath can paint outline for the text
QPainter can draw multiline text
Is there any solution to make use of both of those features?
I also looked up for QLabel styles, and still didn't find anything outline-related.
Unfortunately, no such function exists in (at least, in Qt 5.15). What I did was wrote a function that takes a string and breaks it up into multiple lines, breaking on spaces or \r or \n. Loop over the string one word at a time, measuring it 'till it gets bigger than desired width (or you hit a line break), then back up one word, trunc any space, and call that one line. stick that into your vector of lines. repeat for each line. then in a separate function, you can draw each line one at a time, using stroke/fill from QPainterPath technique, advancing vertically by metrics.height() each line
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.
I am trying to make a program where I can use the arrow keys or the WASD keys to move a character across the screen (rpg style). I dont have any clue how to redraw the board in an easy way since there would be so many possible positions. I was thinking about creating a 2d array which would hold the positions. I am not asking for you all to write the code, I am asking simply. Is it possible to make the text character move along positions across the array?
One way would be to clear the "screen" and redraw the "map" at every change. Another might be to only redraw the lines that have changed. Yet another might be to position the cursor after the character you want to "move", print a backspace followed by e.g. a space, then reposition the cursor to after where you want the new character to be, print another backspace and then the character.
Or simply use a library such as ncurses.
On Windows, you can use the SetConsoleCursorPosition function to move the cursor to any arbitrary XY coordinates that you like.
TO do this, you need a HANDLE to the console, which is fairly easy to get
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
More Windows Console functions.
See here for an example
I am using SDL and libfreetype and constructing a very basic GUI, I'm implementing a textBox, but I haven't been able to figure out how I'm supposed to generate the standard blinking cursor part. It doesn't seem to be exactly the same as a | character. And moreover if I draw it as a | character that changes the text width.
What's the canonically correct way to render text in a textbox with a cursor?
The easiest way is to just draw a line primitive, this gives you a lot more control over the spacing, length and width of the caret.
And if you want to keep it as a text character in your font system, you can do a render-to-texture and copy it out, or do a simple memory blit onto your font atlas (so you can can keep pipe character separate, an use a control char like 0x01 for the caret).