Hey I can't find an answer to this anywhere. I want to change my menuItemLabel's font colour when touched. By default it scales and animates to be bigger when you first touch it, but how to customize it more? Here is my label and menuitem:
//add options label
optionsLabelSettings = Label::createWithTTF("OPTIONS", "fonts/font1.ttf", 140);
optionsLabelSettings->setColor(Color3B(255,255,255));
auto optionsItem = MenuItemLabel::create(optionsLabelSettings, CC_CALLBACK_1(MainMenuScene::GoToOptionsScene, this));
optionsItem->setPosition( Point (visibleSize.width/2 + origin.x, visibleSize.height /2));
//add menu
auto menu = Menu::create(optionsItem, NULL);
menu->setPosition( Point(0,0));
this->addChild(menu);
If you want to change font color, you can insert such method in your handler:
void MainMenuScene::GoToOptionsScene(parameters)
{
optionsItem->getLabel()->setColor(Color3B::BLACK); // or any other color
… // your method of switching to another scene
}
If you switch to another scene after pressing, it will be ok.
But if you plan to stay on the current scene, this method is not suitable, because you can’t to restore the font color back. In this case better way is using MenuItemImage and creating images for normal and selected states:
MenuItemImage *optionsItem = MenuItemImage::create(«normalImage.png», «selectedImage.png», CC_CALLBACK_1(MainMenuScene::GoToOptionsScene, this));
Or using ui::Button, if you haven’t images:
ui::Button* optionsItem = ui::Button::create();
optionsItem->setPosition(…);
optionsItem->setTitleText(«OPTIONS»);
optionsItem->setTitleFontName("fonts/font1.ttf");
optionsItem->setTitleFontSize(140);
optionsItem->setTitleColor(Color3B::WHITE);
optionsItem->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
switch (type)
{
case ui::Widget::TouchEventType::BEGAN:
this->startPressingGoToOptionsScene();
break;
case ui::Widget::TouchEventType::ENDED:
this->finishPressingGoToOptionsScene();
break;
default:
break;
}
});
this->addChild(optionsItem);
and then in each handler set different button behavior:
void MainMenuScene::startPressingGoToOptionsScene(parameters)
{
optionsItem->setTitleColor(Color3B::BLACK);
optionsItem->setTitleText(«…») // change anything else
…
}
void MainMenuScene::finishPressingGoToOptionsScene(parameters)
{
optionsItem->setTitleColor(Color3B::WHITE); // return original font color and other changes
…
}
customise your MenuItemLabel class & Implement following two methods :-
class ChangedMenuItemLabel : MenuItemLabel
{
bool ChangedMenuItemLabel::initWithLabel(cocos2d::Node *label, const ccMenuCallback &callback)
{
if (!MenuItemLabel::initWithLabel(label,callback)) {
return false;
}
return true;
}
void selected(){
this->setColor("your color");
}
void unselected(){
this->setColor("your color");//or nothing
}
}
Related
So I'm trying to scale an Image to fully fit a label from top to bottom. The problem is the outputs from the labels width, and height is not pixel values so I'm not sure how to correctly go about this. Here's my code.
void MainWindow::drawPixmap()
{
int labelWidth = ui->picLabel->width();
int labelHeight = ui->picLabel->height();
if(labelWidth <= labelHeight){
pixMap = this->pixMap.scaledToWidth(labelWidth);
ui->picLabel->setPixmap(pixMap);
}
else{
pixMap = this->pixMap.scaledToHeight(labelHeight);
ui->picLabel->setPixmap(pixMap);
}
}
Here's a visual of my problem, the black box is a border around the label box. I'm trying to get the image in the center to have its top and bottom touch the black box on respective sides.
Thanks for any help!
The problem could be when you calling this function. If you have called this function prior to making the label visible, then the size of the label could be incorrect after the label becomes visible.
Also, think about what happens when the label resize (if ever). You will still have to update the size of pixmap.
If your label is never going to change size, try calling it after the label has become visible.
Alternatively, try setting QLabel::setScaledContents(true)
If both the above doesn't work, try installing an eventFilter on the label to get the label's size change event, in there, you could do your above code
MainWindow::MainWindow()
{
....
ui->picLabel->installEventFilter(this);
}
bool MainWindow::eventFilter(QObject* object, QEvent* event)
{
bool res = Base::eventFilter(object, event);
if (object == ui->picLabel && event->type() == QEvent::Resize)
{
int labelWidth = ui->picLabel->width();
int labelHeight = ui->picLabel->height();
if(labelWidth <= labelHeight){
pixMap = this->pixMap.scaledToWidth(labelWidth);
ui->picLabel->setPixmap(pixMap);
}
else{
pixMap = this->pixMap.scaledToHeight(labelHeight);
ui->picLabel->setPixmap(pixMap);
}
}
return res;
}
I build up a ruse of CustomWidgets in a QListWidget. So far, it works well.
A problem occurs when I move the vertical scroll bar downwards and want to display items that were not previously visible.
Then they are inserted as transparent rectangles, I can click them and respond to the clicks, but they are not drawn. They stay transparent!
I insert a picture to get a rough idea of the problem:
In my QListWidget I try to repaint it, but it doesn't work:
QListWidget::verticalScrollbarValueChanged(value);
auto item = this->itemAt(QPoint(24, value));
if (!item)
{
return;
}
auto widget = this->itemWidget(item);
if (!widget)
{
return;
}
// widget->resize(widget->size());
// widget->repaint();
widget->update();
What can I do? Thanks for help!
EDIT:
According to the request of Martin, I insert here a routine, which shows the addition of items:
void ListControl::AddCustomWidget(QWidget* customWidget, const QSize& size, bool forceSize)
{
if (forceSize)
{
customWidget->adjustSize();
}
auto displaySize = customWidget->size();
auto width = size.width();
auto height = size.height();
auto item = new QListWidgetItem(this);
this->addItem(item);
if (width >= 0)
{
displaySize.setWidth(width);
}
else
{
displaySize.setWidth(displaySize.width() - (this->verticalScrollBar()->width() + this->rightSpace));
}
if (height >= 0)
{
displaySize.setHeight(height);
}
item->setSizeHint(displaySize);
this->setItemWidget(item, customWidget);
}
I have a diamond-sprite and I want to be able to change the colour of the diamond from white, it's original colour to green. However, I can not figure out how to do this.
public class MoveControl : MonoBehaviour {
// Update is called once per frame
void Update () {
if (Input.GetKey(KeyCode.A) )
{
if (GetComponent<Renderer>().material.color == Color.white)
{
GetComponent<Renderer>().material.color = Color.green;
}
}
}
}
This above code is what I have right now and it only works if the material applied to the sprite, being white, is a sprites/default shader. This may not sound like a big problem but whenever I apply a different material of a different colour, such as blue, and change its settings so it has a sprites/default shader, the sprite becomes invisible.
I'm new at Unity and if someone could help me out, it would be very much appreciated
I'm not sure what you're trying to do but this may help you.
public class Material : MonoBehaviour {
Renderer renderer;
Color currentColor;
Color originalColor;
// Use this for initialization
void Start () {
renderer = gameObject.GetComponent<Renderer>(); //If you don't know the gameObject is the object this script is attached to
originalColor = renderer.material.color; //The original color ( in your case white )
}
// Update is called once per frame
void Update () {
if (Input.GetKey(KeyCode.A)) {
if (renderer.material.color == originalColor) { //Here we are checking if the color on the object is the original color
renderer.material.color = Color.blue;
currentColor = renderer.material.color; //Here we are assining the current color
}
}
}
}
I created a material and assigned it to the gameObject in the editor.
I'm trying to create a smaller game and I need to get a rectangle to move left to right within the window. Note that this is not the fully completed code. Below is a snippet of a created window class and the run function of it.
I can draw the rectangle, and at the moment it's also moving. However, when I'm pressing up/down it'll move to the right as well, but I want it to do it automatically. If I move the for-loop calling movement() outside of while (which I assume it should..?), the rectangle just disappears.
Another thing to note is that movement should be called through the vector pcEnhet, since I'll use it with other sprites later on.
void Spelplan::run() {
SDL_RenderClear(render);
for (PCKomponent* k : pcEnhet)
k->draw();
SDL_RenderPresent(render);
bool spela = true;
while (spela) {
SDL_Event eve;
while (SDL_PollEvent(&eve)) {
switch (eve.type) {
case SDL_QUIT:
spela = false;
break;
case SDL_KEYDOWN:
switch (eve.key.keysym.sym) {
case SDLK_DOWN:
for (PCKomponent* k : pcEnhet)
k->knappNer(eve);
break;
case SDLK_UP:
for (PCKomponent* k : pcEnhet)
k->knappUpp(eve);
break;
}//keysym switch
SDL_RenderClear(render);
for (PCKomponent* k : pcEnhet)
k->draw();
SDL_RenderPresent(render);
}//eve.type switch
for (PCKomponent* k : pcEnhet) {
k->movement();
k->draw();
}
}//while SDL_Poll
}//while spela
}
void Spelare::movement() {
area.x++;
}
void Spelare::draw() {
SDL_RenderCopy(sp->getPlan(), spelareTexture, NULL, &area);
}
Don't do the rendering in while (SDL_PollEvent(&eve)), but in while (spela). Your items have to be moved/drawn not depending on whether the input is being registered.
while (SDL_PollEvent(&eve)) {
...
}
SDL_RenderClear(render);
for (PCKomponent* k : pcEnhet) {
k->movement();
k->draw();
}
SDL_RenderPresent(render);
Remove the "pre-rendering" code you have above the bool spela = true; line, and remember to make your event loop similar to this from now on.
Note that rather than moving all the objects, you could think of them as stationary and move just the camera (viewport), with which you would calculate the absolute coordinates of the objects in their draw function.
And also, pick one from the two:
spela = false; // will render one last frame
break; // ^ will not, and does not require spela variable at all
I am trying to change a C++ project, which is currently drawing some lines when I click on the view port. This functionality is perfectly fine, but what I am trying to change is when I click on "UP" or "Down" keys the color for next lines to change. Currently if I click on those keys the color changes for all the lines including the old ones (already drawn).
Please give me an idea of what to do. Here is some of the code:
void drawPrimitive() {
Vertex *temp;
// Set the primitive color
glColor3fv(primitiveColor);
// Set the point size in case we are drawing a point
if (type == POINT)
glPointSize(pointSize);
// Display results depending on the mode
glBegin(mode);
for(temp = head; temp != NULL; temp = temp->np)
{
if (smoothShading)
glColor3f(temp->r, temp->g, temp->b);
glVertex2f(temp->x, temp->y);
}
glEnd(); }
void mouse(int button, int state, int x, int y) {
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
float pointX, pointY;
pointX = (float)x/window_width * world_width;
pointY = (float)(window_height - y)/window_height * world_height;
// Add a vertex to the list of vertices...
addVertex(&head, &tail, pointX, pointY, 0.0f, primitiveColor[0], primitiveColor[1], primitiveColor[2]);
// automatically calls the display function
glutPostRedisplay();
}
else if(button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
{
deleteVertex(&head, &tail);
glutPostRedisplay();
} }
void special(int key, int x, int y) {
switch (key)
{
// change primitive color
case GLUT_KEY_UP :
changePrimitiveColor(1);
break;
case GLUT_KEY_DOWN :
changePrimitiveColor(-1);
break;
}
glutPostRedisplay(); }
void changePrimitiveColor(int step) {
primitiveColorId += step;
if (primitiveColorId < 0)
primitiveColorId = COLOR_COUNT - 1;
if (primitiveColorId >= COLOR_COUNT)
primitiveColorId = 0;
setColor(primitiveColor, primitiveColorId); }
Your code is sort of unclear; is primitiveColor a global variable?
Assuming you're calling drawPrimitive() for all your lines each redraw, the same primitiveColor would be used for all the lines. As soon as you change the color when you press up or down, the redisplay function is called, and all the lines will be redrawn using the same color.
What you might want to do is have a list containing both the primitives and their respective colors. When you iterate through this list, you can set a color for each line.
Keep in mind that OpenGL behaves like a statemachine. If you set a color, everything you draw after it will be drawn with that color. OpenGL will not remember that your other elements had a different color and you want to keep it like that. You have to do the bookkeeping.
So each time your content is drawn, you will have to explicitly state which elements have which color.