summaryrefslogtreecommitdiffstats
path: root/docs/release/src/osd/winui/tabview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'docs/release/src/osd/winui/tabview.cpp')
-rw-r--r--docs/release/src/osd/winui/tabview.cpp335
1 files changed, 335 insertions, 0 deletions
diff --git a/docs/release/src/osd/winui/tabview.cpp b/docs/release/src/osd/winui/tabview.cpp
new file mode 100644
index 00000000000..d5971275819
--- /dev/null
+++ b/docs/release/src/osd/winui/tabview.cpp
@@ -0,0 +1,335 @@
+// For licensing and usage information, read docs/winui_license.txt
+//****************************************************************************
+
+// standard windows headers
+#include <windows.h>
+#include <windowsx.h>
+#include <shellapi.h>
+#include <commctrl.h>
+#include <commdlg.h>
+#include <wingdi.h>
+
+// MAME/MAMEUI headers
+#include "winui.h"
+#include "tabview.h"
+#include "emu.h"
+#include "mui_util.h"
+#include "strconv.h"
+
+
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+
+
+struct TabViewInfo
+{
+ const struct TabViewCallbacks *pCallbacks;
+ int nTabCount;
+ WNDPROC pfnParentWndProc;
+};
+
+
+
+static struct TabViewInfo *GetTabViewInfo(HWND hWnd)
+{
+ LONG_PTR l;
+ l = GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ return (struct TabViewInfo *) l;
+}
+
+
+
+static LRESULT CallParentWndProc(WNDPROC pfnParentWndProc,
+ HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT rc;
+
+ if (!pfnParentWndProc)
+ pfnParentWndProc = GetTabViewInfo(hWnd)->pfnParentWndProc;
+
+ if (IsWindowUnicode(hWnd))
+ rc = CallWindowProcW(pfnParentWndProc, hWnd, message, wParam, lParam);
+ else
+ rc = CallWindowProcA(pfnParentWndProc, hWnd, message, wParam, lParam);
+ return rc;
+}
+
+
+
+static LRESULT CALLBACK TabViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ struct TabViewInfo *pTabViewInfo;
+ WNDPROC pfnParentWndProc;
+ BOOL bHandled = FALSE;
+ LRESULT rc = 0;
+
+ pTabViewInfo = GetTabViewInfo(hWnd);
+ pfnParentWndProc = pTabViewInfo->pfnParentWndProc;
+
+ switch(message)
+ {
+ case WM_DESTROY:
+ free(pTabViewInfo);
+ SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR) pfnParentWndProc);
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) NULL);
+ break;
+ }
+
+ if (!bHandled)
+ rc = CallParentWndProc(pfnParentWndProc, hWnd, message, wParam, lParam);
+
+ switch(message)
+ {
+ case WM_MOVE:
+ case WM_SIZE:
+ if (pTabViewInfo->pCallbacks->pfnOnMoveSize)
+ pTabViewInfo->pCallbacks->pfnOnMoveSize();
+ break;
+ }
+
+ return rc;
+}
+
+
+
+static int TabView_GetTabFromTabIndex(HWND hwndTabView, int tab_index)
+{
+ int shown_tabs = -1;
+ int i;
+ struct TabViewInfo *pTabViewInfo;
+
+ pTabViewInfo = GetTabViewInfo(hwndTabView);
+
+ for (i = 0; i < pTabViewInfo->nTabCount; i++)
+ {
+ if (!pTabViewInfo->pCallbacks->pfnGetShowTab || pTabViewInfo->pCallbacks->pfnGetShowTab(i))
+ {
+ shown_tabs++;
+ if (shown_tabs == tab_index)
+ return i;
+ }
+ }
+ dprintf("invalid tab index %i\n", tab_index);
+ return 0;
+}
+
+
+
+int TabView_GetCurrentTab(HWND hwndTabView)
+{
+ struct TabViewInfo *pTabViewInfo;
+ LPCSTR pszTab = NULL;
+ LPCSTR pszThatTab;
+ int i, nTab = -1;
+
+ pTabViewInfo = GetTabViewInfo(hwndTabView);
+
+ if (pTabViewInfo->pCallbacks->pfnGetCurrentTab)
+ pszTab = pTabViewInfo->pCallbacks->pfnGetCurrentTab();
+
+ if (pszTab)
+ {
+ if (pTabViewInfo->pCallbacks->pfnGetTabShortName)
+ {
+ for (i = 0; i < pTabViewInfo->nTabCount; i++)
+ {
+ pszThatTab = pTabViewInfo->pCallbacks->pfnGetTabShortName(i);
+ if (pszThatTab && !core_stricmp(pszTab, pszThatTab))
+ {
+ nTab = i;
+ break;
+ }
+ }
+ }
+ if (nTab < 0)
+ {
+ nTab = 0;
+ sscanf(pszTab, "%d", &nTab);
+ }
+ }
+ else
+ {
+ nTab = 0;
+ }
+ return nTab;
+}
+
+
+
+void TabView_SetCurrentTab(HWND hwndTabView, int nTab)
+{
+ struct TabViewInfo *pTabViewInfo;
+ LPCSTR pszName;
+ char szBuffer[16];
+
+ pTabViewInfo = GetTabViewInfo(hwndTabView);
+
+ if (pTabViewInfo->pCallbacks->pfnGetTabShortName)
+ {
+ pszName = pTabViewInfo->pCallbacks->pfnGetTabShortName(nTab);
+ }
+ else
+ {
+ snprintf(szBuffer, ARRAY_LENGTH(szBuffer),
+ "%d", nTab);
+ pszName = szBuffer;
+ }
+
+ if (pTabViewInfo->pCallbacks->pfnSetCurrentTab)
+ pTabViewInfo->pCallbacks->pfnSetCurrentTab(pszName);
+}
+
+
+
+static int TabView_GetCurrentTabIndex(HWND hwndTabView)
+{
+ int shown_tabs = 0;
+ int i;
+ int nCurrentTab;
+ struct TabViewInfo *pTabViewInfo;
+
+ pTabViewInfo = GetTabViewInfo(hwndTabView);
+ nCurrentTab = TabView_GetCurrentTab(hwndTabView);
+
+ for (i = 0; i < pTabViewInfo->nTabCount; i++)
+ {
+ if (i == nCurrentTab)
+ break;
+
+ if (!pTabViewInfo->pCallbacks->pfnGetShowTab || pTabViewInfo->pCallbacks->pfnGetShowTab(i))
+ shown_tabs++;
+ }
+ return shown_tabs;
+}
+
+
+
+void TabView_UpdateSelection(HWND hwndTabView)
+{
+ HRESULT res;
+ res = TabCtrl_SetCurSel(hwndTabView, TabView_GetCurrentTabIndex(hwndTabView));
+}
+
+
+
+BOOL TabView_HandleNotify(LPNMHDR lpNmHdr)
+{
+ HWND hwndTabView;
+ struct TabViewInfo *pTabViewInfo;
+ BOOL bResult = FALSE;
+ int nTabIndex, nTab;
+
+ hwndTabView = lpNmHdr->hwndFrom;
+ pTabViewInfo = GetTabViewInfo(hwndTabView);
+
+ switch (lpNmHdr->code)
+ {
+ case TCN_SELCHANGE:
+ nTabIndex = TabCtrl_GetCurSel(hwndTabView);
+ nTab = TabView_GetTabFromTabIndex(hwndTabView, nTabIndex);
+ TabView_SetCurrentTab(hwndTabView, nTab);
+ if (pTabViewInfo->pCallbacks->pfnOnSelectionChanged)
+ pTabViewInfo->pCallbacks->pfnOnSelectionChanged();
+ bResult = TRUE;
+ break;
+ }
+ return bResult;
+}
+
+
+
+void TabView_CalculateNextTab(HWND hwndTabView)
+{
+ struct TabViewInfo *pTabViewInfo;
+ int i;
+ int nCurrentTab;
+
+ pTabViewInfo = GetTabViewInfo(hwndTabView);
+
+ // at most loop once through all options
+ for (i = 0; i < pTabViewInfo->nTabCount; i++)
+ {
+ nCurrentTab = TabView_GetCurrentTab(hwndTabView);
+ TabView_SetCurrentTab(hwndTabView, (nCurrentTab + 1) % pTabViewInfo->nTabCount);
+ nCurrentTab = TabView_GetCurrentTab(hwndTabView);
+
+ if (!pTabViewInfo->pCallbacks->pfnGetShowTab || pTabViewInfo->pCallbacks->pfnGetShowTab(nCurrentTab))
+ {
+ // this tab is being shown, so we're all set
+ return;
+ }
+ }
+}
+
+
+
+void TabView_Reset(HWND hwndTabView)
+{
+ struct TabViewInfo *pTabViewInfo;
+ TC_ITEM tci;
+ int i;
+ TCHAR* t_text;
+ HRESULT res;
+ BOOL b_res;
+
+ pTabViewInfo = GetTabViewInfo(hwndTabView);
+
+ b_res = TabCtrl_DeleteAllItems(hwndTabView);
+
+ memset(&tci, 0, sizeof(tci));
+ tci.mask = TCIF_TEXT;
+ tci.cchTextMax = 20;
+
+ for (i = 0; i < pTabViewInfo->nTabCount; i++)
+ {
+ if (!pTabViewInfo->pCallbacks->pfnGetShowTab || pTabViewInfo->pCallbacks->pfnGetShowTab(i))
+ {
+ t_text = ui_wstring_from_utf8(pTabViewInfo->pCallbacks->pfnGetTabLongName(i));
+ if( !t_text )
+ return;
+ tci.pszText = t_text;
+ res = TabCtrl_InsertItem(hwndTabView, i, &tci);
+ free(t_text);
+ }
+ }
+ TabView_UpdateSelection(hwndTabView);
+}
+
+
+
+BOOL SetupTabView(HWND hwndTabView, const struct TabViewOptions *pOptions)
+{
+ struct TabViewInfo *pTabViewInfo;
+ LONG_PTR l;
+ BOOL bShowTabView;
+
+ assert(hwndTabView);
+
+ // Allocate the list view struct
+ pTabViewInfo = (struct TabViewInfo *) malloc(sizeof(struct TabViewInfo));
+ if (!pTabViewInfo)
+ return FALSE;
+
+ // And fill it out
+ memset(pTabViewInfo, 0, sizeof(*pTabViewInfo));
+ pTabViewInfo->pCallbacks = pOptions->pCallbacks;
+ pTabViewInfo->nTabCount = pOptions->nTabCount;
+
+ // Hook in our wndproc and userdata pointer
+ l = GetWindowLongPtr(hwndTabView, GWLP_WNDPROC);
+ pTabViewInfo->pfnParentWndProc = (WNDPROC) l;
+ SetWindowLongPtr(hwndTabView, GWLP_USERDATA, (LONG_PTR) pTabViewInfo);
+ SetWindowLongPtr(hwndTabView, GWLP_WNDPROC, (LONG_PTR) TabViewWndProc);
+
+ bShowTabView = pTabViewInfo->pCallbacks->pfnGetShowTabCtrl ?
+ pTabViewInfo->pCallbacks->pfnGetShowTabCtrl() : TRUE;
+ ShowWindow(hwndTabView, bShowTabView ? SW_SHOW : SW_HIDE);
+
+ TabView_Reset(hwndTabView);
+ if (pTabViewInfo->pCallbacks->pfnOnSelectionChanged)
+ pTabViewInfo->pCallbacks->pfnOnSelectionChanged();
+ return TRUE;
+}
+
+