-use TabControl for bottom tabs

-show/hide bottom tabs with ctrl+x
This commit is contained in:
Kingcom 2013-09-30 10:40:15 +02:00
parent d4b05f1763
commit f41e5a3867
8 changed files with 98 additions and 119 deletions

View File

@ -75,6 +75,7 @@ CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Di
cpu = _cpu;
lastTicks = CoreTiming::GetTicks();
keepStatusBarText = false;
hideBottomTabs = false;
SetWindowText(m_hDlg, ConvertUTF8ToWString(_cpu->GetName()).c_str());
#ifdef THEMES
@ -125,25 +126,28 @@ CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Di
DefGotoEditProc = (WNDPROC)GetWindowLongPtr(editWnd,GWLP_WNDPROC);
SetWindowLongPtr(editWnd,GWLP_WNDPROC,(LONG_PTR)GotoEditProc);
// init bottom tabs
bottomTabs = new TabControl(GetDlgItem(m_hDlg,IDC_DEBUG_BOTTOMTABS));
// init memory viewer
CtrlMemView *mem = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW));
HWND memHandle = GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW);
CtrlMemView *mem = CtrlMemView::getFrom(memHandle);
mem->setDebugger(_cpu);
bottomTabs->AddTab(memHandle,L"Memory");
breakpointList = new CtrlBreakpointList(GetDlgItem(m_hDlg,IDC_BREAKPOINTLIST));
breakpointList->setCpu(cpu);
breakpointList->setDisasm(ptr);
breakpointList = new CtrlBreakpointList(GetDlgItem(m_hDlg,IDC_BREAKPOINTLIST),cpu,ptr);
breakpointList->reloadBreakpoints();
bottomTabs->AddTab(breakpointList->GetHandle(),L"Breakpoints");
threadList = new CtrlThreadList(GetDlgItem(m_hDlg,IDC_THREADLIST));
threadList->reloadThreads();
bottomTabs->AddTab(threadList->GetHandle(),L"Threads");
stackTraceView = new CtrlStackTraceView(GetDlgItem(m_hDlg,IDC_STACKFRAMES));
stackTraceView->setCpu(cpu);
stackTraceView->setDisasm(ptr);
stackTraceView = new CtrlStackTraceView(GetDlgItem(m_hDlg,IDC_STACKFRAMES),cpu,ptr);
stackTraceView->loadStackTrace();
bottomTabs->AddTab(stackTraceView->GetHandle(),L"Stack frames");
// init bottom "tab"
changeSubWindow(SUBWIN_FIRST);
bottomTabs->ShowTab(memHandle);
// init status bar
statusBarWnd = CreateStatusWindow(WS_CHILD | WS_VISIBLE, L"", m_hDlg, IDC_DISASMSTATUSBAR);
@ -164,63 +168,6 @@ CDisasm::~CDisasm()
{
}
void CDisasm::changeSubWindow(SubWindowType type)
{
HWND bp = GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST);
HWND mem = GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW);
HWND threads = GetDlgItem(m_hDlg, IDC_THREADLIST);
HWND stackFrames = GetDlgItem(m_hDlg, IDC_STACKFRAMES);
// determine if any of the windows are focused, if not
// then leave the focus unchanged
HWND focus = GetFocus();
bool changeFocus = (focus == bp || focus == mem || focus == threads || focus == stackFrames);
if (type == SUBWIN_FIRST)
{
type = SUBWIN_MEM;
} else if (type == SUBWIN_NEXT)
{
if (IsWindowVisible(mem))
{
type = SUBWIN_BREAKPOINT;
} else if (IsWindowVisible(bp))
{
type = SUBWIN_THREADS;
} else if (IsWindowVisible(threads))
{
type = SUBWIN_STACKFRAMES;
} else {
type = SUBWIN_MEM;
}
}
ShowWindow(mem,type == SUBWIN_MEM ? SW_NORMAL : SW_HIDE);
ShowWindow(bp,type == SUBWIN_BREAKPOINT ? SW_NORMAL : SW_HIDE);
ShowWindow(threads,type == SUBWIN_THREADS ? SW_NORMAL : SW_HIDE);
ShowWindow(stackFrames,type == SUBWIN_STACKFRAMES ? SW_NORMAL : SW_HIDE);
if (changeFocus)
{
switch (type)
{
case SUBWIN_MEM:
SetFocus(mem);
break;
case SUBWIN_BREAKPOINT:
SetFocus(bp);
break;
case SUBWIN_THREADS:
SetFocus(threads);
break;
case SUBWIN_STACKFRAMES:
SetFocus(stackFrames);
break;
}
}
}
void CDisasm::stepInto()
{
if (!Core_IsStepping()) return;
@ -379,6 +326,9 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
case IDC_STACKFRAMES:
stackTraceView->HandleNotify(lParam);
break;
case IDC_DEBUG_BOTTOMTABS:
bottomTabs->HandleNotify(lParam);
break;
}
break;
case WM_COMMAND:
@ -392,19 +342,19 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
break;
case ID_DEBUG_DISPLAYMEMVIEW:
changeSubWindow(SUBWIN_MEM);
bottomTabs->ShowTab(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW));
break;
case ID_DEBUG_DISPLAYBREAKPOINTLIST:
changeSubWindow(SUBWIN_BREAKPOINT);
bottomTabs->ShowTab(breakpointList->GetHandle());
break;
case ID_DEBUG_DISPLAYTHREADLIST:
changeSubWindow(SUBWIN_THREADS);
bottomTabs->ShowTab(threadList->GetHandle());
break;
case ID_DEBUG_DISPLAYSTACKFRAMELIST:
changeSubWindow(SUBWIN_STACKFRAMES);
bottomTabs->ShowTab(stackTraceView->GetHandle());
break;
case ID_DEBUG_DSIPLAYREGISTERLIST:
@ -458,6 +408,15 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) stepOut();
break;
case ID_DEBUG_HIDEBOTTOMTABS:
{
RECT rect;
hideBottomTabs = !hideBottomTabs;
GetClientRect(m_hDlg,&rect);
UpdateSize(rect.right-rect.left,rect.bottom-rect.top);
}
break;
case IDC_SHOWVFPU:
vfpudlg->Show(true);
break;
@ -655,8 +614,10 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
return TRUE;
case WM_DEB_TABPRESSED:
changeSubWindow(SUBWIN_NEXT);
bottomTabs->NextTab(true);
SetFocus(bottomTabs->CurrentTabHandle());
break;
case WM_DEB_SETSTATUSBARTEXT:
if (!keepStatusBarText)
SendMessage(statusBarWnd,WM_SETTEXT,0,(LPARAM)ConvertUTF8ToWString((const char *)lParam).c_str());
@ -739,12 +700,7 @@ void CDisasm::UpdateSize(WORD width, WORD height)
GetDlgItem(m_hDlg, IDC_REGLIST)
};
HWND bottomTabs[4] = {
GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW),
GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST),
GetDlgItem(m_hDlg, IDC_THREADLIST),
GetDlgItem(m_hDlg,IDC_STACKFRAMES)
};
HWND bottomTabs = GetDlgItem(m_hDlg, IDC_DEBUG_BOTTOMTABS);
// ignore the status bar
int topHeightOffset = 0;
@ -768,10 +724,12 @@ void CDisasm::UpdateSize(WORD width, WORD height)
positions[1].w = windowRect.right-windowRect.left;
int borderMargin = positions[1].x;
float weight = hideBottomTabs ? 1.f : 390.f/500.f;
// don't use the part above the disassembly for the computations
int bottomHeightOffset = positions[0].y;
positions[0].w = width-borderMargin-positions[0].x;
positions[0].h = (height-bottomHeightOffset-topHeightOffset) * 390./500.;
positions[0].h = (height-bottomHeightOffset-topHeightOffset) * weight;
positions[1].h = positions[0].h-(positions[1].y-positions[0].y);
// bottom tabs
@ -788,10 +746,16 @@ void CDisasm::UpdateSize(WORD width, WORD height)
MoveWindow(leftTabs[i],positions[1].x,positions[1].y,positions[1].w,positions[1].h,TRUE);
}
for (int i = 0; i < 4; i++)
{
MoveWindow(bottomTabs[i],positions[2].x,positions[2].y,positions[2].w,positions[2].h,TRUE);
}
MoveWindow(bottomTabs,positions[2].x,positions[2].y,positions[2].w,positions[2].h,TRUE);
ShowWindow(bottomTabs,hideBottomTabs ? SW_HIDE : SW_NORMAL);
RECT tabRect;
HWND hwnd = GetDlgItem(m_hDlg,IDC_LEFTTABS);
GetWindowRect(hwnd,&tabRect);
MapWindowPoints(HWND_DESKTOP,hwnd,(LPPOINT)&tabRect,2);
TabCtrl_AdjustRect(hwnd, FALSE, &tabRect);
printf("");
}
void CDisasm::SavePosition()

