How to get rounded Corner button image in QML after tiling - qml

I have Button image with Rounded Button image. I am tiling image to get bigger button in QML . I am using parent as rectangle and image as BorderImage. After tiling I am getting rectangle on top image is visible. I need to remove the part of the rectangle so that only rounded button image (Has transparency) is Visible. Even i need to change the color of the behind rectangle so that Color animation is possible.
Please suggest efficient method to remove the behind rectangle and provide the color animation also.
I am attaching the Rounded button border image as attachment and source code for tiling the button image.
Rectangle{
id:outerBorderRect
smooth:true
anchors.fill:parent
//opacity:.25
//border.width:0
BorderImage{
id:innerBorderRect
smooth:true
anchors.fill:parent
border{left:20;top:16;right:17;bottom:20}
horizontalTileMode:BorderImage.Round
verticalTileMode:BorderImage.Round
source:"button_3.png"
}
}

A simple and semi-hack way to do this is to use the radius property in Rectangle to hide the corners of your button.
Or you could use a proper mask by using Qt's OpacityMask.
I'm not sure what kind of animation you're looking for. You'll have to provide more details for me to answer that part.

Related

How to save a scaled image inside QGRaphicsView using QFileDialog

I have a user interface with:
N.1 Push button (used to upload images)
N.2 QGraphicsView (left and right)
N.1 Push button that takes a print screen of the current image loaded on QGraphicsView left
Using the mouse is possible to:
1) zoom-in/zoom-out from the image
2) draw rectangles on the image.
I want to take the print screen of the image according to the zoom-in or zoom-out area I am using. However, once the file is saved it shows the entire image (wrong because I wanted only the enlarged or shrank part) with the rectangles drawn (this is correct).
According to this post QFileDialog was used in a similar way I am trying to do. I successfully used QFileDialog::getSaveFileName() to save the image. However it is not entirely solving the problem.
Below the pushbutton that takes care of taking the print screen of the image in the QGraphicsView left:
void MainWindow::on_addNewRecordBtn_clicked()
{
leftScene->clearSelection(); // Selections would also render to the file
leftScene->setSceneRect(leftScene->itemsBoundingRect()); // Re-shrink the scene to it's bounding contents
QImage image(leftScene->sceneRect().size().toSize(), QImage::Format_ARGB32); // Create the image with the exact size of the shrunk scene
image.fill(Qt::transparent); // Start all pixels transparent
QPainter painter(&image);
leftScene->render(&painter);
image.save(QFileDialog::getSaveFileName(this, tr("New Image Name"), QDir::rootPath(),
"Name (*.jpg *.jpeg *.png *.tiff *.tif)"));
}
The expected result would be saving the zoomed image (zoom.jpg for example) like this:
However when I save the image (zoom.jpg) the result that I am obtaining is constantly the entire image with the drawn features:
So if anyone needs, it is possible to take a print screen of an image no matter what the zoom in. Meaning you can zoom-in and zoom-out and take a print screen.
The following statement will do the job, grabbing the image your present (zoomed in or out status):
QImage image = ui->leftView->grab().toImage();
The only glitch is that the scroll bars horizontal and vertical (depending on the zoom) are also printed in your image. You can avoid that by setting them off right before taking the print screen and putting them back on right after.
Basically my previous function can be better written as follows:
void MainWindow::on_addNewRecordBtn_clicked()
{
leftScene->setSceneRect(leftScene->itemsBoundingRect());
// Setting off the scroll bars
ui->leftView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->leftView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
QImage image = ui->leftView->grab().toImage();
image.save(QFileDialog::getSaveFileName(this, tr("New Image Name"), QDir::rootPath(),
"Name (*.jpg *.jpeg *.png *.tiff *.tif)"));
// Putting the scroll bars back on
ui->leftView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
ui->leftView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
}
Hope this will be helpful in case you encountered my same problem.

How to use mask with transparency on QWidget?

