Rating Control

Has anyone made a “Rating Control” before?
I mean, a control with stars, representing a value.

I am looking for something like a canvas-subclass or something like that.
I was thinking about adding properties like:

  • maximum value
  • value
  • segmentCount (number of stars to show)

When having a rating value between 0 and 10, with 5 segments visible, and my RatingValue is 5, only 2,5 stars will show up.

Well, you know what I mean, it is used in lot of applications :slight_smile:

simple example

[quote=188047:@Axel Schneider]simple example


Thats nice and elegant Axel!
I am going to tweak it a bit more.

You know you are a very kind fellow, Axel - always helping and uploading code. Thank you.

If you want to restrict the rating to half- and full-stars then replace

cnv.Width = x


cnv.Width = Round( x/10 ) * 10

I am thinking of using the code you guys provided in a Canvas-Subclass. Maybe when the next release of Xojo comes out, I can change it to a nice plugin.
The image provided by Axel is cool. But I will try to use an embedded method to provide the star-images. That way I can make the RatingSlider-control more customizable, by changing colors etc.

The embedded star method is something I found on the Real Software Forum, by some guy named Phil M.
So, Thanks Phil… :slight_smile:

Sub FillStar(Extends g As Graphics, numberOfPoints As Integer, centerOfStarX As Integer, centerOfStarY As Integer, outerRadius As Double, innerRadius As Double, startAngle As Double = -90)
  Const PI = 3.14159265358979323846264338327950
  // check required and return if not available
  If ( g Is Nil ) Then Return
  If ( numberOfPoints < 3 ) Then Return   // cannot make a star with fewer than 3 points
  Dim points( 0 ) As Integer
  Dim angleOffset As Double = 360 / ( numberOfPoints * 2 )
  Dim thisRadius As Double
  innerRadius = Abs( innerRadius )    // can't have negative radius values
  outerRadius = Abs( outerRadius )
  For k As Integer = 0 To ( numberOfPoints * 2 )
    If (( k Mod 2 ) = 0 ) Then thisRadius = outerRadius Else thisRadius = innerRadius   // set radius
    points.Append( centerOfStarX + ( thisRadius * Cos( startAngle * ( PI / 180 ))))    // x of point
    points.Append( centerOfStarY + ( thisRadius * Sin( startAngle * ( PI / 180 ))))    // y of point
    startAngle = startAngle + angleOffset
  // copy values for first point to CLOSE off shape
  points.Append( points( 1 ))
  points.Append( points( 2 ))
  // now draw the star to the graphics
  g.FillPolygon( points )
End Sub

Only, the code above draws a star around a center point. I made another small method that calls the Fillstar method and drawes it with only the TopLeft position and the OuterRadius. In this method I calculate the size of the InnerRadius by dividing the OuterRadius by 2. That made it a little bit easier to call the method.

Here is my offering:



System fonts contain very nice stars that can be used to draw on a canvas : ???.

Coding a star control with that then becomes easier.

Rather than drawing the stars on the fly it might be less cpu intensive to just create an array of pictures on startup, draw the stars required (e.g. 5 pictures if only full stars, 10 is half stars), and draw these pictures when needed with g.DrawPicture(7) for 3.5 stars

[quote=188731:@Michel Bujardet]System fonts contain very nice stars that can be used to draw on a canvas : ???.

Coding a star control with that then becomes easier.[/quote]

You are right Michel. A simple yet effective way.

Except you cannot draw a half-star.

That is kind of what I did. What I did is adding a method that creates the full amount of stars.
Actually, 1 picture with the colored stars. And 1 with star placeholders, like gray or just outlines or dots.
The stars picture is basically a rectangle in a solid color, with star shaped masks, to allow transparency.

Every time a layout property changes, like color, size, shape and starcount it updates these pictures. The starcount is the property that defines the amount of stars that will be shown when the Value property is set to it’s maximum. That is 5, in the examples above.

In the Paint event I draw the placeholder first. Next I draw the colored stars with either a mask, that let me only show the stars I need to see.

Drawing the stars using system fonts is definitely an option. It is not necessary to draw half-stars, since a mask is taking care of that. The solution is to draw the number of stars I need in a temporary picture object, and draw that picture on the canvas, with a mask covering the stars I don’t want to see. Maybe just cropping will work fine in this case.

added Simon’s and Michel’s suggestion to the Example

I worked in a dynamic version, I hope will be helpful

source code

Nice Job Javier.
I tried something too, before I checked the replies in this threat.
This control is quite customizable. Lots of properties can be changed. I am still working on transparency and stuff like that.
All colors are adjustable. Also size of the elements (stars) and placeholder dots are adjustable.
The control is resizable. The elements will reposition after the Update method is called. This control is a subclass of the Canvas Control, which doesn’t have the Resize event. That’s why I added the update method, just in case you want to lock the width and height of the control to the RatingSlider’s parent.

The elements are drawn dynamically. Every time the layout changes, the elements are re-rendered. I used a mask to hide the portion of the elements. This prevents the stars (or whatever elements used) have to be re-drawn every time the value changes. That would cost too much CPU time.
The border thickness and corner radius can be changed also. That can make the control look a little bit nicer. To hide the border, simply set the borderSize to 0.
The stars are drawn using polygons. Therefore no images have to be stored internally. This makes the control file smaller, and there are no resolution distortion or artifacts.

This control is just one class you can easily drag into your project browser.
Just check the properties to see what can be changed and modified.

Example Project