I'm creating a simple chat client and server and I'm having some issues with how sf::Text is rendered. Say in the chat history for example. When users type their messages, the old messages will be pushed up. Eventually the message hits the top and I'll want to only display the part of the message that is still within the chat history. This is where I'm lost.
The element containing the text has two visible objects - sf::RectangleShape (the background for the text) and a sf::Text. I can easily adjust the size of the shape once it hits the top so it's not visible outside the chat history, but I can't adjust the size of the text without distorting the contents. Changing the character size obviously isn't ideal either.
What I want is to cut the text in half horizontally if half of the text is outside the chat history. My first thought was to mask it somehow but it seems like SFML has no support for that.
The reason I'm mentioning sf::Texture in the title as well is because I've had the same issue with that in the past. I just couldn't find a way to cut off parts of it, I only managed to distort it.
Is this possible at all in SFML?
One way of doing this is to draw the chat history to a sf::RenderTexture, which is the tool used for off-screen rendering.
Once you've drawn the chat history to your render texture, you can draw the texture on to the screen.
So if you place text that is half on the render texture and half outside, only the part that actually fits on there will be drawn.
Be aware though that render_texture are fairly expensive to construct, so you you want to re-use them and not create new ones all the time.
Related
For university, we need to make a game in Unity that is controlled with an Arduino. My idea was a hacking game where the Arduino acts as the 'hacking device' when hacking something in the game. The arduino would have a screen and on that screen would be a basic command-line interface that lets me input simple commands to 'hack' but I've been having trouble regarding text and clearing it.
I've been able to use unity to send typed characters to the display as-well as a backspace function (pressing backspace would remove last character in the string)
I first had issue with clearing all the text when writing (calling tft.print doesn't clear any previous text). I was using fillScreen which was slow. I found out setTextColor had a second argument that let me just set all certain colored text to a different color. Setting it to black would essentially clear it.
This made it update pretty much instantly when writing to the screen but I now had a new issue, backspace would no longer would.
My understand is that when removing the character, it's color won't be updated when calling setTextColor leaving it on the screen until a restart/fillScreen is called.
I'm not really sure how to solve this and all google searches turn up little to no help.
Here's my code for updating the text:
void updateString(char c){
tft.setTextColor(WHITE,BLACK);
if(c!='<'){
//Add new character to end of string
str.concat(String(c));
}
else if(c=='<' && str.length()>2){
//Remove last character in string
str.remove(str.length()-1);
}
//Set cursor back to 0,0
tft.setCursor(0,0);
//Display text
tft.print(str);
}
I'd appreciate any help.
Maybe, use a similar function to tft.clear() each time you refresh the screen or you can draw a filled square of the background on the text so it looks like it has been erased then you rewrite the text.
Sounds like you are using proportionally-spaced fonts instead of the original classic fonts that ships with Adafruit_GFX. Historically, when using the default classic fonts one could set the background color option of the text to the same color as the background of the screen (usually black). This would overwrite the old screen contents with new data and work because the characters using the classic fonts are a uniform size. When using proportionally-spaced fonts, the background color option for the font is disabled by design.
This was presumably because of memory requirements and speed on slower AVR's. Regardless, when using proportionally-spaced fonts the background color feature won't work due to non-uniform sized characters overlapping the same regions as adjacent characters.
There are two work-arounds to this. Adafruit says in order to replace previously drawn text when using custom fonts you can either:
Use getTextBounds() to determine the smallest rectangle that encloses a
string and then erase that area using fillRect() prior to drawing
the new text. OR
Create an offscreen bitmap using GFXcanvas1 for a fixed size area,
draw the text in the GFXcanvas1 object and then copy to the screen
using drawBitmap().
Note that options 1 & 2 above are mutually exclusive. The second method requires more memory. The first method isn't perfect and produces some small amount of flicker, but is in general acceptable if coded carefully.
I hope that I have understood what the nature of your problem is and answered it in a satisfactory manner. If nothing else, at least now you know why custom font's will not work with the so called background color feature that works with the original 'classic' Adafruit fonts.
Nikki Cooper
I am building an editor using C++/Qt which has a click-and-drag feel to it. The behavour is similar to schematic editors (Eagle, KiCAD, etc), Microsoft Visio, or other programs where you drag objects from a toolbar into a central editing area.
My problem is that when the user clicks inside the custom widget I want to be able to select the instance of the box-like object and manipulate it. There will also be lines connecting the boxes together. However, I can't decide on an efficient method for selecting those objects.
I have two main thoughts on how to do the programming for this: The first is that the widget which is drawing the entire editor would simply encapsulate every one of the instances of the box. The other is to have each instance of the box (which is in my Model) carry with it an instance of a QWidget which would handle rendering the box (which would be in my View...but it would end up being strongly attached to the model). As for the lines connecting them, since they don't have a square bounding boxes they will have to be rendered by the containing widget.
So here is the summary of how I see this being done:
The editor widget turns into a container which holds the widgets and the widgets process their own click events. The potential issues here are that I don't know how to make the custom widget turn into a layout which lets click-and-drag functionality.
The editor widget takes care of all the rendering and processes the mouse clicks (the easier way in that I don't have to worry about layout...its just selecting the instances efficiently that I don't know what would be best).
So, now that there is a bit of background, for the 2nd method I plan on having each box-like instance having a bounding rectangle and the lines being represented by 3-4 pixel wide bounding rectangle segments (they are at 90 degree angles). I could iterate through every single box and line, but that seems really inefficient.
The big question: Is there some sort of data structure I can hold rectangles in and link them to widgets (or anything else for that matter) and then give it two coordinates (such as mouse coordinates) and have it spit me out the bounding box or linked object that those coordinates are inside of?
It sounds like your real question is about finding a good way to implement your editor, not the specifics of rectangle intersection performance.
You may be interested in Qt's "Diagram Scene" example project, which demonstrates the QGraphicsScene API. It sounds like a good fit for the scenario you describe. (The full source for the example ships with Qt.)
The best part is that you still don't have to implement hit testing yourself, because the API already provides what you are looking for (e.g., QGraphicsScene::itemAt()).
It's worth noting that internally, QGraphicsScene uses a simple iterative method to perform hit tests. As others have pointed out, this isn't going to be a serious bottleneck unless your scenes have a lot of individual items.
I am sorry for the terrible description of this question. I am making a game where the user has to try and through a football through a moving tire. I have the game set up with a single scene & layer and I am wondering how to implement options for having different background images, tires, and footballs to choose from. I don't expect someone to explain to me how to code my game. I want to have specific objects for the different background images. Like, for instance, a prison background image would have a metal tire, different football, and have certain objects be flying through the scene while attempting to throw the football through the tire. Should I create a separate scene & layer for each background image & its corresponding sprites or is there a better way to go about this. All I am asking is for someone to point me to some example code or a project that does something similar. SORRY for the long post
If you are willing to keep everything in just one png (background + moving sprites) and use a CCSpriteBatchNode you can easily keep the rects of the elements equal for all the different settings and just load a different file.
Otherwise just have a set of files and use same CGRect, it shouldn't be hard at all..
I have to design a GUI using Qt. I would like to draw multiple lines depicting relationships between two objects. It's the same idea as matching a word with a definition by drawing a straight line (which might be a diagonal) between the two.
In my case it is an a label (with image inside of it) that needs to be matched with another label.
So we have something like this - http://dl.dropbox.com/u/46437808/DrawLines.png
And I want to add lines to make it look something like this http://dl.dropbox.com/u/46437808/DrawLines2.png
I need to do this in run time because the relationship will be changing based on different factors.
Thanks!
Do you need interaction or is this just an image that the user needs to see based on other information? If it's just a static image, I would simply draw it onto a QImage and show it. That way you have complete control over how things are drawn. So you can either cache the relationship diagrams you need ahead of time, or just draw them on the fly onto the QImage based on the relationship that needs to be displayed at the time. You can look at Qt's painting example for some ideas on how to accomplish what you need.
If you need interactivity, I would probably go with the Graphics View Framework. This way if you need push buttons, check boxes, etc. for any reason you can use the QGraphicsProxyWidget to get them, or you can just make your own from QGraphicsItem subclasses.
This is related to one of my other questions.
If I am tiling a large image by creating a separate QGraphicsItem (with the raster data as its pixmap), how do I keep track of the QGraphicsItem's position within the scene? Obviously for raster data, it is important to keep all the tiles "touching" to make a continuous image and they also have to be in the right place so the image doesnt look jumbled.
Does each tile have to have positioning methods that move it in relation to it's neighbors on the top/left/bottom/right? This seems kind of clunky. Is there a better way to make them all move together?
In other words, if I pan the scene with scroll bars, or pick up the image and drag/move it around in the scene, I want all the tiles to also move and stay in the right position relative to each other.
What is the best approach for controlling the layout, which tiles need to be rendered (i.e. only the visible ones), and populating the data only once it is needed? Also, once a tile has been rendered, is the data from it ever dropped, and repopulated from the image file, say if it stays out of view for a while, then comes back later if someone pans to that section?
There are (more than) 2 ways of doing this:
Use QGraphicsItemGroup which
handles grouping of your tile items
for you. It moves, selects, updates
it's group members as if they are
one. I've never used it but from the
doc, it seems to work with typical
applications.
Paint the tiles yourself in the
paint() of one custom item. This
gives you total control on how to
place and draw the tiles while the
item truly acts as one item since it
is, well, one item. This is what I
do.