"Shape Mode" for ControlP5 - processing

Vanilla Processing has shapeMode() for modifying "the location from which shapes draw." How, if possible, can one get the same functionality drawing UI "controllers" with ControlP5?
Concretely, I have tried the following code:
shapeMode(CENTER);
cp5.addButton("On/Off")
.setPosition(width/2, height/2)
.setSize(300, 300)
.setColorBackground(color(0, 113, 0));
And got this result:
But what I would like to see is this:
Obviously something like .setPosition(width/2 - buttonWidth/2, height/2 - buttonWidth/2) would work, but I would like to keep the code minimal.

Calling the shapeMode() function only changes the mode of shapes drawn with the shape() function.
ControlP5 doesn't use the shape() function to draw buttons. It uses the rect() function.
You can use the rectMode() function to change how rectangles are drawn. More info can be found in the reference.
But I doubt you'll be pleased with the results. That will move the rectangle of the button, but it won't move the text of the buttons, so all of your text will be off-center. That's just one issue, I'm sure there will be plenty of others.
If I were you I would just do the calculations myself. If you're really worried about keeping your code minimal, then you could create your own wrapper classes or utility functions that encapsulate the "logic" required to do the offsetting. But imho you should be more worried about keeping your code readable and maintainable.

Related

Winapi How do I draw a rectangle to a specific Window handle?

I'm Using a Wrapper Library in GMS2 That was made back in GM6 Days (gamemaker) Someone was able to wrap majority of the win32API to use in GM6-8. There is only 1 odd instance in where the WinAPI system seems to mess up when drawing the controls to the Main Application Window.
The desired goal is to draw an image to an Child window and draw a grid defining it's splitting according to the user input EX: 16x16 and having the user select squares VIA Mouse Click + Dragging over the boxes.
Unfortunately I have little to no experience in win32API so i'm a bit lost as to where to start.
Looking over the documentation it looks like he left majority of the script names of the DLL to mimic the format of that when calling in C++ or C (just my assumptions).
From His Documentation he has things like "Drawing System" Which Contains things like "Move Item","Add Line","Add Graphic Buffer" etc... and then other Graphic Buffer functions. But then theres the "Draw" functions which has things like "Draw Fill Rect , DrawSelectObj" etc... he doesn't really provide examples so i'm unsure as to how to use these things together to get my desired results. What is the difference between a drawing system and a draw function? Do I have to use them in conjunction, along with the Graphics Buffer?
Can Someone point in the right direction of the necessary steps to get it done? An Example without code and just the function equivalent will suffice, I just need to know out of which functions to use and then later bind it to the Child Window.
An Example Code from his demo is something like this
GbGradient2 = API_GB_Create (105,105); //Graphics Buffer
DcGradient2 = API_GB_GetDC (GbGradient2);
API_Draw_Gradient (DcGradient2,0,0,105,105,0,c_yellow,c_lime);
BrGradient2 = API_Draw_CreatePatternBrush (API_GB_GetBitmap (GbGradient2));
API_Draw_Gradient (DcGradient2,0,0,105,105,0,c_red,65535);
BrGradient3 = API_Draw_CreatePatternBrush (API_GB_GetBitmap (GbGradient2));
hRectangle = API_DS_AddRectangle (2,5,5,105,105); // Adds a rectangle(Drawing System)
hEllipse = API_DS_AddEllipse (2,5,5,105,105);
hNoPen = API_Draw_CreatePen (PS_NULL,0,0);
API_DS_SetItemBrush (hRectangle,BrGradient2); // Sets the brush
API_DS_SetItemBrush (hEllipse,BrGradient3);
API_DS_SetItemPen (hRectangle,hNoPen); // Sets the pen
API_DS_SetItemPen (hEllipse,hNoPen);
API_Draw_Gradient (GbGradient2,0,0,16,16,0,c_yellow,c_lime);
Lookin at it a little more it looks like the draw functions are linked to GDI somehow.
since GMS2 is a cross platform tool , its windows-only functionality gas been removed.
you can make a nice GUI for that porpose by using GMS2 objects , as you have a little Xp
about Win32 API,this will be easier than that big stuffy coding
here are some tips ,
creating a window object with a rectangle sprite
creating ui objects at the create event of above object
adding some code to the global mouse event

Drawing lines in ThreeJS

