GUI: Resize console and its buffer

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4090 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson 2009-08-29 06:08:14 +00:00
parent 90d979554c
commit 508051ec8d
7 changed files with 176 additions and 56 deletions

View File

@ -15,9 +15,14 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
#include <algorithm> // min #include <algorithm> // min
#include <string> // System: To be able to add strings with "+" #include <string> // System: To be able to add strings with "+"
#include <stdio.h> #include <stdio.h>
#include <math.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#else #else
@ -26,12 +31,16 @@
#include "Common.h" #include "Common.h"
#include "LogManager.h" // Common #include "LogManager.h" // Common
////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////
// Main
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
ConsoleListener::ConsoleListener() ConsoleListener::ConsoleListener()
{ {
#ifdef _WIN32 #ifdef _WIN32
m_hStdOut = NULL; hConsole = NULL;
#endif #endif
} }
@ -43,26 +52,28 @@ ConsoleListener::~ConsoleListener()
// 100, 100, "Dolphin Log Console" // 100, 100, "Dolphin Log Console"
// Open console window - width and height is the size of console window // Open console window - width and height is the size of console window
// Name is the window title // Name is the window title
void ConsoleListener::Open(int width, int height, const char *title) void ConsoleListener::Open(int Width, int Height, const char *Title)
{ {
#ifdef _WIN32 #ifdef _WIN32
// Open the console window and create the window handle for GetStdHandle() // Open the console window and create the window handle for GetStdHandle()
AllocConsole(); AllocConsole();
// Save the window handle that AllocConsole() created // Save the window handle that AllocConsole() created
m_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
// Set the console window title // Set the console window title
SetConsoleTitle(title); SetConsoleTitle(Title);
// Set the total letter space // Set the total letter space to MAX_BYTES
COORD co = {width, 3000}; // Big scrollback. int LWidth = Width / 8;
SetConsoleScreenBufferSize(m_hStdOut, co); int LBufHeight = floor((float)(MAX_BYTES / (LWidth + 1)));
COORD co = {LWidth, LBufHeight};
SetConsoleScreenBufferSize(hConsole, co);
/* Set the window size in number of letters. The height is hard coded here /* Set the window size in number of letters. The height is hard coded here
because it can be changed with MoveWindow() later */ because it can be changed with MoveWindow() later */
SMALL_RECT coo = {0,0, (width - 1), 50}; // Top, left, right, bottom SMALL_RECT coo = {0,0, (LWidth - 1), 50}; // Top, left, right, bottom
SetConsoleWindowInfo(m_hStdOut, TRUE, &coo); SetConsoleWindowInfo(hConsole, TRUE, &coo);
#endif #endif
} }
@ -70,10 +81,10 @@ void ConsoleListener::Open(int width, int height, const char *title)
void ConsoleListener::Close() void ConsoleListener::Close()
{ {
#ifdef _WIN32 #ifdef _WIN32
if (m_hStdOut == NULL) if (hConsole == NULL)
return; return;
FreeConsole(); FreeConsole();
m_hStdOut = NULL; hConsole = NULL;
#else #else
fflush(NULL); fflush(NULL);
#endif #endif
@ -82,53 +93,130 @@ void ConsoleListener::Close()
bool ConsoleListener::IsOpen() bool ConsoleListener::IsOpen()
{ {
#ifdef _WIN32 #ifdef _WIN32
return (m_hStdOut != NULL); return (hConsole != NULL);
#else #else
return true; return true;
#endif #endif
} }
////////////////////////////////////////////////////////////////////////////////////////////////////////
// Logs the message to screen
void ConsoleListener::Log(LogTypes::LOG_LEVELS level, const char *text) ////////////////////////////////////////////////////////////////////////////////////////////////////////
// Size
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void ConsoleListener::LetterSpace(int Width, int Height)
{
#ifdef _WIN32
// Get console info
CONSOLE_SCREEN_BUFFER_INFO ConInfo;
GetConsoleScreenBufferInfo(hConsole, &ConInfo);
// Change the screen buffer window size
SMALL_RECT coo = {0,0, Width, Height}; // top, left, right, bottom
bool SW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
// Change screen buffer to the screen buffer window size
COORD Co = {Width + 1, Height + 1};
bool SB = SetConsoleScreenBufferSize(hConsole, Co);
// Resize the window too
MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(Height*12 + 50), true);
// Logging
//printf("LetterSpace(): L:%i T:%i Iconic:%i\n", ConsoleLeft, ConsoleTop, ConsoleIconic);
#endif
}
void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool Resize)
{
#ifdef _WIN32
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
// Get console info
CONSOLE_SCREEN_BUFFER_INFO ConInfo;
GetConsoleScreenBufferInfo(hConsole, &ConInfo);
// Letter space
int LWidth = floor((float)(Width / 8));
int LHeight = floor((float)(Height / 12));
int LBufHeight = floor((float)(MAX_BYTES / (LWidth + 1)));
// Read the current text
char Str[MAX_BYTES];
DWORD dwConSize = ConInfo.dwSize.X * ConInfo.dwSize.Y;
DWORD cCharsRead = 0;
COORD coordScreen = { 0, 0 };
ReadConsoleOutputCharacter(hConsole, Str, dwConSize, coordScreen, &cCharsRead);
// Change the screen buffer window size
SMALL_RECT coo = {0,0, LWidth, LHeight}; // top, left, right, bottom
bool bW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
// Change screen buffer to the screen buffer window size
COORD Co = {LWidth + 1, LBufHeight};
bool bB = SetConsoleScreenBufferSize(hConsole, Co);
// Redraw the text
DWORD cCharsWritten = 0;
WriteConsoleOutputCharacter(hConsole, Str, cCharsRead, coordScreen, &cCharsWritten);
// Resize the window too
if (Resize) MoveWindow(GetConsoleWindow(), Left,Top, (Width + 50),(Height + 50), true);
// Logging
//Log(LogTypes::LNOTICE, StringFromFormat("\n\n\n\nMaxBytes: %i, WxH:%ix%i, Consize: %i, Read: %i, Written: %i\n\n", MAX_BYTES, LWidth, LHeight, dwConSize, cCharsRead, cCharsWritten).c_str());
#endif
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////
// Write
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text, ...)
void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text)
{ {
#if defined(_WIN32) #if defined(_WIN32)
DWORD cCharsWritten; // We will get a value back here /*
WORD color; const int MAX_BYTES = 1024*10;
char Str[MAX_BYTES];
va_list ArgPtr;
int Cnt;
va_start(ArgPtr, Text);
Cnt = vsnprintf(Str, MAX_BYTES, Text, ArgPtr);
va_end(ArgPtr);
*/
DWORD cCharsWritten;
WORD Color;
switch (level) switch (Level)
{ {
case NOTICE_LEVEL: // light green case NOTICE_LEVEL: // light green
color = FOREGROUND_GREEN | FOREGROUND_INTENSITY; Color = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
break; break;
case ERROR_LEVEL: // light red case ERROR_LEVEL: // light red
color = FOREGROUND_RED | FOREGROUND_INTENSITY; Color = FOREGROUND_RED | FOREGROUND_INTENSITY;
break; break;
case WARNING_LEVEL: // light yellow case WARNING_LEVEL: // light yellow
color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
break; break;
case INFO_LEVEL: // cyan case INFO_LEVEL: // cyan
color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; Color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
break; break;
case DEBUG_LEVEL: // gray case DEBUG_LEVEL: // gray
color = FOREGROUND_INTENSITY; Color = FOREGROUND_INTENSITY;
break; break;
default: // off-white default: // off-white
color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
break; break;
} }
if (strlen(text) > 10) { if (Level != CUSTOM_LEVEL && strlen(Text) > 10)
// first 10 chars white {
SetConsoleTextAttribute(m_hStdOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); // First 10 chars white
WriteConsole(m_hStdOut, text, 10, &cCharsWritten, NULL); SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
text += 10; WriteConsole(hConsole, Text, 10, &cCharsWritten, NULL);
Text += 10;
} }
SetConsoleTextAttribute(m_hStdOut, color); SetConsoleTextAttribute(hConsole, Color);
WriteConsole(m_hStdOut, text, (DWORD)strlen(text), &cCharsWritten, NULL); WriteConsole(hConsole, Text, (DWORD)strlen(Text), &cCharsWritten, NULL);
#else #else
fprintf(stderr, "%s", text); fprintf(stderr, "%s", text);
#endif #endif
@ -147,11 +235,13 @@ void ConsoleListener::ClearScreen()
GetConsoleScreenBufferInfo(hConsole, &csbi); GetConsoleScreenBufferInfo(hConsole, &csbi);
dwConSize = csbi.dwSize.X * csbi.dwSize.Y; dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, // Write space to the entire console
coordScreen, &cCharsWritten); FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten);
GetConsoleScreenBufferInfo(hConsole, &csbi); GetConsoleScreenBufferInfo(hConsole, &csbi);
FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
coordScreen, &cCharsWritten); // Reset cursor
SetConsoleCursorPosition(hConsole, coordScreen); SetConsoleCursorPosition(hConsole, coordScreen);
#endif #endif
} }
////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -23,6 +23,7 @@
#define WARNING_LEVEL 3 // Something is suspicious. #define WARNING_LEVEL 3 // Something is suspicious.
#define INFO_LEVEL 4 // General information. #define INFO_LEVEL 4 // General information.
#define DEBUG_LEVEL 5 // Detailed debugging - might make things slow. #define DEBUG_LEVEL 5 // Detailed debugging - might make things slow.
#define CUSTOM_LEVEL 6 // Custom log
namespace LogTypes namespace LogTypes
{ {

View File

@ -77,15 +77,19 @@ public:
const char * Name = "Console"); const char * Name = "Console");
void Close(); void Close();
bool IsOpen(); bool IsOpen();
void Log(LogTypes::LOG_LEVELS, const char *text); void LetterSpace(int Width, int Height);
void PixelSpace(int Left, int Top, int Width, int Height, bool);
void Log(LogTypes::LOG_LEVELS, const char *Text);
//void Log(LogTypes::LOG_LEVELS, const char *Text, ...);
void ClearScreen(); void ClearScreen();
const char *getName() const { return "console"; } const char *getName() const { return "Console"; }
private: private:
#ifdef _WIN32 #ifdef _WIN32
HWND GetHwnd(void); HWND GetHwnd(void);
HANDLE m_hStdOut; HANDLE hConsole;
static const int MAX_BYTES = 1024 * 30;
#endif #endif
}; };

