I have a problem with the Mouse events!
I have subscribed to the event MouseEnter and MouseLeave.
If my mouse cursor example is in the exact center of the panel, the MouseEnter and MouseLeave event triggered, why?
My goal would be to sense, starting from when the mouse cursor is on the 3D PlotCube and when not.
Code:
scene.MouseEnter += ILSurface_MouseEnter;
scene.MouseLeave += ILSurface_MouseLeave;
A plot cube catches events for the whole area of its ScreenRect rectangle. In a standard setup, this rectangle is set to (0,0,1,1) which fills the whole panel. So, unless you have multiple plot cubes / cameras on your panel, the mouse will basically always be on the plot cube.
In order to show the functioning of the MouseEnter and MouseLeave events nevertheless, I'll post an example which acts on a plot within the plot cube instead. It writes "On Plot" in the title bar of the form when the mouse enteres the plot. "Off Plot" is written as soon as the mouse leaves the plot.
Start with a fresh panel and setup ILNumerics as shown here: http://ilnumerics.net/visualization-api-quick-start-guide.html
Drag an ILPanel onto form1 and double click on it in order to switch to the code of the auto generated ilPanel1_Load event handler. Replace the handler with the following code:
private void ilPanel1_Load(object sender, EventArgs e) {
var surfPlot = new ILSurface(ILMath.tosingle(ILSpecialData.sincf(50, 40))) {
Colormap = Colormaps.Prism
};
var pc = ilPanel1.Scene.Add(new ILPlotCube(twoDMode: false) {
surfPlot
});
surfPlot.MouseEnter += (_s, _a) => {
if (!_a.DirectionUp)
Text = "On Plot - Target: " + _a.Target.ToString();
};
surfPlot.MouseLeave += (_s, _a) => {
if (!_a.DirectionUp)
Text = "Off Plot - Target: " + _a.Target.ToString();
};
}
This would produce a result similar to the following image:
The title of the form now reflects, if the mouse is on the plot or not. Note, that this is working regardless of the rotation / shape of the plot. The full documentation of the mouse event handling in ILNumerics is found here: http://ilnumerics.net/mouse-events.html
Related
I have a code to when I press "p" the game pauses. Although, I want to show some text saying like "Game is Paused. Press P to progress" how can I do that? HereĀ“s my code:
//create event
pause=false;
pauseSurf=-1;
pauseSurfBuffer=-1;
resW=1920;
resH=1080;
//Post-Draw event
gpu_set_blendenable(false);
if(pause)
{
surface_set_target(application_surface);
if(surface_exists(pauseSurf)) draw_surface(pauseSurf,0,0);
else // restore from buffer if we lost the surface
{
pauseSurf = surface_create(resW,resH);
buffer_set_surface(pauseSurfBuffer,pauseSurf,0);
}
surface_reset_target();
}
if(keyboard_check_pressed(ord("P")))// Toggle pause(Whatever condition/trigger you like)
{
if(!pause)// pause now
{
pause=true;
// deactivate everything other than this instance
instance_deactivate_all(true);
// NOTE:
// If you need to pause anything like animating sprites,tiles,room backgrounds
// you need to do that separately,unfortunately!
// capture this game moment(won't capture draw gui contents though)
pauseSurf=surface_create(resW,resH);
surface_set_target(pauseSurf);
draw_surface(application_surface,0,0);
surface_reset_target();
// Back up this surface toabuffer in case we lose it(screen focus,etc)
if(buffer_exists(pauseSurfBuffer)) buffer_delete(pauseSurfBuffer);
pauseSurfBuffer=buffer_create(resW*resH*4,buffer_fixed,1);
buffer_get_surface(pauseSurfBuffer,pauseSurf,0);
}
else // unpause now
{
pause=false;
instance_activate_all();
if(surface_exists(pauseSurf))surface_free(pauseSurf);
if(buffer_exists(pauseSurfBuffer))buffer_delete(pauseSurfBuffer);
}
}
gpu_set_blendenable(true);
//Clean up event
if(surface_exists(pauseSurf))surface_free(pauseSurf);
if(buffer_exists(pauseSurfBuffer))buffer_delete(pauseSurfBuffer);
Code from: https://www.youtube.com/watch?v=dNiLIX8jNOM&t=95s&ab_channel=ShaunSpalding
If any of you knows how to help me I would be thankful! :)
Add a DrawGui Event to your object, and then add the following code within:
if (pause)
{
draw_text(50, 50, "Game is Paused. Press P to progress");
}
DrawGui makes it so that it renders on top of your viewport, so it's not connected with the position in the room.
The 50, 50, is the X and Y position of the text, use it as you see fit. You can use it centered if you take the width/height of the camera/viewport and divide that by 2.
The pause is already defined in the Create Event, so that shouldn't give any problems.
Is there any way to not show this slider(as in screenshot below) on click of few polygons but to show on click of few other polygons?
To simplify what I mean to say, suppose This slider should be shown on click of blue polygon but should not be shown when red polygon is clicked, but I want to keep the ids for both polygons.
There's an undocumented property [_enableInfoOrSelection][1] (note - this is a private property and is unsafe for production - use with care).
The code is:
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
var shouldShow = true;
handler.setInputAction(function(click) {
viewer._enableInfoOrSelection = shouldShow;
shouldShow = !shouldShow;
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
Note the line that controls weather to show or not to show the info box:
viewer._enableInfoOrSelection = shouldShow;
You'd might want to do something smarter (like to remove the info box in case a new entity was clicked etc., but it's up to you :)).
Here's a working code:
http://plnkr.co/edit/Zb6fwNExkceAPpRyXnEw?p=preview
I want to create a button which can be dragged and dropped toward another button so that the button location (x, y) is dragged into the location of the destination button.
My code:
sejarah.onPress = function(){
startDrag(this);}
sejarah.onRelease = function(){
if(this.hitTest (atarget)){
this._x = _root.atarget._x;
this._y = _root.atarget._y;}
else{stopDrag();}
}
I want to achieve this: http://www.thibaud.be/#
on(press) {
startDrag(this);
}
on(release) {
stopDrag();
_x = Math.round(_x/_width)*_width + 0;
_y = Math.round(_y/_height)*_height + 0;
}
This is one of the most simple code that can do a job like this. You put this code inside a button and when you stop dragging this button it's position will snap to the grid.
Your button's clip center must be at top-left corner of button else it can get weird. Also, you can change beginning of grid by changing zeros to position you need.
You can draw a grid to see attachment.
I am trying to move an object in a page form top to down on user finger movement using translate transform. we should see page contents as the bar goes down the page and sits at bottom.
Just like Action Center in windows phone 8.1.
Please let me know any ideas how we can design. Thanks.
Good question!
My first thought was to do something like this.
You could get the touch input location and then move a rectangle from the top of the screen and translate it down according to they Y Cord of the Touch Input.
EDIT:
Okay so here is what you can do.
Create a Canvas and position it somewhere at the top ( i gave it the height of 14 in collapsed state).
Then create a private void cn_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e) event and make it set the height of the Canvas. I also included a float i to later make it snap back or cover the entire screen if the user lets go during the pull-event.
private void cn_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
{
cn.Height += e.DeltaManipulation.Translation.Y;
i = (float)e.CumulativeManipulation.Translation.Y;
}
And thats it. You can also add this event to make it snap back or go cover the full screen when the user lets go.
private void cn_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
{
if(i < 100)
{
cn.Height = 14;
}
else
{
cn.Height = Application.Current.Host.Content.ActualHeight;
}
}
Of course you can add smoother animations so it slowly goes back into the collapsed view or fills the entire page.
I hope this helps!
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.