I'm working on an application in which Users can draw lines (with or without arrowheads). Similar to PowerPoint or SnagIt, but on a 3D plane."
Basically I would like to be able to create some line types like in the attached draft:
I've seen the fat lines demo (https://threejs.org/examples/#webgl_lines_fat). But lines don't seem to change width when zooming, and they don't have perspective.
There is also this 3rd party library THREE.MeshLine (https://github.com/spite/THREE.MeshLine) which has some nice features, even dashed lines animation, but before experimenting with it I would like to see what ThreeJS can do by itself.
1) Using ThreeJS Line is there a way to get:
Size and perspective change depending on camera distance/zoom or angle.
Dotted lines (Maybe extending DashedLineMaterial?).
2) Maybe there is a library other than THREE.MeshLine that does what I need?
MeshLine is definitely what you want. Three.js's line implementations are all pixel based and don't really fit your needs. MeshLine is well written and performant, I use it myself for a similar purpose - it'll serve you well.

How to make a shape in a vb6 application that resembles an Excel shape

I am trying to make a shape like a "call-out" box to use in a VB6 application. I can use the "Shape" tool to make a rounded-corner rectangle, but I would like to add the "V" shape at the bottom and have it all incorporated in the shape. A good example is the call-out shape used in Excel.
I have also used an image tool with a BMP in it, but still have the square corners of the image tool. I can't figure a way to do this and hope some out there knows how...???
Karl Peterson has code and explanation on creating an irregularly shaped object. It uses API calls, not just native VB controls.
See http://vb.mvps.org/samples/PolyBtn/.

Smooth animation of three shapes in SciLab

This answer provides a nice way to make smooth animations in SciLab. I now have to write a simulation of a body attached to two strings (and therefore its movement regarding some additional forces).
The code in the link works well to render movement of a single point and, unfortunately, I didn't manage to make an animation of a point + two lines using this method. If someone is curious, I tried this code to do it:
frametime=(tk-t0)/Nt//defining the waitnig time
plot(Y(1,1),Y(2,1),"o")//plotting the point
plot([0;Y(1,1)],[0;Y(2,1)],style=1)
plot([D;Y(1,1)],[0;Y(2,1)],style=1)//plotting the two initial lines
h1_compound = gce();
h_point=h1_compound.children
h_point.mark_size = 20;
h_point.mark_background = 2;
h_line1=h_compound.children
h_line2=h_compound.children
//h_axes = gca();
//h_axes.data_bounds = [0,-1;10,1];
realtimeinit(frametime);
for i=1:Nt//my vectors have Nt points
realtime(i);//wait "frametime" seconds before drawing the new position
h_point.data=[Y(1,i),Y(2,i)];
h_line1.data=[[0;Y(1,i)],[0;Y(2,i)]]
h_line2.data=[[D;Y(1,i)],[0;Y(2,i)]]
end
The question is: is there any way to make an animation of three shapes without making axes blink (as it is with the window refreshment) or other wierd stuff?
Since you didn't create a MCVE I can't reproduce your exact problem. But you may try to add drawlater(); before, and drawnow(); after your data modification to see if it does help with blinking or not.
Or you may get much better looking result by saving your plots in every round with xs2gif and assemble the animation with another gifmaker progam (there are free online sites to do this, however with some limitations). If you need to present your result, you should do this step anyway.

Why might the scaling of SetWindowExtEx be just wrong?