View File

@ -4,6 +4,7 @@
#define _DISASM_H
#include "Windows/W32Util/DialogManager.h"
#include "Windows/W32Util/TabControl.h"
#include "Windows/Debugger/CtrlDisasmView.h"
#include "Windows/Debugger/Debugger_Lists.h"
#include "Windows/Debugger/CPURegsInterface.h"
@ -18,10 +19,6 @@
class CDisasm : public Dialog
{
private:
typedef enum { SUBWIN_MEM, SUBWIN_BREAKPOINT, SUBWIN_THREADS, SUBWIN_STACKFRAMES,
// pseudo controls
SUBWIN_NEXT, SUBWIN_FIRST } SubWindowType;
int minWidth,minHeight;
DebugInterface *cpu;
u64 lastTicks;
@ -30,15 +27,16 @@ private:
CtrlBreakpointList* breakpointList;
CtrlThreadList* threadList;
CtrlStackTraceView* stackTraceView;
TabControl* bottomTabs;
std::vector<BreakPoint> displayedBreakPoints_;
std::vector<MemCheck> displayedMemChecks_;
bool keepStatusBarText;
bool hideBottomTabs;
BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam);
void UpdateSize(WORD width, WORD height);
void SavePosition();
void updateThreadLabel(bool clear);
void changeSubWindow(SubWindowType type);
void stepInto();
void stepOver();
void stepOut();