View File

@ -333,16 +333,12 @@ int CCodeWindow::Limit(int i, int Low, int High)
} }
void CCodeWindow::OpenPages() void CCodeWindow::OpenPages()
{ {
ConsoleListener* Console = LogManager::GetInstance()->getConsoleListener(); if (bRegisterWindow) Parent->DoToggleWindow(IDM_REGISTERWINDOW, true);
Console->Log(LogTypes::LNOTICE, StringFromFormat( if (bBreakpointWindow) Parent->DoToggleWindow(IDM_BREAKPOINTWINDOW, true);
"OpenPages:%i %i\n", iRegisterWindow, iBreakpointWindow).c_str()); if (bMemoryWindow) Parent->DoToggleWindow(IDM_MEMORYWINDOW, true);
if (bJitWindow) Parent->DoToggleWindow(IDM_JITWINDOW, true);
if (bRegisterWindow) Parent->DoToggleWindow(IDM_REGISTERWINDOW, bRegisterWindow); if (bSoundWindow) Parent->DoToggleWindow(IDM_SOUNDWINDOW, true);
if (bBreakpointWindow) Parent->DoToggleWindow(IDM_BREAKPOINTWINDOW, bBreakpointWindow); if (bVideoWindow) Parent->DoToggleWindow(IDM_VIDEOWINDOW, true);
if (bMemoryWindow) Parent->DoToggleWindow(IDM_MEMORYWINDOW, bMemoryWindow);
if (bJitWindow) Parent->DoToggleWindow(IDM_JITWINDOW, bJitWindow);
if (bSoundWindow) Parent->DoToggleWindow(IDM_SOUNDWINDOW, bSoundWindow);
if (bVideoWindow) Parent->DoToggleWindow(IDM_VIDEOWINDOW, bVideoWindow);
} }
void CCodeWindow::OnToggleWindow(wxCommandEvent& event) void CCodeWindow::OnToggleWindow(wxCommandEvent& event)
{ {

View File

@ -525,6 +525,10 @@ CFrame::CFrame(bool showLogWindow,
wxKeyEventHandler(CFrame::OnKeyUp), wxKeyEventHandler(CFrame::OnKeyUp),
(wxObject*)0, this); (wxObject*)0, this);
m_Mgr->Connect(wxID_ANY, wxEVT_AUI_RENDER, // Resize
wxAuiManagerEventHandler(CFrame::OnManagerResize),
(wxObject*)0, this);
#ifdef _WIN32 // The functions are only tested in Windows so far #ifdef _WIN32 // The functions are only tested in Windows so far
wxTheApp->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxTheApp->Connect(wxID_ANY, wxEVT_LEFT_DOWN,
wxMouseEventHandler(CFrame::OnDoubleClick), wxMouseEventHandler(CFrame::OnDoubleClick),

View File

@ -123,6 +123,7 @@ class CFrame : public wxFrame
void SetPaneSize(wxArrayInt,wxArrayInt); void SetPaneSize(wxArrayInt,wxArrayInt);
void ToggleNotebookStyle(long); void ToggleNotebookStyle(long);
void Save(); void Save();
void ResizeConsole();
private: private:
@ -224,6 +225,7 @@ class CFrame : public wxFrame
void OnToggleDualCore(wxCommandEvent& event); void OnToggleDualCore(wxCommandEvent& event);
void OnToggleSkipIdle(wxCommandEvent& event); void OnToggleSkipIdle(wxCommandEvent& event);
void OnToggleThrottle(wxCommandEvent& event); void OnToggleThrottle(wxCommandEvent& event);
void OnManagerResize(wxAuiManagerEvent& event);
void OnResize(wxSizeEvent& event); void OnResize(wxSizeEvent& event);
void OnToggleToolbar(wxCommandEvent& event); void OnToggleToolbar(wxCommandEvent& event);
void DoToggleToolbar(bool); void DoToggleToolbar(bool);

View File

@ -746,11 +746,30 @@ void CFrame::ToggleNotebookStyle(long Style)
} }
} }
} }
void CFrame::ResizeConsole()
{
for (int i = 0; i < m_NB.size(); i++)
{
if (!m_NB[i]) continue;
for(u32 j = 0; j <= m_NB[i]->GetPageCount(); j++)
{
if (m_NB[i]->GetPageText(j).IsSameAs(wxT("Console")))
{
// Get the client size
int X = m_NB[i]->GetClientSize().GetX() - 35;
int Y = m_NB[i]->GetClientSize().GetY() - 70;
// Resize buffer
ConsoleListener* Console = LogManager::GetInstance()->getConsoleListener();
Console->PixelSpace(0,0, X,Y, false);
}
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////
// Miscellaneous menu // Miscellaneous menus
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// NetPlay stuff // NetPlay stuff
void CFrame::OnNetPlay(wxCommandEvent& WXUNUSED (event)) void CFrame::OnNetPlay(wxCommandEvent& WXUNUSED (event))
@ -1161,13 +1180,17 @@ void CFrame::ToggleConsole(bool Show, int i)
///////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////
// GUI // GUI
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void CFrame::OnManagerResize(wxAuiManagerEvent& event)
{
event.Skip();
ResizeConsole();
}
void CFrame::OnResize(wxSizeEvent& event) void CFrame::OnResize(wxSizeEvent& event)
{ {
event.Skip();
// fit frame content, not needed right now // fit frame content, not needed right now
//FitInside(); //FitInside();
DoMoveIcons(); // In FrameWiimote.cpp DoMoveIcons(); // In FrameWiimote.cpp
event.Skip();
} }
// Update the enabled/disabled status // Update the enabled/disabled status