I am trying to scale images/text etc using MM_ANISTROPIC and what I've done is the following (by the way if the syntax is a little weird, it's originally from delphi so treat the following as pseudocode)
I would expect the following code to produce a rectangle that is 70% of the width of the PaintBox and 30% of the height, yet it doesn't, instead it it noticeably too small.
SetMapMode(hdc,MM_ANISOTROPIC);
SetWindowExtEx(hdc,100,100,0);
SetViewportExtEx(hdc,70,30,0);
Rectangle(hdc, 0,0,PaintBox.width-1,PaintBox.Height-1);
if, on the other hand I change the code so that the SetWindowExtEx has 91 instead of 100 as its parameters (as shown below) then it works, which makes no sense to me at all...
SetMapMode(hdc,MM_ANISOTROPIC);
SetWindowExtEx(hdc,91,91,0);
SetViewportExtEx(hdc,70,30,0);
Rectangle(hdc, 0,0,PaintBox.width-1,PaintBox.Height-1);
My sanity test case was to add the following pseudocode
SetMapMode(hdc,MM_TEXT);
DrawLine(hdc,Round(PaintBox.width*0.7),0,Round(PaintBox.width*0.7),PaintBox.Height-1);
DrawLine(hdc,0,Round(PaintBox.height*0.3),PaintBox.width-1,Round(PaintBox.height*0.3));
I would have expected this to overwrite the lower / bottom edges of my original Rectangle but it does not unless I uses that 91,91 SetWindowExtEx.
Can anyone duplicate this?
FURTHER EDIT: Here is my exact original code I had given pseudo code before to make the question more accessible to non-delphi users but one of my commenters wanted full code to see if my contention that it was a delphi quirk was true or not.
The entire project consisted of a VCL form with a rectangular paintbox dropped on it centered so there was space all around it, and its onPaint event was set to the code below resulting in this image::
procedure TForm11.PaintBox2Paint(Sender: TObject);
var
hdc:THandle;
res:TPoint;
procedure SetupMapMode;
begin
SetMapMode(hdc,MM_ANISOTROPIC);
SetWindowExtEx(hdc,100,100,0);
SetViewportExtEx(hdc,70,30,0);
// These lines are required when we're painting to a TPaintBox but can't be used
// if we're paiting to a TPanel and they were NOT in my original question but only
// got added as part of the answer
// SetViewportOrgEx(hdc,PaintBox2.Left,PaintBox2.Top,#ZeroPoint);
// SetWindowOrgEx(hdc,0,0,#ZeroPoint);
end;
begin
//draw a rectangle to frame the Paintbox Surface
PaintBox2.Canvas.Pen.Style:=psSolid;
PaintBox2.Canvas.Pen.width:=2;
PaintBox2.Canvas.Pen.Color:=clGreen;
PaintBox2.Canvas.Brush.Style:=bsClear;
PaintBox2.Canvas.Rectangle(0,0,PaintBox2.Width-1,PaintBox2.Height-1);
PaintBox2.Canvas.Brush.Style:=bsSolid;
//initialize convenience variable
hdc:=PaintBox2.Canvas.Handle;
SetTextAlign(hdc,TA_LEFT);
//as doing things to the PaintBox2.Canvas via Delphi's interface tends to reset
//everything, I'm ensuring the map mode gets set **immediately** before
//each drawing call
SetupMapMode;
/// Draw Text at the bottom of the PaintBox2.Canvas (though as it's mapped it
/// SHOULD be 1/3 of the way down and much smaller instead)
TextOut(hdc,200,PaintBox2.Height-PaintBox2.Canvas.TextHeight('Ap'),'Hello, World!',13);
PaintBox2.Canvas.Pen.Color:=clblue;
PaintBox2.Canvas.Brush.Style:=bsClear;
//ensure it's set before doing the rectangle
SetupMapMode;
// Redraw the same rectangle as before but in the mapped mode
Rectangle(hdc, 0,0,PaintBox2.Width-1,PaintBox2.Height-1);
PaintBox2.Canvas.Brush.Style:=bsSolid;
//reset the map mode to normal
SetMapMode(hdc,MM_Text);
//draw text at the "same" position as before but unmapped...
TextOut(hdc,200,PaintBox2.Height-PaintBox2.Canvas.TextHeight('Ap'),'Goodbye, World!',15);
//Draw lines exactly at 70% of the way across and 30% of the way down
//if this works as expected they should overwrite the right and bottom
//borders of the rectangle drawn in the mapped mode
PaintBox2.Canvas.Pen.Color:=RGB(0,255,255);
PaintBox2.Canvas.MoveTo(Round(PaintBox2.Width*0.7),0);
PaintBox2.Canvas.LineTo(Round(PaintBox2.Width*0.7),PaintBox2.Height);
PaintBox2.Canvas.MoveTo(0,Round(PaintBox2.Height*0.3));
PaintBox2.Canvas.LineTo(PaintBox2.Width,Round(PaintBox2.Height*0.3));
end;
Okay, I don't know WHY the following is necessary -- it may be a Delphi quirk, the fact that I'm using a TPaintBox with is a TGraphicControl rather than a Component, or if I'm missing out on some fundamental concept on how this whole mapping mode works, BUT if I add the following code:
ZeroPoint:=TPoint.Zero;
SetViewportOrgEx(hdc,PaintBox1.Left,PaintBox1.Top,#ZeroPoint);
SetWindowOrgEx(hdc,0,0,#ZeroPoint);
Then it all displays as expected. Anyone have any explanations as to why this is necessary?
EDIT: Okay, I've got a PARTIAL explanation. It has to do with the control I was painting on being a TPaintBox, which is a TGraphic control rather than a TWinControl. To wit:
TGraphicControl is the base class for all lightweight controls.
TGraphicControl supports simple lightweight controls that do not need the ability to accept keyboard input or contain other controls. Since lightweight controls do not wrap Windows screen objects, they are faster and user fewer resources than controls based on TWinControl.
As such, although they APPEAR to have a separate canvas, I have this sneaking feeling that they are really sharing the form's canvas which is why, when I switched to a TWinControl descendant, which DOES own its own Windows DC, then the display worked as expected without setting the ViewpointOrg.
So it was a Delphi quirk after all...!

Resources