Save and restore window position of a LibGDX application (LWJGL) - window

I want to restore the position and size of my LibGDX application (LwjglApplication) window when started again.
I know that I can use LwjglApplicationConfiguration to set the position of the window before creating it as follows:
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
cfg.x = lastX;
cfg.y = lasty;
LwjglApplication a = new LwjglApplication(new MyGame(), cfg);
But how can I read the last position of the window before quitting? The user might have moved and resized the window while playing my game. How to save the data?
Thanks a lot!

The only way I found is to use the LWJGL class Display (Javadoc) with methods getX() and getY() as you can see here:
int x = Display.getX();
int y = Display.getY();

Related

FlxSpriteGroup is not visible (haxeflixel)

I'm trying to create some sort of "item displayer" in a game to showcase items or act as an icon in the inventory (it will include informations like item tier, item name, exc).
To achieve this, i wanted to create a ItemDisplay class extending FlxSpriteGroup, and put inside it the frame, background and info for the item as Sprites, so that i would be able to work with all as if they were a single Sprite.
So i did just that, but the group isn't showing up when the ItemDisplay object is created and supposedly added to the FlxState.
After some troubleshooting, i discovered that the object exists, but isOnScreen() returns false, and i don't know why.
Here's the code i'm using to create the ItemDisplay object:
var itd:ItemDisplay = new ItemDisplay(FlxG.width / 2, FlxG.height / 2, test_sword);
add(itd);
...and here's the ItemDisplay class in all it's glory:
class ItemDisplay extends FlxSpriteGroup
{
override public function new(posX:Float, posY:Float, itemToShow:Item)
{
super();
x = posX;
y = posY;
// create sprites
var bckgr:FlxSprite = new FlxSprite(x, y);
var itPng:FlxSprite = new FlxSprite(x, y);
var itFrm:FlxSprite = new FlxSprite(x, y);
// load sprites graphics (problem's not here, i checked)
bckgr.loadGraphic("assets/images/ui/item_framing/ifbg_" + itemToShow.tier + "Tier.png");
itPng.loadGraphic(itemToShow.pngPath);
itFrm.loadGraphic("assets/images/ui/item_framing/item_frame.png");
// add all sprites to group
this.add(bckgr);
this.add(itPng);
this.add(itFrm);
}
}
(i'm running the code on macos, not HTML5)
If you have any idea why the ItemDisplay is not showing up, please explain it to me, as i'm not that good of a programmer, and i might have missed something.
Thank you ^-^
Nvm, as i thought, it was my stupid error: when creating the sprites in lines 10-12, i set their positions to X and Y, to make them the same as the group positions.
I just found out that the sprites consider the group's x and y as (0, 0), and start calculating their position from there.
So, by setting the sprites' x/y the same as the group's, i was essentially doubling the values, and putting the sprites outside of the screen
lmao sorry for bad english

UWP app with multiple views with different sizes

I have a UWP app. I want to be ale to create new windows from the app, but any subsequent window needs to be a specific smaller size compared to the main window. I don't do anything with regards to sizing the main window and let the OS take care of sizing it for me.
I bring up a new window like this:
auto window = CoreApplication::CreateNewView();
window->show();
void NewWindow::show() {
auto currView = ApplicationView::GetForCurrentView();
currView->PreferredLaunchViewSize =
Windows::Foundation::Size(float(options.width), float(options.height));
currView->PreferredLaunchWindowingMode = ApplicationViewWindowingMode::PreferredLaunchViewSize;
currView->SetPreferredMinSize(Size(20,20));
Xaml::Window::Current->Activate();
ApplicationViewSwitcher::TryShowAsStandaloneAsync(
window_->id(),
ViewSizePreference::Default,
window_->parentId(),
ViewSizePreference::Default);
}
When the main window comes up, it comes up just fine. When I click on a button which gets to this function, the new window comes up in the same size as the main window. I reopen the app, but now the main window shows up in the size I wanted the new window to show up in. Then clicking the button to bring up the new window brings up the new window in the size I wanted it in. So I am a bit confused. Am I setting the sizes the right way? Is there anything else glaringly wrong here?
As # Raymond Chen said, PreferredLaunchViewSize set the size when the app launches, it will change the size of your main window. And you can use ApplicationView.TryResizeView method to set the size of new window.
For example:
auto parentView = ApplicationView::GetForCurrentView();
auto newView = CoreApplication::CreateNewView();
newView->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this,parentView]()
{
int newViewId = 0;
Windows::UI::Xaml::Controls::Frame^ rootFrame = ref new Windows::UI::Xaml::Controls::Frame();
rootFrame->Navigate(Windows::UI::Xaml::Interop::TypeName(MainPage::typeid), nullptr);
Window::Current->Content = rootFrame;
// You have to activate the window in order to show it later.
Window::Current->Activate();
newViewId = ApplicationView::GetForCurrentView()->Id;
IAsyncOperation<bool>^ mytask = ApplicationViewSwitcher::TryShowAsStandaloneAsync(newViewId);
auto deviceEnumTask = concurrency::create_task(mytask);
deviceEnumTask.then([this](bool res)
{
// set the size of new window
ApplicationView::GetForCurrentView()->TryResizeView(Size(600, 320));
});
}));

Storyboard-Animating a Grid from CodeBehind

