Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Drawing Custom Buttons

Status
Not open for further replies.

splaisance

Programmer
Jul 2, 2001
67
US
I am having a problem drawing custom button shapes at specified locations in my application. The app has a grid of 24 concentric circles. Then a set of rectangles (or button shapes) are to be drawn onto this grid but they need to be drawn at an angle. Here is the code I am using in the paint event:


oG.TranslateTransform(pnlGrid.Width / 2, pnlGrid.Height / 2)

*For Each wABtn In clsBtn
'Move the origin to the bottom right corner of button
oG.TranslateTransform(wABtn.gSize.Width, wABtn.gSize.Height)

'Rotate the graphics by mydegrees
oG.RotateTransform(45)

'Get a fresh array of original corner points of button
* pts = wABtn.gPts

'Transform array to match transformation done on graphics object
* oG.TransformPoints(CoordinateSpace.Page, CoordinateSpace.World, pts)

'Update bounds of button w/newly transformed corner(points)
* wABtn.gBounds = New GraphicsPath(pts,mRectanglePathPoints)

'Close the bounding rectangle
* wABtn.gBounds.CloseAllFigures()

'Use ControlPaint to render 3D button image w/ state
*ControlPaint.DrawButton(oG, myRect.X, myRect.Y, hldWidth, hldHeight, wABtn.State)
*Next

'Reset transformation so drawing resumes on normal coordinate space
*oG.ResetTransform()

'Draw bounds of each button
* For i As Integer = 0 To (clsBtn.Count - 1)
* oG.DrawPath(Pens.Aqua, clsBtn.Item(i).gBounds)
* Next

Definitions at top of form are:
Private mRectanglePathPoints As Byte() = New Byte() {PathPointType.Start, PathPointType.Line, PathPointType.Line, PathPointType.Line}

Dim clsBtn As ArrayList
Private oG As Graphics
Dim wABtn As myButton

Where myButton is a class which determines each item's location, size, button pressed state, bounds (which is defined as a GraphicsPath), and other data.

When I only have the statements which are starred (*) run then I get the correct button outline, but the buttons are drawn 'regular' as in to say not on an angle or anything. Yet when I use all of the above code, neither the outlines nor the buttons are in the correct places.

Can anyone help me figure out what is going wrong?

 
Without the code to rotate, are they being drawn in the right location? Or are they being drawn in the wrong spot either way?

If you are getting the rectangle in the correct spot, but not at the correct angle, then you need to look at your angle calculation.

If you are getting it at the right angle, but not the right location, then you need to look at your offset algorithm.


-The answer to your problem may not be the answer to your question.
 
The rectangle is in the right spot but not the correct angle. What would affect the angle other than the og.RotateTransform(45) line? It is being (for now) hardcoded to be at a 45 degree angle yet is not at any angle. Am I missing something in the different transform methods?

Thanks!
 
no, but you may be forgetting to "nudge" the button when you rotate it, because it will (more than likely) rotate around the upper left corner, and not the center, which is what you were planning on.

what is an oG? --whoa...are you rotating the graphic, or the button?

'Rotate the graphics by mydegrees
oG.RotateTransform(45)


-The answer to your problem may not be the answer to your question.
 
og was previously defined as a graphics object.

I finally got the buttons to show at an angle. I needed to put the ResetTransform inside the button for loop. It was performing the transforms from the last button position for each button which wasn't what I meant for it to do. Oops!

And my understanding is that og.RotateTransform(45) rotates the graphics object I am drawing on then the button is drawn as a regular rectangle but when the graphic object is displayed (unrotated) the rectangle is then shown at the angle.

Now I just have to adjust the rectangle positions somewhat because aren't 100% where I want.

Thanks for the help tho!

 
cool.
sometimes you can "nudge" a person in the right direction, just by asking them the right questions about their code.


The only reason i was asking about the rotating code was because a made a funky lil script where one labels position was based on the position of another label and i had to offset my calculations, because it was using the upper left, not the center...


-The answer to your problem may not be the answer to your question.
 
Unfortunately I think I will have to look at doing this another way for 3 reasons.
1. Using the drawbutton method I don't see how I can make it a certain background color (unless I've missed it and someone can tell me how)
2. The buttons are not hitting the circles exactly right nor are they consistent on the "spokes" which are used to calculate the positioning. The position calculates work for the same sample data when I made the mybutton class actually inherit the system control's button class and added a true button control to the grid altering the shape using region commands. I was trying to find another way instead of doing this b/c when a bunch of the buttons need to be added then it is very slow to draw on the screen and you can "see" it drawing.

3. The buttons need to have the ability to be moved w/the mouse and can not get the repositioning from first place clicked w/mouse and ending place clicked w/mouse correct. Actually I am having problems doing this when used a true button control too so if anyone has advice on doing this correctly then it would be very helpful!

Yes, determing what/where the transforms are using can get confusing I've found. This whole thing is driving me NUTS!
Partially b/c I will not know ahead of time how many "buttons" I will need b/c the user will be able to add/remove them and such so it will not be only a set number.

Thanks!

 
Re 1) Do they have to be buttons? Why not just use a label, with an image.

