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
// http://code.google.com/p/dolphin-emu/
////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
#include <algorithm> // min
#include <string> // System: To be able to add strings with "+"
#include <stdio.h>
#include <math.h>
#ifdef _WIN32
#include <windows.h>
#else
@ -26,12 +31,16 @@
#include "Common.h"
#include "LogManager.h" // Common
////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////
// Main
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
ConsoleListener::ConsoleListener()
{
#ifdef _WIN32
m_hStdOut = NULL;
hConsole = NULL;
#endif
}
@ -43,26 +52,28 @@ ConsoleListener::~ConsoleListener()
// 100, 100, "Dolphin Log Console"
// Open console window - width and height is the size of console window
// 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
// Open the console window and create the window handle for GetStdHandle()
AllocConsole();
// Save the window handle that AllocConsole() created
m_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
// Set the console window title
SetConsoleTitle(title);
SetConsoleTitle(Title);
// Set the total letter space
COORD co = {width, 3000}; // Big scrollback.
SetConsoleScreenBufferSize(m_hStdOut, co);
// Set the total letter space to MAX_BYTES
int LWidth = Width / 8;
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
because it can be changed with MoveWindow() later */
SMALL_RECT coo = {0,0, (width - 1), 50}; // Top, left, right, bottom
SetConsoleWindowInfo(m_hStdOut, TRUE, &coo);
SMALL_RECT coo = {0,0, (LWidth - 1), 50}; // Top, left, right, bottom
SetConsoleWindowInfo(hConsole, TRUE, &coo);
#endif
}
@ -70,10 +81,10 @@ void ConsoleListener::Open(int width, int height, const char *title)
void ConsoleListener::Close()
{
#ifdef _WIN32
if (m_hStdOut == NULL)
if (hConsole == NULL)
return;
FreeConsole();
m_hStdOut = NULL;
hConsole = NULL;
#else
fflush(NULL);
#endif
@ -82,53 +93,130 @@ void ConsoleListener::Close()
bool ConsoleListener::IsOpen()
{
#ifdef _WIN32
return (m_hStdOut != NULL);
return (hConsole != NULL);
#else
return true;
#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)
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
color = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
Color = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
break;
case ERROR_LEVEL: // light red
color = FOREGROUND_RED | FOREGROUND_INTENSITY;
Color = FOREGROUND_RED | FOREGROUND_INTENSITY;
break;
case WARNING_LEVEL: // light yellow
color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
break;
case INFO_LEVEL: // cyan
color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
Color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
break;
case DEBUG_LEVEL: // gray
color = FOREGROUND_INTENSITY;
Color = FOREGROUND_INTENSITY;
break;
default: // off-white
color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
Color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
break;
}
if (strlen(text) > 10) {
// first 10 chars white
SetConsoleTextAttribute(m_hStdOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
WriteConsole(m_hStdOut, text, 10, &cCharsWritten, NULL);
text += 10;
if (Level != CUSTOM_LEVEL && strlen(Text) > 10)
{
// First 10 chars white
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
WriteConsole(hConsole, Text, 10, &cCharsWritten, NULL);
Text += 10;
}
SetConsoleTextAttribute(m_hStdOut, color);
WriteConsole(m_hStdOut, text, (DWORD)strlen(text), &cCharsWritten, NULL);
SetConsoleTextAttribute(hConsole, Color);
WriteConsole(hConsole, Text, (DWORD)strlen(Text), &cCharsWritten, NULL);
#else
fprintf(stderr, "%s", text);
#endif
@ -146,12 +234,14 @@ void ConsoleListener::ClearScreen()
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsole, &csbi);
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize,
coordScreen, &cCharsWritten);
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
// Write space to the entire console
FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten);
GetConsoleScreenBufferInfo(hConsole, &csbi);
FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize,
coordScreen, &cCharsWritten);
FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
// Reset cursor
SetConsoleCursorPosition(hConsole, coordScreen);
#endif
}
////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

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

View File

@ -77,15 +77,19 @@ public:
const char * Name = "Console");
void Close();
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();
const char *getName() const { return "console"; }
const char *getName() const { return "Console"; }
private:
#ifdef _WIN32
HWND GetHwnd(void);
HANDLE m_hStdOut;
HANDLE hConsole;
static const int MAX_BYTES = 1024 * 30;
#endif
};

View File

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

View File

@ -525,6 +525,10 @@ CFrame::CFrame(bool showLogWindow,
wxKeyEventHandler(CFrame::OnKeyUp),
(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
wxTheApp->Connect(wxID_ANY, wxEVT_LEFT_DOWN,
wxMouseEventHandler(CFrame::OnDoubleClick),

View File

@ -123,6 +123,7 @@ class CFrame : public wxFrame
void SetPaneSize(wxArrayInt,wxArrayInt);
void ToggleNotebookStyle(long);
void Save();
void ResizeConsole();
private:
@ -224,6 +225,7 @@ class CFrame : public wxFrame
void OnToggleDualCore(wxCommandEvent& event);
void OnToggleSkipIdle(wxCommandEvent& event);
void OnToggleThrottle(wxCommandEvent& event);
void OnManagerResize(wxAuiManagerEvent& event);
void OnResize(wxSizeEvent& event);
void OnToggleToolbar(wxCommandEvent& event);
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
void CFrame::OnNetPlay(wxCommandEvent& WXUNUSED (event))
@ -1161,13 +1180,17 @@ void CFrame::ToggleConsole(bool Show, int i)
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// GUI
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void CFrame::OnManagerResize(wxAuiManagerEvent& event)
{
event.Skip();
ResizeConsole();
}
void CFrame::OnResize(wxSizeEvent& event)
{
event.Skip();
// fit frame content, not needed right now
//FitInside();
DoMoveIcons(); // In FrameWiimote.cpp
event.Skip();
}
// Update the enabled/disabled status