]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Box art/screenshot window.
authorToni Wilen <twilen@winuae.net>
Sat, 9 Dec 2017 19:28:46 +0000 (21:28 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 9 Dec 2017 19:28:46 +0000 (21:28 +0200)
od-win32/win32.cpp
od-win32/win32gui.cpp
od-win32/win32gui.h
od-win32/win32gui_extra.cpp

index d524083789b451a8cd215b1c3000c1270e2d28d2..d956565e7cb9848904967e1076d529f085920aa8 100644 (file)
@@ -2745,6 +2745,19 @@ static int WIN32_RegisterClasses (void)
        if (!RegisterClass (&wc))
                return 0;
 
+       wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
+       wc.lpfnWndProc = BoxArtWindowProc;
+       wc.cbClsExtra = 0;
+       wc.cbWndExtra = DLGWINDOWEXTRA;
+       wc.hInstance = hInst;
+       wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_APPICON));
+       wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+       wc.hbrBackground = CreateSolidBrush(g_dwBackgroundColor);
+       wc.lpszMenuName = 0;
+       wc.lpszClassName = _T("BoxArt");
+       if (!RegisterClass(&wc))
+               return 0;
+
        wc.style = 0;
        wc.lpfnWndProc = HiddenWindowProc;
        wc.cbClsExtra = 0;
@@ -2771,7 +2784,6 @@ static int WIN32_RegisterClasses (void)
        if (!RegisterClass (&wc))
                return 0;
 
-
        hHiddenWnd = CreateWindowEx (0,
                _T("Useless"), _T("You don't see me"),
                WS_POPUP,
@@ -6866,9 +6878,9 @@ void systray (HWND hwnd, int remove)
        nid.cbSize = sizeof (nid);
        nid.hWnd = hwnd;
        nid.hIcon = LoadIcon (hInst, (LPCWSTR)MAKEINTRESOURCE (IDI_APPICON));
-       nid.uFlags = NIF_ICON | NIF_MESSAGE | (os_win7 ? NIF_GUID : 0);
+       nid.uFlags = NIF_ICON | NIF_MESSAGE | (os_win8 ? NIF_GUID : 0);
        nid.uCallbackMessage = WM_USER + 1;
-       if (os_win7) {
+       if (os_win8) {
                nid.guidItem = iconguid;
        }
        v = Shell_NotifyIcon (remove ? NIM_DELETE : NIM_ADD, &nid);
index 5b4c760dc62eec7aa83493f63b9c6d37f0513c5b..1d8664859b68b03c1d694ddac366e2f5a85f68db 100644 (file)
@@ -20019,10 +20019,10 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int       currentpage)
 #endif
 
 static int dialogreturn;
+static int devicechangetimer = -1;
 static INT_PTR CALLBACK DialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
        static int recursive = 0;
-       static int devicechangetimer;
        static int oldwidth, oldheight;
 
        switch (msg)
@@ -20043,8 +20043,15 @@ static INT_PTR CALLBACK DialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
                }
        }
        break;
