Restore WinForms window to correct position after Aero Snap - windows

When I drag a WinForms window to the top of the screen to perform a Maximize "Aero Snap", if I then hit the "Restore" button after this, the window is restored to the correct size but at the wrong location. It flickers to the correct location for a moment, but then it immediately moves to the top of the screen with its title bar halfway off the screen.
Apparently, the WinForms window restores to its last dragged location before it was maximized, which was at the top of the screen where it was dragged in order to do the Aero Snap.
This behavior is incorrect and annoying. You can see the correct behavior by following those same steps for a Windows Explorer window. After an Aero Snap, the Windows Explorer window correctly restores to the last dropped restore location (wherever it was sitting before it was dragged to do the Aero Snap).
How can I make a WinForms window restore to the correct location after an Aero Snap, like a Windows Explorer window does?
I could try and hook into the form positioning events and save the last-dropped restore location, and restore that after a Restore after an Aero Snap, but I'm hoping there's a simpler way.

You can override the OnResizeBegin, OnResizeEnd and OnSizeChanged methods to:
store a Form's current Location when it's first dragged (when you begin to drag a Form around the OnResizeBegin is called)
clear the stored values if the Form is released (OnResizeEnd is called) while it's WindowState is FormWindowState.Normal
finally restore the Form.Location when OnSizeChanged notifies that the Form.WindowState changes from FormWindowState.Maximized to FormWindowState.Normal.
If you use a Controller or similar, you can subscribe to the corresponding events instead.
Point beginDragLocation = Point.Empty;
FormWindowState beginDragFormState = FormWindowState.Normal;
protected override void OnResizeBegin(EventArgs e)
{
base.OnResizeBegin(e);
beginDragLocation = this.Location;
}
protected override void OnResizeEnd(EventArgs e)
{
base.OnResizeEnd(e);
if (this.WindowState != FormWindowState.Maximized) {
beginDragLocation = Point.Empty;
}
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
if (beginDragFormState == FormWindowState.Maximized && beginDragLocation != Point.Empty) {
BeginInvoke(new Action(() => this.Location = beginDragLocation));
}
beginDragFormState = this.WindowState;
}

Related

How to create a "clicking effect" on a 3d-object (3d-cube) in Unity3d?

I have a 3d-object (cube), which I want to use as a button. I've written the code in order to detect, if the cube was pressed but it doesn't look like it was pressed, since it lacks the "clicking animation". How can I create a clicking animation on my 3d-object ?
A good idea is to play an aninimation which skrinks the cube a bit and releases it immediately afterwards. The handler code you want to execute on a click might block the game loop, e.g. when you load a level. Then it might be useful to load the level aysnchronously to be able to see the animation. Or you execute the handler code after the animation. Or you play the scale down animation on the press event and the scale up animation on the release event.
Technically you can use the build in animation editor, the Update() method, start a coroutine or use the assets iTween or HOTween.
http://docs.unity3d.com/ScriptReference/Transform-localScale.html
Let me know if you like the idea or questions arise.
Unity makes it easier now to do this using Unity Canvas UI. Instead of real 3d buttons, you could place a canvas UI in world space at the location where you want the buttons. Add a UI Panel to the canvas then add a UI Button.
Now, you have out of the box several clicking effects. The default it color tint, but you can choose sprite swap, or animation.
If you do want animation, when you select button animation it will create an animator for you. Click on your UI button Game Object in the scene hierarchy and open the animation window. You can choose Pressed animation from the drop down, and press RECORD button, then edit your buttons scale, say make it 0.75 for x,y,z. Now when you click on the button it will animate a cool scale down for you.
Sorry, I know that is a lot of information dumped! But you will find it pretty great once you start working with it in world space.
You can scale it down a tiny bit once click happen. For example:
void OnMouseDown() {
this.transform.localScale += new Vector3(0.05f, 0.05f, 0.05f);
}
Then after click scale it back to the original size.
Perhaps look into iTween (free on Unity Asset store).
Its very easy to use and you can produce some nice looking animations.
you can scale it when pressed or just change the color a little bit. On mouse up, rescale or recolor it.
void OnMouseDown()
{
transform.localScale -= new Vector3(0.05, 0.05 , 0);
//or
transform.GetComponent<SpriteRenderer>().color += new Color(40,40,40);
}
void OnMouseUp()
{
transform.localScale += new Vector3(0.05, 0.05 , 0);
//or
transform.GetComponent<SpriteRenderer>().color -= new Color(40,40,40);
}
You can implement your button using new Event system of unity. Here are the functions you can implement :
public class ExampleClass : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler
{
public void OnPointerEnter(PointerEventData eventData)
{
//it is the function when you hover your mouse to the object
//You can change the color of your object to make your users
//understand that it is not just a cube but also a clickable item
}
public void OnPointerExit(PointerEventData eventData)
{
//You can revert your color back to its original
}
public void OnPointerDown (PointerEventData eventData)
{
//You can play with local scale as suggested by other answers here
}
public void OnPointerUp (PointerEventData eventData)
{
// Revert back the changes you made at onPointerDown
}
public void OnPointerClick (PointerEventData eventData)
{
//Use here for operations when your button is clicked
}
}

Multiple leave events generated in Custom widget in Qt