View File

@ -230,7 +230,8 @@ const char* CtrlThreadList::getCurrentThreadName()
// CtrlBreakpointList
//
CtrlBreakpointList::CtrlBreakpointList(HWND hwnd): GenericListControl(hwnd,breakpointColumns,BPL_COLUMNCOUNT)
CtrlBreakpointList::CtrlBreakpointList(HWND hwnd, DebugInterface* cpu, CtrlDisAsmView* disasm)
: GenericListControl(hwnd,breakpointColumns,BPL_COLUMNCOUNT),cpu(cpu),disasm(disasm)
{
SetSendInvalidRows(true);
Update();
@ -582,7 +583,8 @@ void CtrlBreakpointList::showBreakpointMenu(int itemIndex, const POINT &pt)
// CtrlStackTraceView
//
CtrlStackTraceView::CtrlStackTraceView(HWND hwnd): GenericListControl(hwnd,stackTraceColumns,SF_COLUMNCOUNT)
CtrlStackTraceView::CtrlStackTraceView(HWND hwnd, DebugInterface* cpu, CtrlDisAsmView* disasm)
: GenericListControl(hwnd,stackTraceColumns,SF_COLUMNCOUNT),cpu(cpu),disasm(disasm)
{
Update();
}

View File

@ -28,16 +28,8 @@ class CtrlDisAsmView;
class CtrlBreakpointList: public GenericListControl
{
public:
CtrlBreakpointList(HWND hwnd);
CtrlBreakpointList(HWND hwnd, DebugInterface* cpu, CtrlDisAsmView* disasm);
void reloadBreakpoints();
void setCpu(DebugInterface* cpu)
{
this->cpu = cpu;
};
void setDisasm(CtrlDisAsmView* disasm)
{
this->disasm = disasm;
};
void showMenu(int itemIndex, const POINT &pt);
protected:
virtual bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT& returnValue);
@ -64,15 +56,7 @@ private:
class CtrlStackTraceView: public GenericListControl
{
public:
CtrlStackTraceView(HWND hwnd);
void setCpu(DebugInterface* cpu)
{
this->cpu = cpu;
};
void setDisasm(CtrlDisAsmView* disasm)
{
this->disasm = disasm;
};
CtrlStackTraceView(HWND hwnd, DebugInterface* cpu, CtrlDisAsmView* disasm);
void loadStackTrace();
protected:
virtual bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT& returnValue);

View File

@ -4,6 +4,8 @@
#include <windowsx.h>
#include <commctrl.h>
const DWORD tabControlStyleMask = ~(WS_POPUP | WS_TILEDWINDOW);
TabControl::TabControl(HWND handle): hwnd(handle)
{
SetWindowLongPtr(hwnd,GWLP_USERDATA,(LONG_PTR)this);
@ -13,7 +15,7 @@ TabControl::TabControl(HWND handle): hwnd(handle)
HWND TabControl::AddTabWindow(wchar_t* className, wchar_t* title, DWORD style)
{
style |= WS_CHILD;
style = (style |WS_CHILD) & tabControlStyleMask;
TCITEM tcItem;
ZeroMemory (&tcItem,sizeof (tcItem));
@ -43,7 +45,11 @@ HWND TabControl::AddTabWindow(wchar_t* className, wchar_t* title, DWORD style)
void TabControl::AddTabDialog(Dialog* dialog, wchar_t* title)
{
HWND handle = dialog->GetDlgHandle();
AddTab(handle,title);
}
void TabControl::AddTab(HWND handle, wchar_t* title)
{
TCITEM tcItem;
ZeroMemory (&tcItem,sizeof (tcItem));
tcItem.mask = TCIF_TEXT;
@ -61,7 +67,7 @@ void TabControl::AddTabDialog(Dialog* dialog, wchar_t* title)
TabCtrl_AdjustRect(hwnd, FALSE, &tabRect);
SetParent(handle,GetParent(hwnd));
DWORD style = (GetWindowLong(handle,GWL_STYLE) | WS_CHILD) & ~(WS_POPUP | WS_TILEDWINDOW);
DWORD style = (GetWindowLong(handle,GWL_STYLE) | WS_CHILD) & tabControlStyleMask;
SetWindowLong(handle, GWL_STYLE, style);
MoveWindow(handle,tabRect.left,tabRect.top,tabRect.right-tabRect.left,tabRect.bottom-tabRect.top,TRUE);
tabs.push_back(handle);
@ -94,19 +100,36 @@ void TabControl::ShowTab(HWND pageHandle)
}
}
int TabControl::CurrentTabIndex()
{
return TabCtrl_GetCurSel(hwnd);
}
void TabControl::NextTab(bool cycle)
{
int index = TabCtrl_GetCurSel(hwnd);
if (index == tabs.size()-1 && cycle)
index = 0;
int index = CurrentTabIndex()+1;
if (index == tabs.size())
{
if (cycle == false)
index--;
else
index = 0;
}
ShowTab(index);
}
void TabControl::PreviousTab(bool cycle)
{
int index = TabCtrl_GetCurSel(hwnd);
if (index == 0 && cycle)
index = (int) tabs.size()-1;
int index = CurrentTabIndex()-1;
if (index < 0)
{
if (cycle == false)
index = 0;
else
index = (int) tabs.size()-1;
}
ShowTab(index);
}

View File

@ -11,13 +11,17 @@ public:
void HandleNotify(LPARAM lParam);
HWND AddTabWindow(wchar_t* className, wchar_t* title, DWORD style = 0);
void AddTabDialog(Dialog* dialog, wchar_t* title);
void AddTab(HWND hwnd, wchar_t* title);
void ShowTab(int index, bool setControlIndex = true);
void ShowTab(HWND pageHandle);
void NextTab(bool cycle);
void PreviousTab(bool cycle);
int CurrentTabIndex();
HWND CurrentTabHandle() { return tabs[CurrentTabIndex()]; };
private:
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void OnResize();
HWND hwnd;
WNDPROC oldProc;
std::vector<HWND> tabs;

View File

@ -103,6 +103,7 @@ BEGIN
VK_F10, ID_DEBUG_STEPOVER, VIRTKEY, NOINVERT
VK_F11, ID_DEBUG_STEPINTO, VIRTKEY, NOINVERT
VK_F11, ID_DEBUG_STEPOUT, VIRTKEY, SHIFT, NOINVERT
"X", ID_DEBUG_HIDEBOTTOMTABS, VIRTKEY, CONTROL, NOINVERT
END
@ -157,10 +158,11 @@ BEGIN
CONTROL "",IDC_LEFTTABS,"SysTabControl32",TCS_BUTTONS,1,63,78,15
LISTBOX IDC_FUNCTIONLIST,1,83,103,255,LBS_SORT | LBS_NOINTEGRALHEIGHT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "VFPU",IDC_SHOWVFPU,83,63,24,12
CONTROL "",IDC_BREAKPOINTLIST,"SysListView32",LVS_ALIGNLEFT | LVS_SHOWSELALWAYS | LVS_REPORT | WS_BORDER,1,338,513,93
CONTROL "Custom2",IDC_DEBUGMEMVIEW,"CtrlMemView",WS_BORDER,1,338,513,93
CONTROL "",IDC_BREAKPOINTLIST,"SysListView32",LVS_ALIGNLEFT | LVS_SHOWSELALWAYS | LVS_REPORT,1,338,513,93
CONTROL "Custom2",IDC_DEBUGMEMVIEW,"CtrlMemView",0,1,338,513,93
CONTROL "",IDC_THREADLIST,"SysListView32",LVS_ALIGNLEFT | LVS_SHOWSELALWAYS | LVS_REPORT | WS_BORDER,1,338,513,93
CONTROL "",IDC_STACKFRAMES,"SysListView32",LVS_ALIGNLEFT | LVS_SHOWSELALWAYS | LVS_REPORT | WS_BORDER,1,338,513,93
CONTROL "",IDC_STACKFRAMES,"SysListView32",LVS_ALIGNLEFT | LVS_SHOWSELALWAYS | LVS_REPORT | WS_BORDER,1,338,513,93
CONTROL "",IDC_DEBUG_BOTTOMTABS,"SysTabControl32",TCS_TABS | TCS_FOCUSNEVER,1,338,513,93
END
IDD_GEDEBUGGER DIALOGEX 0, 0, 500, 400

View File

@ -270,6 +270,8 @@
#define IDC_GEDBG_LISTS_STACK 40124
#define IDC_GEDBG_LISTS_SELECTEDLIST 40125
#define ID_OPTIONS_FXAA 40126
#define IDC_DEBUG_BOTTOMTABS 40127
#define ID_DEBUG_HIDEBOTTOMTABS 40128
// Dummy option to let the buffered rendering hotkey cycle through all the options.
#define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500
@ -282,7 +284,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 252
#define _APS_NEXT_COMMAND_VALUE 40126
#define _APS_NEXT_COMMAND_VALUE 40129
#define _APS_NEXT_CONTROL_VALUE 1181
#define _APS_NEXT_SYMED_VALUE 101
#endif