I need a MenuBar on the left side of my screen that can slide in and out. As this app is crossplattform it should be on the left side and not like the usual ApplicationBar on the Bottom or NavigationBar on Top.
What I have so far is:
private bool isTapped = false;
private void TEST_TAP(object sender, TappedRoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("TAP");
Storyboard s = new Storyboard();
DoubleAnimation doubleAni = new DoubleAnimation();
doubleAni.To = -30;
if (isTapped) doubleAni.To = 0;
doubleAni.Duration = new Duration(TimeSpan.FromMilliseconds(500));
Storyboard.SetTarget(doubleAni, LOGO);
Storyboard.SetTargetProperty(doubleAni, "(UIElement.RenderTransform).(TranslateTransform.XProperty)");
s.Children.Add(doubleAni);
s.Begin();
}
The bar I want to move is a Grid or should be something similar. But this even fails to move a single Image. I googled a bit and replaced "(UIElement.RenderTransform).(TranslateTransform.XProperty)" with "(Canvas.Left)". This doesn't crash but also doesn't move anything else.
Any ideas or solutions?
EDIT:
Well I played around a lot and now I know (and tested it) that "(Canvas.Left)" only works inside of a Canvas. Yay.
My App looks like this: Scrollview (horizontal) and inside is a Grid with columns to display different stuff. The left-most Column contains another Grid that I want to move out of the screen and back in again. But how do I move a grid with Storyboard-animation?
If anybody thinks of a different way to do this, I'm totally happy if it works in any way.
EDIT2:
It seems to be THE way to use Storyboard.SetTargetProperty(doubleAni, "(UIElement.RenderTransform).(CompositeTransform.TranslateX)"); but it keeps crashing =/
Before using this transform you need to add it:
Storyboard s = new Storyboard();
DoubleAnimation doubleAni = new DoubleAnimation();
doubleAni.To = to;
doubleAni.From = from;
doubleAni.Duration = new Duration(TimeSpan.FromMilliseconds(250));
// THIS LINE IS NEW
NaviBar.RenderTransform = new CompositeTransform();
Storyboard.SetTarget(doubleAni, NaviBar);
Storyboard.SetTargetProperty(doubleAni, "(UIElement.RenderTransform).(CompositeTransform.TranslateX)");
s.Children.Add(doubleAni);
s.Begin();
This does the trick. It's still not the functionality that I wanted but the hardest part - the animation - works now.

Map tap event / mouse down event in windows phone 8?

I am using the windows phone emulator. I wrote a very simple program: draw a marker on the map when the user tap the map once.
Then I used map_tap event, and get the tapped location as follows,
private void map_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
Point p = e.GetPosition(null);
GeoCoordinate s = map.ConvertViewportPointToGeoCoordinate(p);
Ellipse myCircle = new Ellipse();
myCircle.Fill = new SolidColorBrush(Colors.Blue);
myCircle.Height = 20;
myCircle.Width = 20;
myCircle.Opacity = 50;
MapOverlay myLocationOverlay = new MapOverlay();
myLocationOverlay.Content = myCircle;
myLocationOverlay.PositionOrigin = new Point(0, 0);
myLocationOverlay.GeoCoordinate = s;
MapLayer myLocationLayer = new MapLayer();
myLocationLayer.Add(myLocationOverlay);
map.Layers.Add(myLocationLayer);
}
The problem is that, the point I get is not the point where the mouse (in the emulator it is a mouse but not a finger) clicked. It is some distance lower (about 50 pixels lower) than where I clicked.
So wherever I click in the emulator, the circle is drawn below where I clicked, it's some kind of weird.
Is there anything wrong with my code?
Thank you very much.
The GestureEventArgs.GetPosition() method takes a parameter specifying what UIElement to get the coordinate relative to (see the MSDN documentation). So, try doing
Point p = e.GetPosition(map);
instead.

Making a JLabel become another JLabel

So, here is my problem. I have a JPanel, with a JLabel on it, and what I want is once that JLabel is clicked, it should resize, (ideally it will change with it's scale, but for now I am using a constant value). I have returned the image, and I now that I am able to scale it, but I just cant manage to make the original JLabel become the newly sized one.
So this is what should happen ideally, e.getSource should become the newly increased in size JLabel.
I know I'm pretty close, I did a JOptionPane as a debug statement to see if I can increase the size, and I can.
Why cant ((JLabel)me.getSource = a;
where a is my new JLabel?
Anyways, here is my code:
Please help me out.
public void mousePressed(MouseEvent me) {
//GreetingCard.setBackground.findComponentAt(me.getX(), me.getY());
//GreetingCard.setBackground.findComponentAt(me.getX(), me.getY)
JLabel a= (JLabel) me.getSource();
Icon icon = a.getIcon();
int scale = 4;
BufferedImage bi = new BufferedImage(
scale*icon.getIconWidth(),
scale*icon.getIconHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.scale(scale,scale);
icon.paintIcon(null,g,0,0);
g.dispose();
JLabel temp = new JLabel(new ImageIcon(bi));
((JLabel)me.getSource())= temp;
JOptionPane.showMessageDialog(
null,
new JLabel(new ImageIcon(bi)));
System.out.println("The size of the image is" + b.getIconWidth());
initiateEvent = me;
me.consume();
}
me.getSource() returns a JLabel, it doesn´t return a variable you can assign a new value.
Probably the best way is not to create a new JLabel but just assign the new ImageIcon to the old JLabel.
((JLabel)me.getSource()).setIcon(new ImageIcon(bi));
You also need to call label or panel updateUI() to force a "hard" repaint with resizing.

Resources