I am trying to use mask on my QWidget. I want to overlay existing widget with row of buttons - similar to Skype
Notice that these buttons don't have jagged edges - they are nicely antialiased and widget below them is still visible.
I tried to accomplish that using Qt Stylesheets but on pixels that should be "masked out" was just black colour - it was round button on black, rectangular background.
Then I tried to do this using QWidget::mask(). I used following code
QImage alpha_mask(QSize(50, 50), QImage::Format_ARGB32);
alpha_mask.fill(Qt::transparent);
QPainter painter(&alpha_mask);
painter.setBrush(Qt::black);
painter.setRenderHint(QPainter::Antialiasing);
painter.drawEllipse(QPoint(25,25), 24, 24);
QPixmap mask = QPixmap::fromImage(alpha_mask);
widget.setMask(mask.mask());
Sadly, it results in following effect
"Edges" are jagged, where they should be smooth. I saved generated mask so I could investigate if it was the problem
it wasn't.
I know that Linux version of Skype does use Qt so it should be possible to reproduce. But how?
One possible approach I see is the following.
Prepare a nice high resolution pixmap with the circular button icon over transparent background.
Paint the pixmap on a square widget.
Then mask the widget leaving just a little bit of margin beyond the border of the circular icon so that the widget mask jaggedness won't touch the smooth border of the icon.
I managed to get a nice circular button with not so much code.
Here is the constructor of my custom button:
Button::Button(Type t, QWidget *parent) : QPushButton(parent) {
setIcon(getIcon(t));
resize(30,30);
setMouseTracking(true);
// here I apply a centered mask and 2 pixels bigger than the button
setMask(QRegion(QRect(-1,-1,32,32),QRegion::Ellipse));
}
and in the style sheet I have the following:
Button {
border-radius: 15px;
background-color: rgb(136, 0, 170);
}
With border-radius I get the visual circle and the mask doesn't corrupt the edges because it is 1 pixel away.
You are using the wrong approach for generating masks. I would generate them from the button images themselves:
QImage image(widget.size(), QImage::Format_Alpha8);
widget.render(&image);
widget.setMask(QBitmap::fromImage(image.createMaskFromColor(qRgba(0, 0, 0, 0))));

How to set background color of an image using draw2d?

I have drawn one rectangle by using RectangleFigure in draw2d. And I am able to
color the rectangle figure by calling rectangleFigure.setBackgroundColor.
Now the same way I want to color the Image also. For that I used ImageFigure in
draw2d and I gave the background color by calling ImageFigure.setBackgroundColor().
But it does not give any color for me. So How can I give the background color
to the image figure in draw2d?
RectangleFigure extends Shape which draws it's own background by default. ImageFigure directly extends Figure which will only draw the background if you set it as Opaque:
imageFigure.setOpaque(true);

Fullscreen Panel overlay in Sencha Touch 1

