This example demonstrates how the use of the XPLMSetWindowGravity()
API to cause your window to dynamically resize based on the X-Plane window’s size.
- Download as a project for Xcode 14 or newer (64-bit Intel)
- Download as a project for Microsoft Visual Studio 2017 (64-bit; requires Windows 8.1 SDK)
- Download as a project for GCC 4.x/Linux (64-bit)
#include "XPLMDisplay.h"
#include "XPLMGraphics.h"
#include <string.h>
#include <stdio.h>
#if IBM
#include <windows.h>
#endif
#if LIN
#include <GL/gl.h>
#elif __GNUC__
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
#ifndef XPLM300
#error This is made to be compiled against the XPLM300 SDK
#endif
static XPLMWindowID g_window;
void draw(XPLMWindowID in_window_id, void * in_refcon);
int dummy_mouse_handler(XPLMWindowID in_window_id, int x, int y, int is_down, void * in_refcon) { return 0; }
XPLMCursorStatus dummy_cursor_status_handler(XPLMWindowID in_window_id, int x, int y, void * in_refcon) { return xplm_CursorDefault; }
int dummy_wheel_handler(XPLMWindowID in_window_id, int x, int y, int wheel, int clicks, void * in_refcon) { return 0; }
void dummy_key_handler(XPLMWindowID in_window_id, char key, XPLMKeyFlags flags, char virtual_key, void * in_refcon, int losing_focus) { }
PLUGIN_API int XPluginStart(
char * outName,
char * outSig,
char * outDesc)
{
strcpy(outName, "GravitySamplePlugin");
strcpy(outSig, "xpsdk.examples.gravitysampleplugin");
strcpy(outDesc, "A test plug-in that demonstrates the gravity features of the X-Plane 11 GUI plugin API.");
// We're not guaranteed that the main monitor's lower left is at (0, 0)... we'll need to query for the global desktop bounds!
int global_desktop_bounds[4]; // left, bottom, right, top
XPLMGetScreenBoundsGlobal(&global_desktop_bounds[0], &global_desktop_bounds[3], &global_desktop_bounds[2], &global_desktop_bounds[1]);
XPLMCreateWindow_t params;
params.structSize = sizeof(params);
// Set the window bounds such that we stretch the full *width* of the global desktop, and cover the top 200 bx
params.left = global_desktop_bounds[0];
params.bottom = global_desktop_bounds[3] - 200;
params.right = global_desktop_bounds[2];
params.top = global_desktop_bounds[3];
params.visible = 1;
params.drawWindowFunc = draw;
params.handleMouseClickFunc = dummy_mouse_handler;
params.handleRightClickFunc = dummy_mouse_handler;
params.handleMouseWheelFunc = dummy_wheel_handler;
params.handleKeyFunc = dummy_key_handler;
params.handleCursorFunc = dummy_cursor_status_handler;
params.refcon = NULL;
params.layer = xplm_WindowLayerFlightOverlay; // stick our window beneath all floating windows (like the X-Plane 11 map)
params.decorateAsFloatingWindow = 0;
g_window = XPLMCreateWindowEx(¶ms);
XPLMSetWindowPositioningMode(g_window, xplm_WindowPositionFree, -1);
// As the X-Plane window resizes, glue our left and right edges to the sides of the screen
// (causing our width to grow and shrink to match the window size), but keep a constant
// height for our window (with the same y position relative to the window's top).
XPLMSetWindowGravity(g_window, 0, 1, 1, 1);
return (g_window != NULL);
}
PLUGIN_API void XPluginStop(void)
{
// Since we created the window, we'll be good citizens and clean it up
XPLMDestroyWindow(g_window);
g_window = NULL;
}
PLUGIN_API void XPluginDisable(void) { }
PLUGIN_API int XPluginEnable(void) { return 1; }
PLUGIN_API void XPluginReceiveMessage(XPLMPluginID inFrom, int inMsg, void * inParam) { }
void draw(XPLMWindowID in_window_id, void * in_refcon)
{
XPLMSetGraphicsState(
0 /* no fog */,
0 /* 0 texture units */,
0 /* no lighting */,
0 /* no alpha testing */,
1 /* do alpha blend */,
1 /* do depth testing */,
0 /* no depth writing */
);
int b[4];
XPLMGetWindowGeometry(in_window_id, &b[0], &b[3], &b[2], &b[1]);
// Draw our window's translucent background overlay
XPLMDrawTranslucentDarkBox(b[0], b[3], b[2], b[1]);
// Display the window bounds (centered within the window)
char scratch_buffer[150];
sprintf(scratch_buffer, "Window bounds: %d %d %d %d", b[0], b[1], b[2], b[3]);
float col_white[] = {1.0, 1.0, 1.0};
int text_width = XPLMMeasureString(xplmFont_Proportional, scratch_buffer, strlen(scratch_buffer));
float text_midpoint_x = (b[2] + b[0]) / 2;
XPLMDrawString(col_white, text_midpoint_x - text_width / 2, (b[3] + b[1]) / 2, scratch_buffer, NULL, xplmFont_Proportional);
}
Thanks a lot Tyler,
What’s about using it on X-Plane v10 ?
Probably a stupid question but where we can download the last SDK please ?
Cheers
Stef
Shhh… you’ve found my super-secret SDK version 3.0 samples. 🙂 Version 3 of the SDK will be released with the impending X-Plane 11.10 release. (Watch the blog for an announcement on where to get it.)
There are no plans to backport new SDK functionality to X-Plane 10, though.
Ah. Being stealthy, are we? 😉
So the SDK will be updated sooner rather than later! That’s really good news – and very important for commercial devs to know. New toys to play with, new ways to break old toys.
Joy?
Watching the blog like a hawk. 😀
Hoo, I’m happy. Don’t worry, I’ll say no word 🙂
I’m impatient to read more, The way appears to be simple to use and I’m sure you will enjoy plugin developers with that. GoodWay will be HAPPY to use it 🙂
Don’t worry, Shhhhhh…. 🙂 THANKS !!!!!
Cheers
Stef
Tyler,
Is there a list of enhancements you are planning for the new SDK? I’m interested being able to create undocked windows and have scale-able fonts using XPStandardWidgets.
I’ also interested if we have a bit more control over the mouse events, like a right mouse click.
Mark
As we get closer to the 11.10b1 release, we’ll put out a blog post detailing all the new SDK features. 🙂
I found the new SDK 3.0.0 but found that the release notes are not updated.
Thanks Bill