I receive a Leave Event every time i move a pixel with my mouse over a customized QFrame i did. Why is this happening?.
I reimplemmented the leave and enter event as follows. As you can see i tried to comment the QFrame enterEvent, and restrict the repetition with a boolean, but it doesnt work because an enter and leave are continuously generated:
void enterEvent( QEvent *event ){
//QFrame::enterEvent(event);
if (!mouseHover_)
{
mouseHover_ = true;
emit hoverInSignal("");
}
}
void leaveEvent( QEvent *event ){
//QFrame::leaveEvent(event);
if (mouseHover_)
{
SmartUIWrapper::Instance()->addInfoMessage("out");
emit hoverOutSignal();
mouseHover_ = false;
}
}
Does it have something to be with the focus?
I discovered the reason.
I created a panel over this QFrame when i hovered.
When i moved the mouse, since the panel is positioned on the right bottom side of the cursor position, everytime i moved over the QFrame to the right or bottom, when i hovered this new panel i created, it looses the focus, so it gets closed again, then another hover comes, and then it´s created again... and again... everytime i hover the new panel.

How to override default behavior of the Zoom button in Qt?

I have an application written using Qt5 in Python (PyQt5).
I want to override default behavior of the zoom (green "+" at top left) so it will set appropriate size of the window rather than maximize it to cover all available space.
I tried to override showMaximize, but that method was never called. My window is a subclass of QWidget without any additional window flags set (i.e. defaults are used).
How can I override the event or how can I tell the layout system size I want to be set once user clicks that button?
You cannot override showMaximized because it is not virtual. There is no way to override this action. But you can override changeEvent. It will be called when user maximizes the window. You can reset normal window's position and adjust its size.
void MyWidget::changeEvent(QEvent *e) {
QWidget::changeEvent(e);
if (e->type() == QEvent::WindowStateChange) {
if (isMaximized()) {
showNormal();
resize(200, 200);
move(100, 100);
}
}
}

How to handle back button in windows phone 7?

I have an application, the main page contains few functions. To explain in detail - I have save, color palette button in my main page. When any of these buttons are clicked, save pop up or color palette appears. How to handle back button of the device, when color palette or save pop up is opened. When back button is pressed at these scenario it should just make them invisible and stay on the main page. When nothing is being performed in the main page, then it should come out of the app. I tried to make their visibility collapsed on back button press. But it still is coming out of the application.
Please, guide me in this. Thanks in advance.
Override PhoneApplicationPage.OnBackKeyPress and then set CancelEventArgs.Cancel to true if you want to stop it from actually going back.
protected override void OnBackKeyPress(CancelEventArgs args)
{
if (PanelIsShowing)
{
HidePanel();
args.Cancel = true;
}
}
The back button behaves as is intended by Microsoft.
If you change its behavior you risk your application not being certified for the Marketplace.
If you want the back button to close the popups, turn the popups into pages so the back button navigates back to the main page..
You need to use
protected override void OnBackKeyPress(CancelEventArgs e)
{
if (_popup.IsOpen)
{
_popup.IsOpen= false;
e.Cancel = true;
}
else
{
base.OnBackKeyPress(e);
}
}
That should do the trick.

How to handle the back button on Windows Phone 7

On the windows phone 7 emulator, when the hardware back button is pressed, the default behaviour is for it to close your current application. I want to override this default behaviour so that it navigates to the previous page in my application.
After some research, it seems it should be possible to do this by overriding the OnBackKeyPress method, like so:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
// do some stuff ...
// cancel the navigation
e.Cancel = true;
}
However, clicking the back button still closes my application. Putting a breakpoint on the above method reveals that it is never called. I have another breakpoint on my application exit code, and this breakpoint is hit.
Is there something else I need to do to intercept the back button?
It would appear that it's not possible to override the OnBackKeyPress method to intercept the back key unless you use the Navigate method to move between pages in your application.
My previous method of navigation was to change the root visual, like:
App.Current.RootVisual = new MyPage();
This meant I could keep all my pages in memory so I didn't need to cache the data stored on them (some of the data is collected over the net).
Now it seems I need to actually use the Navigate method on the page frame, which creates a new instance of the page I'm navigating to.
(App.Current.RootVisual as PhoneApplicationFrame).Navigate(
new Uri("/MyPage.xaml", UriKind.Relative));
Once I started navigating using this method, I could then override the back button handling in the way described in my question...
If you don't want the default back key behavior, set Cancel = true in the CancelEventArgs parameter in OnBackKeyPress. In my page, I've overridden the back button to close a web browser control instead of navigating back.
protected override void OnBackKeyPress(CancelEventArgs e)
{
if (Browser.Visibility == Visibility.Visible)
{
Browser.Visibility = Visibility.Collapsed;
e.Cancel = true;
}
}
I was able to use this technique to do what I wanted, which is to prevent back navigation while hiding a control that slides in and out of the window. By default, the control's visibility is collapsed. Storyboards are used to control when it becomes visible or collapsed. In XAML, inside the Storyboard:
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ControlScroller" Storyboard.TargetProperty="(UIElement.Visibility)">
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames.KeyFrames>
Then in the page's code:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
if(ControlScroller.Visibility == Visibility.Visible && StoryboardHideControlSlider.GetCurrentState() != ClockState.Active)
{
StoryboardHideControlSlider.Begin();
ContentGrid.IsHitTestVisible = true;
e.Cancel = true;
}
}
Note: In the Storyboard that hides the ContentScroller (which is a grid), the KeyTime is set to "00:00:01" because I want it to remain visible while it is sliding (and fading) out of view.
Note 2: The reason StoryboardHideControlSlider.GetCurrentState() != ClockState.Active is included in the if statement is because if the user hits the back button twice and the Storyboard hasn't completed it will run again. This prevents the backbutton cancelling navigation back to the previous page. So in other words, if the Storyboard is active, the code "knows" that the user has already initiated hiding it and intends to navigate back to the previous page. (Well, at least that's behavior they're going to get...and they won't see the animation twice)!

Resources