I am trying to slide a Panel from the bottom, so that it covers the entire viewport, like the Bookmarks panel in iOS Safari. This is similar to the ActionSheet, but fulscreen, and without the dark frame around it.
this.advSearch = Ext.ComponentMgr.create({xtype: 'advanced_search', itemId: 'pnlAdvancedSearch'});
this.advSearch.autoRender = true;
this.advSearch.show({type: 'slide', direction: 'up'});
This sort of works, but the new panel doesn't fill the whole screen, and parts of it appear behind the background panel. I've tried various layouts, including fit, vbox, with varying degrees of ugliness, but the root problem seems to be that the panel doesn't know how tall it needs to be. Maybe because it doesn't have a container?
Any suggestions? Is this even the right approach, or should I try to hack the ActionSheet to expand to fullscreen, and show without the border?
Thanks.
Because your panel is floating (or I presume it is), you will need to give the panel a fixed height in Sencha Touch 1. You are very restricted in that respect. This following code should work:
var sheet = new Ext.Sheet({
html: 'hello',
style: 'color:#fff',
height: window.innerHeight,
stretchX: true
});
// replace this show with your animation
sheet.show();
As you can see, I give it a fixed height of the window and then stretch it on the X axis (y doesn't work).

(C++/CLI) Testing Mouse Position in a Rectangle Relevent to Parent

I've been messing around with the Graphics class to draw some things on a panel. So far to draw, I've just been using the Rectangle Structure. On a panel, by clicking a button, it makes a rectangle in a random place and adds it to an array of other rectangles (They're actually a class called UIElement, which contains a Rectangle member). When this panel is clicked, it runs a test with all the elements to see if the mouse is inside any of them, like this:
void GUIDisplay::checkCollision()
{
Point cursorLoc = Cursor::Position;
for(int a = 0; a < MAX_CONTROLS; a++)
{
if(elementList[a] != nullptr)
{
if(elementList[a]->bounds.Contains(cursorLoc))
{
elementList[a]->Select();
//MessageBox::Show("Click!", "Event");
continue;
}
elementList[a]->Deselect();
}
}
m_pDisplay->Refresh();
}
The problem is, when I click the rectangle, nothing happens.
The UIElement class draws its rectangles in the following bit of code. However, I've modified it a bit, because in this example it uses the DrawReversibleFrame method to do the actually drawing, as I was using Graphics.FillRectangle method. When I changed it, I noticed DrawReversibleFrame drew in a different place than FillRectangle. I believe this is because DrawReversibleFrame draws with its positions relative to the window, while FillRectangle does it relative to whatever Paint event its in (Mines in a panel's Paint method.) So let me just show the code:
void UIElement::render(Graphics^ g)
{
if(selected)
{
Pen^ line = gcnew Pen(Color::Black, 3);
//g->FillRectangle(gcnew SolidBrush(Color::Red), bounds);
ControlPaint::DrawReversibleFrame(bounds, SystemColors::Highlight, FrameStyle::Thick);
g->FillRectangle(gcnew SolidBrush(Color::Black), bounds);
//g->DrawLine(line, bounds.X, bounds.Y, bounds.Size.Width, bounds.Size.Height);
}
else
{
ControlPaint::DrawReversibleFrame(bounds, SystemColors::ControlDarkDark, FrameStyle::Thick);
//g->FillRectangle(gcnew SolidBrush(SystemColors::ControlDarkDark), bounds);
}
}
I add in both DrawReverisbleFrame and FillRectangle so that way I could see the difference. This is what it looked like when I clicked the frame drawn by DrawReversibleFrame:
The orange frame is where I clicked, the black is where its rendering. This shows me that the Rectangle's Contains() method is look for the rectangle relevant to the window, and not the panel. That's what I need fixed :)
I'm wondering if this is happening because the collision is tested outside of the panels Paint method. But I don't see how I could implement this collision testing inside the Paint method.
UPDATE:
Ok, so I just discovered that it appears that what DrawReversibleFrame and FillRectangle draw are always a certain distance apart. I don't quite understand this, but someone else might.
Both Cursor::Position and DrawReversableFrame operate in screen coordinates. That is for the entire screen, everything on your monitor, and not just your window. FillRectangle on the other hand operates on window coordinates, that is the position within your window.
If you take your example where you were drawing with both and the two boxes are always the same distance apart, and move your window on the screen then click again, you will see that the difference between the two boxes changes. It will be the difference between the top left corner of your window and the top left corner of the screen.
This is also why when you check to see what rectangle you clicked isn't hitting anything. You are testing the cursor position in screen coordinates against the rectangle coordinates in window space. It is possible that it would hit one of the rectangles, but it probably won't be the one you actually clicked on.
You have to always know what coordiante systems your variables are in. This is related to the original intention of Hungarian Notation which Joel Spolsky talks about in his entry Making Wrong Code Look Wrong.
Update:
PointToScreen and PointToClient should be used to convert coordinates between screen and window coordinates.