I have this JavaFX Slider:
As you can see, the min value is 1 and the major tick unit is 5.
But what I'd like to achieve is this:
or at least this:
So basically, I want to move the whole scale to the left by 1 tick. But how?
(I also saw this post, but isn't there a quicker and easier way? Or do I really have to define my own Slider for this little task?)
Edit
Okay, I tried to make my own slider then. But I'm really lost.
This is what I want to do logically; but I don't know how to do it practially:
public class ImprovedTicksSlider extends Slider {
public void setTickMarks(int majorTickUnit, int minorTickCount) {
// 1.)
// set the first major tick mark at
// getMin() + (majorTickUnit - getMin() % majorTickUnit)
// 2.)
// set minor tick count in the very first block to:
// majorTickUnit - (getMin() % majorTickUnit)
// 3.)
// set all other major tick marks at positions where
// (x % majorTickUnit == 0)
// 4.)
// set all other blocks of minor ticks to (minorTickCount)
// like it would usually be the case in a standard Slider
// ...but how?!
}
}
I think you pretty much got it. You'll have to use a custom Slider since this basic slider only supports regular tick intervals.
The custom slider isn't really that big and you can import it in FXML so it's not a big problem.
Related
My LineItem inheriting from QGraphicsLineItem can change its pen width.
I have created a boundingRect that uses the QGraphicsLineItem::boundingRect adjusted by pads that get calculated based on pen width and arrows. It works.
void LineItem::calculateStuff() // called on any change including pen width
{
qreal padLeft, padRight, padT;
padLeft = 0.5 * m_pen.width(); // if no arrows
padT = padLeft;
padRight = padLeft;
m_boundingRect = QGraphicsLineItem::boundingRect().adjusted(-padLeft, -padT, padRight, padT);
update();
}
QRectF LineItem::boundingRect() const
{
return m_boundingRect;
}
QPainterPath LineItem::shape() const
{
QPainterPath p;
p.addRect(m_boundingRect);
return p;
}
There is only one artifact that I get:
if I increase the pen width, then decrease it, I get traces:
these of course disappear as soon as i move mouse or any action (I had a hard time getting the screen shots)
As pretty as they are (seriously I consider them a "feature :-) ) - I am trying to eliminate them. I tried to remember previous bounding rectangle, and update the item with the previous bounding rectangle - i thought that was what the option was for - but it didn't work.
QRectF oldRect = selectedItem->boundingRect();
item->setItemPenWidth(p);
selectedItem->update(oldRect);
selectedItem->update();
My viewport has
setViewportUpdateMode(BoundingRectViewportUpdate);
If I change to
setViewportUpdateMode(FullViewportUpdate);
I don't get artifacts - but I think this will impact performance which is a major constraint.
How can I fix these artifacts - that only occur in that specific situation, decreasing pen width / decreasing bounding rect of line, without impacting performance ?
Simple fix... I had to add
prepareGeometryChange();
in my calculateStuff() function.
I have not seen any changes from this before, it is the first time I change my boundingRect that it does not update seamlessly.
Currently I have a project that is being used to draw rooms with lines and images that can be selected by the user by hitting a button representing what they want to add. I.E. if they want a shower a button for shower is pressed and an image appears in a pane. The shower can be resized and moved in the pane. The user also has the ability to use lines to draw objects or walls. The lines can be resized, rotated, or moved. I am now trying to get these objects to interact with each other. Say a user is using lines to make an object, and when the line comes near another object the line being moved snaps to the other object. I have found a 3rd party library that has SnapLineSnapResult but I don't see anything where someone has used it. Is this something that is desktop JavaFX usable, or is it a touch operation and does anyone have code to model or another solution?
SnapLineSnapResult
My code for line that would be useful if I can use this class is as follows:
line.setOnMouseDragged((MouseEvent event1) -> {
// in resize region
if (isInResizeZoneLine(line, event1)) {
// adjust line
line.setEndX(event1.getX());
}
// in movable region
else {
Point2D currentPointer = new Point2D(event1.getX(), event1.getY());
if (bound.getBoundsInLocal().contains(currentPointer)) {
/*--------*/ // potential place for if (near other object to be snapped)
double lineWidth = line.getEndX() - line.getStartX();
line.setStartY(currentPointer.getY());
line.setEndY(currentPointer.getY());
line.setStartX(currentPointer.getX() - lineWidth/2);
line.setEndX(currentPointer.getX() + lineWidth/2);
}
}
});
I would like to write a custom QLabel subclass with some more features for responsive design. In thisexample, I want to write a QLabel which scales the text based on the useable space. This is quite easy but also has some problems because of Qt-intern stuff. (I have to scale the text to 0.9 of the useable space, otherwise resizing the window / widget gets buggy)
Now I wan't to add a way to hide the label completely when the font size is bellow a specific threshold. However, this seems to be quite a complex task.
Here is what I have sofar in the classes resizeEvent(QResizeEvent *event) function.
Right now, my function only sets the text to "" when the size would be bellow the threshold.
void CustomLabel::resizeEvent (QResizeEvent * event ) {
if(autoFontResize) {
this->setSilentText(labelText); // just the normal setText function, I overwrote it for the subclass
QFont f = this->font();
int flags = Qt::TextDontClip|Qt::TextWordWrap;
QRect fontBoundRect = this->fontMetrics().boundingRect(this->rect(), flags, this->text());
float xFactor = (float)event->size().width() / (float)fontBoundRect.width();
float yFactor = (float)event->size().height() / (float)fontBoundRect.height();
float factor = xFactor < yFactor ? xFactor : yFactor;
f.setPointSizeF(f.pointSize()*factor*0.9); //
if(minimumFontSize != 0) { // 0 = no minimum Size for the font
if(f.pointSize() < minimumFontSize) {
if(hideFontOnMinimum) { // either Hide or set to the limit size
this->setSilentText(""); //replace text
} else {
f.setPointSizeF(minimumFontSize);
}
}
}
this->setFont(f);
}
QLabel::resizeEvent(event);
}
By the way, some parts of the code are found on stackoverflow, not mine. ;)
What I would like to do is to completely hide() the label. However the label doesn't know when It can show() again since the resizeEvent doesn't seem to be called after that.
Any ideas?
Thanks!
As you've noticed, if you call hide() on the widget it fails to receive a resize event. Since you're customising the class anyway, rather than calling hide(), you could just set a class variable to note that it's hidden and overload the paintEvent function, not to draw the widget if the variable is set: -
void CustomLabel::paintEvent(QPaintEvent * event)
{
if(m_hideOnMinimum)
return;
QLabel::paintEvent(event);
}
Note that by not painting the label, it will be hidden, but the user may still be able to interact with it, so you will need to disable it or overload keyboard / mouse events too.
Stacked Widgets don't have the possibility to update the size to the minimum size of the contents current shown.
It always shows the biggest size of the biggest layer and stays there as long as the QSizePolicy stays the same.
An aproach i found long time ago was to use a function like this:
void SmartUIWrapper::updateStackedWidgetSize( QStackedWidget* stacked, int index )
{
// Set to size policy ignored for the rest of pages. Set expanding to the actual one
for (int i = 0; i < stacked->count (); ++i)
{
// determine the vertical size policy
QSizePolicy::Policy policy = QSizePolicy::Ignored;
if (i == index)
policy = QSizePolicy::Expanding;
// update the size policy
stacked->widget (i)->setSizePolicy(QSizePolicy::Fixed, policy);
}
}
It sets all elements to Ignored, and then it sets the vertical policy of the selected widget which is Expanding (or whatever you want).
Later on i found out that reloading the styletheet updates the current sizes and makes the widget to resize to the minimum. But this approach is way too slow and unnecessary.
Do you know any other way to update the size to shrink to the smallest size in the current layer shown?
I want to create a progress bar of which a % of it is filled in with a different color based on some variable. For example 33 % would fill 33 % of the progress bar with a different color and then 40 % would likewise, fill 40 % of it. What is the best way to do this in Actionscript and Flex 3?
The way I've done this in the past is to create a custom progress bar skin, then set the fill to be a gradient that goes the entire length of the bar (even though a smaller portion of the bar actually gets drawn.) Sounds strange to use a gradient for something that has hard stops to the colors, but it's actually pretty easy. You set the stop for the next color right next to an end stop for the previous color. Here's an example where the color changes from green to red at the mid point:
package some.package.skins
{
import flash.display.GradientType;
import flash.geom.Matrix;
import mx.core.UIComponent;
import mx.skins.halo.ProgressBarSkin;
public class ColoredProgressBarSkin extends ProgressBarSkin
{
override protected function updateDisplayList(w:Number, h:Number):void {
super.updateDisplayList(w, h);
graphics.clear();
var fullWidth:int = w;
if (parent != null && (parent as UIComponent).mask != null)
fullWidth = (parent as UIComponent).mask.width;
var matrix:Matrix = new Matrix();
matrix.createGradientBox(fullWidth, h);
var colors:Array = [0x00ff00, 0x00ff00, 0xff0000, 0xff0000];
this.graphics.lineStyle();
this.graphics.beginGradientFill(GradientType.LINEAR, colors, [1,1,1,1], [0,128,128,255], matrix);
this.graphics.drawRoundRect(2, 2, w - 4, h - 4, h - 4);
}
}
}
You then set this skin to the barSkin style on your progress bar, either in CSS or in the tag where you use the progress bar.
Hope that helps.
I had to do this a while back and opted to take the following route:
I built a custom preloader by extending the DownloadProgressBar and then integrated it with this Degrafa component. http://degrafa.org/source/CapacityIndicator/CapacityIndicator.html
To create the custom preloader, I think I used this tute:
http://iamjosh.wordpress.com/2007/12/18/flex-custom-preloader/
and then created a separate class that was responsible for dynamically adjusting the values in that degrafa component linked above. And then of course in your SWFDownloadProgress function (on the Progress Event), you can adjust those values accordingly.
I found this to be the quickest and a fairly clean way of doing it :)
Good luck!