Re 2) That is what i was talking about, you actually have to figure out where the center of the button is and do your calculations based on that.

Re 3) Is the button supposed to do something when you click it? or is it just moving it? if you need the button to do something with a click and something else (like move) with some other sequence (CTRL+Click) then you will have to program that with the button code.

Re 4) Good luck with that, you may want to have a "generic" button with all the behaviors that you are looking for and when the user clicks the "Add" button you just instantiate a copy of that button.

Don't you have Love/Hate relationship with projects like this?


-The answer to your problem may not be the answer to your question.
 
Re 2) Yes I know but the thing is that the calculations I am using work when I use a button class and only show it "angled" via the region method and using setbounds. (Same concept used if you want say a circular button). But using the drawbutton method does not put the buttons/drawing in the same place. Each is just a little off but it -shouldn't- be since the calculations are correct.

Re 3) Right now I am just moving them and creating links between them but I wouldn't doubt that later I may have to add more functionality. That's why I hate to use a different control although I did think about it.

Re 4) Wouldn't my own class which inherits button be the same thing? That isn't the issue really. It's positioning and moving w/out it taking forever to draw.

Actually I feel fed up cause nothing seems to work and I can't find the answers. But somehow I have to figure it out.
 
All right then, back up.

What are you trying to accomplish?

-The answer to your problem may not be the answer to your question.
 
*lol*

Okay - here is the idea. I have a type of grid which is made up of a number of concentric circles a set width apart. The default is 24 (think 24 hours). Each button (or whatever I make it) represents something that happens at a particular starting time (hour) and it's height is determined by how long the activity is. ie: time duration of 4 hours will cover 4 sections on grid, 2 hours will cover 2 sections of grid.

This information will come from a database but can also be added at run time too. Each button needs to be able to be moved from one area or time on the grid to another. The buttons are also linked together such as when one finishes then it might cause 2 other button(ie: jobs) to start.

Does that make sense?

On the moving I have been trying to evaluate the mouse position on the mouseup event and with those coordinates see if it was found in the rectangle making up each circle where the smallest circle that contains the point should be the "hour" the button was moved to, but this is not working correctly.
 
careful with the mouse position, i believe it is the X,Y for the control that you are in, and it goes left to right, top to bottom. I seem to remember the mouse up event having a strange number that wasn't where it was on the screen, but a "relational" number that had to be linked to something else.

Question: is there only 1 job per (concentric) circle?
so that when one "job" is "done" the next will "fall" into the "now active" position?






-The answer to your problem may not be the answer to your question.
 
Yeah I did read that the x,y coordinates were relative and I am playing with that.

No, there can be multiple jobs. In fact, it can be filled up with jobs if the user so chooses to add that many to one grid.
 
so, it can be a partial circle if is more than one job running/scheduled to run?

You're going to have fun piecing this together, I suggest playing with this on paper before you try this. I mean get a paper copy of that grid and cut circles out of it, and figure out how you want these to act.

-The answer to your problem may not be the answer to your question.
 
Hmm - no that isn't right. No partial circles - It is one circle inside another circle inside another circle, etc where the circle are a certain width apart. I guess you could say it looks like a bullseye. The buttons will be the jobs that are running/scheduled. If the start time is say 2, then the button needs to start on the 2nd circle's line. Then if the time it takes to complete is 3 hours then the button will go through the circles up to the 6th's circle's line but not into the 6th's circle area.

Is that clearer?
 
Okay, I am going to play dumb here. I am going to assume that you have X number of buttons, where X is a static number of rings that will not change. Why can't you just make a custom circular button for each ring?

Rather than making one button take up 2 button rings (as a single button) why dont you just assign that jobs value to 2 buttons?

-The answer to your problem may not be the answer to your question.
 
The buttons are not circular - the are a rectangle on an angle. And the number of buttons will not be static - it can change based on data plan choosen and additions/deletions user makes to data plan.
 
okay, so if:
there is only 1 job per ring
The buttons are rectangular, not round

Why do the buttons have to be at an angle? Do you have a full circle? If so, why not just put the buttons on the top of the circle? is the "bulls-eye" only a partial bulls-eye, such as a quarter and thats why the buttons are on an angle?

So part of your design has to be static, such as a formula for determining the location of a button based upon what ring it is going to wind up in. You have to have a max number of rings that you can create/display, or else they will literally go off of the screen.

I am actually having a harder time visualizing now than before, when i thought it was a full circle with multiple jobs per circle and you were drawing custom circular ring buttons.


-The answer to your problem may not be the answer to your question.
 
Your last line is almost correct: "I am actually having a harder time visualizing now than before, when i thought it was a full circle with multiple jobs per circle and you were drawing custom circular ring buttons."

It is a full circle w/multiple jobs just that the buttons ontop of the circles are custom drawn.

Think a bullseye with circle inside of circle, etc for 12(for an example) circles. Now imagine angled buttons at different areas of the circles. I don't know how to describe it better really.
 
so, there ARE multiple Jobs per ring?
or just multiple buttons (that might do different things)

-The answer to your problem may not be the answer to your question.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top