+       case WM_MOVING:
+               move_box_art_window();
+               return FALSE;
+       case WM_MOVE:
+               move_box_art_window();
+               return TRUE;
        case WM_SIZING:
        {
+               close_box_art_window();
                if (!recursive && gui_resize_enabled) {
                        RECT *r = (RECT*)lParam;
                        if (r->right - r->left < MIN_GUI_INTERNAL_WIDTH)
@@ -20089,6 +20096,8 @@ static INT_PTR CALLBACK DialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
                                        doit = 1;
                        }
                        if (doit) {
+                               if (devicechangetimer < 0)
+                                       return TRUE;
                                if (devicechangetimer)
                                        KillTimer(hDlg, 3);
                                devicechangetimer = 1;
@@ -20100,10 +20109,15 @@ static INT_PTR CALLBACK DialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
                if (wParam == 3) {
                        KillTimer(hDlg, 3);
                        devicechangetimer = 0;
-                       inputdevice_devicechange (&workprefs);
-                       updatePanel (currentpage, 0);
-                       break;
+                       if (inputdevice_devicechange (&workprefs))
+                               updatePanel (currentpage, 0);
+               }
+               if (wParam == 4) {
+                       KillTimer(hDlg, 4);
+                       if (devicechangetimer < 0)
+                               devicechangetimer = 0;
                }
+               break;
 
        case WM_DESTROY:
                PostQuitMessage (0);
@@ -20114,6 +20128,7 @@ static INT_PTR CALLBACK DialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
                devicechangetimer = 0;
                addnotifications (hDlg, TRUE, TRUE);
                updatePanel (-1, 0);
+               show_box_art(NULL);
                DestroyWindow(hDlg);
                if (dialogreturn < 0) {
                        dialogreturn = 0;
@@ -20618,7 +20633,9 @@ static int GetSettings (int all_options, HWND hwnd)
                        MapDialogRect (dhwnd, &dialog_rect);
 
                        hGUIWnd = dhwnd;
-
+                       if (devicechangetimer < 0)
+                               SetTimer(dhwnd, 4, 2000, NULL);
+                       
                        for (;;) {
                                HANDLE IPChandle;
                                IPChandle = geteventhandleIPC (globalipc);
index 85cab43af14181cb91bc4def84aa46ae28633cce..a8f9f5b83cf6ad4acb13d69bcefe874df10f82b3 100644 (file)
@@ -40,7 +40,6 @@ extern void scaleresource_getmult (int *mx, int *my);
 extern HWND CustomCreateDialog (int templ, HWND hDlg, DLGPROC proc);
 extern INT_PTR CustomDialogBox (int templ, HWND hDlg, DLGPROC proc);
 extern struct newresource *getresource (int tmpl);
-extern struct newresource *resourcefont (struct newresource*, TCHAR *font, int size);
 extern void scaleresource_init (const TCHAR*, int);
 extern int scaleresource_choosefont (HWND hDlg, int fonttype);
 extern void scaleresource_setdefaults (void);
@@ -49,4 +48,7 @@ extern void scaleresource_getdpimult (double*, double*, int*, int*);
 extern void scalaresource_listview_font_info(int*);
 extern int getscaledfontsize(int size);
 extern bool show_box_art(const TCHAR*);
+extern void move_box_art_window(void);
+extern void close_box_art_window(void);
+extern LRESULT CALLBACK BoxArtWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
 #endif
index f547bea9f066224c24fda5bf821a110ce11b1872..02ad25b6e3e6f7b1e2451756d48395d06021fd66 100644 (file)
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <windows.h>
 #include <commctrl.h>
+#include <Dwmapi.h>
 
 #include "sysconfig.h"
 #include "sysdeps.h"
@@ -693,8 +694,22 @@ int scaleresource_choosefont (HWND hDlg, int fonttype)
 
 #include <gdiplus.h> 
 
+#define MAX_BOX_ART_IMAGES 12
+
 static bool boxart_inited;
 static ULONG_PTR gdiplusToken;
+static HWND boxarthwnd;
+static int boxart_window_width;
+static int boxart_window_height;
+static const int box_art_width = 400;
+static const int hgap = 10;
+static const int wgap = 10;
+static Gdiplus::Image *images[MAX_BOX_ART_IMAGES];
+static int total_height;
+static int max_width;
+static int total_images;
+static int imagemode;
+static bool imagemodereset;
 
 static void boxart_init(void)
 {
@@ -702,32 +717,236 @@ static void boxart_init(void)
        Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
 }
 
-static const TCHAR *boxartnames[] = {
+static const TCHAR *boxartnames[MAX_BOX_ART_IMAGES + 1] = {
        _T("Boxart"),
        _T("SShot"),
        _T("Title"),
+       _T("Misc1"),
+       _T("Misc2"),
+       _T("Misc3"),
+       _T("Misc4"),
+       _T("Misc5"),
+       _T("Misc6"),
+       _T("Misc7"),
+       _T("Misc8"),
+       _T("Misc9"),
        NULL
 };
 
+typedef HRESULT(CALLBACK* DWMGETWINDOWATTRIBUTE)(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute);
+static DWMGETWINDOWATTRIBUTE pDwmGetWindowAttribute;
+static HMODULE dwmapihandle;
+
+static void getpos(RECT *r)
+{
+       RECT r1, r2;
+       if (!pDwmGetWindowAttribute && !dwmapihandle && os_vista) {
+               dwmapihandle = LoadLibrary(_T("dwmapi.dll"));
+               if (dwmapihandle)
+                       pDwmGetWindowAttribute = (DWMGETWINDOWATTRIBUTE)GetProcAddress(dwmapihandle, "DwmGetWindowAttribute");
+       }
+
+       GetWindowRect(hGUIWnd, &r1);
+       r2 = r1;
+
+       if (pDwmGetWindowAttribute) {
+               pDwmGetWindowAttribute(hGUIWnd, DWMWA_EXTENDED_FRAME_BOUNDS, &r2, sizeof(r2));
+       }
+
+       r->left = r1.right - ((r2.left - r1.left) + (r1.right - r2.right));
+       r->top = r1.top;
+       r->bottom = r1.bottom;
+       r->right = r->left + box_art_width;
+}
+
+void move_box_art_window(void)
+{
+       RECT r;
+
+       if (!hGUIWnd || !boxarthwnd)
+               return;
+       getpos(&r);
+       SetWindowPos(boxarthwnd, HWND_TOPMOST, r.left, r.top, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOSIZE);
+}
+
+void close_box_art_window(void)
+{
+       for (int i = 0; boxartnames[i]; i++) {
+               if (images[i]) {
+                       delete images[i];
+                       images[i] = NULL;
+               }
+       }
+       if (!boxarthwnd)
+               return;
+       ShowWindow(boxarthwnd, SW_HIDE);
+       DestroyWindow(boxarthwnd);
+       boxarthwnd = NULL;
+}
+
+static bool open_box_art_window(void)
+{
+       RECT r;
+       
+       getpos(&r);
+       if (!boxarthwnd) {
+               DWORD exstyle = GetWindowLong(hGUIWnd, GWL_EXSTYLE);
+               DWORD style = GetWindowLong(hGUIWnd, GWL_STYLE);
+
+               style &= ~(WS_VISIBLE);
+
+               boxarthwnd = CreateWindowEx(exstyle | WS_EX_NOACTIVATE,
+                       _T("BoxArt"), _T("WinUAE"),
+                       style,
+                       r.left, r.top,
+                       box_art_width, r.bottom - r.top,
+                       hGUIWnd, NULL, hInst, NULL);
+               if (boxarthwnd) {
+                       RECT r;
+                       GetClientRect(boxarthwnd, &r);
+                       boxart_window_width = r.right - r.left;
+                       boxart_window_height = r.bottom - r.top;
+               }
+       } else {
+               move_box_art_window();
+       }
+
+       return boxarthwnd != 0;
+}
+
+static void boxartpaint(HDC hdc, HWND hwnd)
+{
+       if (!total_images)
+               return;
+
+       int image_count = total_images;
+       int image_total_height = total_height;
+
+       if (imagemode) {
+               int round = 0;
+               if (imagemode > MAX_BOX_ART_IMAGES) {
+                       if (imagemodereset) {
+                               imagemode = 0;
+                       } else {
+                               imagemode = 1;
+                       }
+               }
+               while (imagemode) {
+                       if (images[imagemode - 1]) {
+                               Gdiplus::Image *img = images[imagemode - 1];
+                               image_count = 1;
+                               image_total_height = img->GetHeight();
+                               img = NULL;
+                               break;
+                       }
+                       imagemode++;
+                       if (imagemode > MAX_BOX_ART_IMAGES) {
+                               if (imagemodereset) {
+                                       imagemode = 0;
+                               } else {
+                                       imagemode = 1;
+                               }
+                               round++;
+                       }
+                       if (round > 1) {
+                               imagemode = 0;
+                       }
+               }
+       }
+
+       int window_w = boxart_window_width - 2 * wgap;
+       int window_h = boxart_window_height - (image_count + 1) * hgap;
+
+       float scale;
+       float scalex = (float)window_w / max_width;
+       float scaley = (float)window_h / image_total_height;
+       if (scalex > 1)
+               scalex = 1;
+       scale = scalex;
+       if (scale > scaley)
+               scale = scaley;
+
+       Gdiplus::Graphics graphics(hdc);
+       int y = hgap;
+
+       Gdiplus::Pen pen(Gdiplus::Color(170, 170, 0, 0), 1);
+
+       for (int i = 0; boxartnames[i]; i++) {
+               if (imagemode && imagemode - 1 != i)
+                       continue;
+               if (images[i]) {
+                       Gdiplus::Image *img = images[i];
+                       int w = img->GetWidth();
+                       int h = img->GetHeight();
+
+                       w = (int)(w * scale + 0.5);
+                       h = (int)(h * scale + 0.5);
+
+                       int x1 = wgap + (window_w - w) / 2;
+                       int x2 = w;
+                       int y1 = y;
+                       int y2 = h;
+
+                       if (image_count == 1) {
+                               y1 = hgap + (window_h - h) / 2;
+                       }
+
+                       Gdiplus::Rect d(x1, y1, x2, y2);
+                       graphics.DrawImage(img, d);
+
+                       Gdiplus::Rect d2(x1 - 1, y1 - 1, x2 + 2, y2 + 2);
+                       graphics.DrawRectangle(&pen, d2);
+
+                       y += h;
+                       y += hgap;
+               }
+       }
+}
+
 bool show_box_art(const TCHAR *path)
 {
        TCHAR tmp1[MAX_DPATH];
 
-       if (!path || !artcache)
+       for (int i = 0; boxartnames[i]; i++) {
+               if (images[i]) {
+                       delete images[i];
+                       images[i] = NULL;
+               }
+       }
+
+       if (!path) {
+               close_box_art_window();
+               return false;
+       }
+       if (!artcache) {
                return false;
+       }
        if (!boxart_inited) {
                boxart_init();
                boxart_inited = true;
        }
 
+       if (isfullscreen() > 0 || !hGUIWnd) {
+               close_box_art_window();
+               return false;
+       }
+
+       if (!open_box_art_window())
+               return false;
+
+       total_height = 2 * hgap;
+       max_width = 0;
+       total_images = 0;
+
        write_log(_T("Box art path '%s'\n"), path);
        for (int i = 0; boxartnames[i]; i++) {
+               Gdiplus::Image *image;
                _tcscpy(tmp1, path);
                _tcscat(tmp1, _T("___"));
                _tcscat(tmp1, boxartnames[i]);
                _tcscat(tmp1, _T(".png"));
 
-               Gdiplus::Image *image = Gdiplus::Image::FromFile(tmp1);
+               image = Gdiplus::Image::FromFile(tmp1);
                // above returns out of memory if file does not exist!
                if (image->GetLastStatus() != Gdiplus::Ok) {
                        _tcscpy(tmp1 + _tcslen(tmp1) - 3, _T("jpg"));
@@ -737,8 +956,73 @@ bool show_box_art(const TCHAR *path)
                        int w = image->GetWidth();
                        int h = image->GetHeight();
                        write_log(_T("Image '%s' loaded %d*%d\n"), tmp1, w, h);
+                       images[i] = image;
+                       if (w > max_width)
+                               max_width = w;
+                       total_height += h;
+                       total_images++;
+               } else {
+                       delete image;
+                       images[i] = NULL;
                }
-               delete image;
+               image = NULL;
        }
+
+       if (!total_images)
+               return false;
+
+       total_height += hgap * (total_images - 1);
+
+       ShowWindow(boxarthwnd, SW_SHOWNOACTIVATE);
+
        return true;
 }
+
+LRESULT CALLBACK BoxArtWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+       switch (message)
+       {
+               case WM_LBUTTONDOWN:
+                       imagemode++;
+                       imagemodereset = false;
+                       InvalidateRect(hWnd, NULL, TRUE);
+               break;
+               case WM_RBUTTONDOWN:
+                       imagemode = imagemode ? 0 : 1;
+                       imagemodereset = false;
+                       InvalidateRect(hWnd, NULL, TRUE);
+               break;
+               case WM_PAINT:
+               {
+                       PAINTSTRUCT ps;
+                       HDC hDC = BeginPaint(hWnd, &ps);
+                       boxartpaint(hDC, hWnd);
+                       EndPaint(hWnd, &ps);
+               }
+               break;
+               case WM_CLOSE:
+                       close_box_art_window();
+               return 0;
+               case WM_CHAR:
+                       if (wParam == 27)
+                               DestroyWindow(hWnd);
+                       if (wParam == ' ') {
+                               imagemode++;
+                               imagemodereset = true;
+                               InvalidateRect(hWnd, NULL, TRUE);
+                       }
+                       break;
+               case WM_SIZING:
+               case WM_MOVING:
+               {
+                       RECT *r = (RECT*)lParam, r2;
+                       getpos(&r2);
+                       r->left = r2.left;
+                       r->top = r2.top;
+                       r->right = r2.right;
+                       r->bottom = r2.bottom;
+               }
+               return FALSE;
+       }
+       return DefWindowProc(hWnd, message, wParam, lParam);
+}