- add first custom dialog box to the wxWindows interface in
gui/wxdialog.h and gui/wxdialog.cc. The first dialog box is called LogMsgAskDialog. It displays panic messages and asks if you want to continue, quit, etc.
This commit is contained in:
parent
67f9213460
commit
7fc65e2e25
@ -53,7 +53,7 @@ GUI_OBJS_NOGUI = nogui.o
|
||||
GUI_OBJS_TERM = term.o
|
||||
GUI_OBJS_RFB = rfb.o
|
||||
GUI_OBJS_AMIGAOS = amigaos.o
|
||||
GUI_OBJS_WX = wx.o wxmain.o
|
||||
GUI_OBJS_WX = wx.o wxmain.o wxdialog.o
|
||||
GUI_OBJS = keymap.o gui.o siminterface.o @GUI_OBJS@
|
||||
|
||||
|
||||
|
249
bochs/gui/wxdialog.cc
Normal file
249
bochs/gui/wxdialog.cc
Normal file
@ -0,0 +1,249 @@
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// $Id: wxdialog.cc,v 1.1 2002-08-28 03:20:23 bdenney Exp $
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// misc/wxdialog.cc
|
||||
// This is a testbed for wxWindows dialog box experiments.
|
||||
//
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
#include "wx/html/htmlwin.h"
|
||||
|
||||
#include "config.h" // definitions based on configure script
|
||||
#include "osdep.h" // workarounds for missing stuff
|
||||
#include "gui/siminterface.h" // interface to the simulator
|
||||
#include "bxversion.h" // get version string
|
||||
#include "wxmain.h" // wxwindows shared stuff
|
||||
#include "wxdialog.h" // custom dialog boxes
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// constants, prototypes
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum {
|
||||
ID_ShowDialog_1 = 1,
|
||||
ID_ShowDialog_2,
|
||||
ID_ShowDialog_3,
|
||||
ID_Quit,
|
||||
ID_Button1,
|
||||
ID_Button2,
|
||||
ID_Continue,
|
||||
ID_Die,
|
||||
ID_DumpCore,
|
||||
ID_Debugger,
|
||||
ID_Help,
|
||||
ID_MY_LAST_ID
|
||||
};
|
||||
|
||||
void ChangeStaticText (wxSizer *sizer, wxStaticText *win, wxString newtext);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// LogMsgAskDialog implementation
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// all events go to OnEvent method
|
||||
BEGIN_EVENT_TABLE(LogMsgAskDialog, wxDialog)
|
||||
EVT_BUTTON(ID_Continue, LogMsgAskDialog::OnEvent)
|
||||
EVT_BUTTON(ID_Die, LogMsgAskDialog::OnEvent)
|
||||
EVT_BUTTON(ID_DumpCore, LogMsgAskDialog::OnEvent)
|
||||
EVT_BUTTON(ID_Debugger, LogMsgAskDialog::OnEvent)
|
||||
EVT_BUTTON(ID_Help, LogMsgAskDialog::OnEvent)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
LogMsgAskDialog::LogMsgAskDialog(
|
||||
wxWindow* parent,
|
||||
wxWindowID id,
|
||||
const wxString& title)
|
||||
: wxDialog (parent, id, title, wxDefaultPosition, wxDefaultSize,
|
||||
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
{
|
||||
for (int i=0; i<N_BUTTONS; i++) enabled[i] = TRUE;
|
||||
vertSizer = new wxBoxSizer(wxVERTICAL);
|
||||
context = new wxStaticText (this, -1, "Context: ");
|
||||
wxFont font = context->GetFont ();
|
||||
font.SetWeight (wxBOLD);
|
||||
font.SetPointSize (2 + font.GetPointSize ());
|
||||
context->SetFont (font);
|
||||
message = new wxStaticText (this, -1, "Message: ");
|
||||
message->SetFont (font);
|
||||
dontAsk = new wxCheckBox (this, -1, LOG_MSG_DONT_ASK_STRING);
|
||||
btnSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
// fill vertical sizer
|
||||
vertSizer->Add (context, 0, wxGROW|wxALIGN_LEFT|wxLEFT|wxTOP, 30);
|
||||
vertSizer->Add (message, 0, wxGROW|wxALIGN_LEFT|wxLEFT, 30);
|
||||
vertSizer->Add (dontAsk, 0, wxALIGN_CENTER|wxTOP, 30);
|
||||
vertSizer->Add (btnSizer, 0, wxALIGN_CENTER|wxTOP, 30);
|
||||
// Some object creation and layout is postponed until Init()
|
||||
// so that caller has time to configure the dialog.
|
||||
}
|
||||
|
||||
void LogMsgAskDialog::SetContext (char *s) {
|
||||
wxString text;
|
||||
text.Printf ("Context: %s", s);
|
||||
ChangeStaticText (vertSizer, context, text);
|
||||
}
|
||||
|
||||
void LogMsgAskDialog::SetMessage (char *s) {
|
||||
wxString text;
|
||||
text.Printf ("Message: %s", s);
|
||||
ChangeStaticText (vertSizer, message, text);
|
||||
}
|
||||
|
||||
void LogMsgAskDialog::Init ()
|
||||
{
|
||||
static const int ids[N_BUTTONS] = LOG_MSG_ASK_IDS;
|
||||
static const char *names[N_BUTTONS] = LOG_MSG_ASK_NAMES;
|
||||
for (int i=0; i<N_BUTTONS; i++) {
|
||||
if (!enabled[i]) continue;
|
||||
wxButton *btn = new wxButton (this, ids[i], names[i]);
|
||||
btnSizer->Add (btn, 1, wxALL, 5);
|
||||
}
|
||||
wxSize ms = message->GetSize ();
|
||||
printf ("message size is %d,%d\n", ms.GetWidth(), ms.GetHeight ());
|
||||
SetAutoLayout(TRUE);
|
||||
SetSizer(vertSizer);
|
||||
vertSizer->Fit (this);
|
||||
wxSize size = vertSizer->GetMinSize ();
|
||||
printf ("minsize is %d,%d\n", size.GetWidth(), size.GetHeight ());
|
||||
int margin = 10;
|
||||
SetSizeHints (size.GetWidth () + margin, size.GetHeight () + margin);
|
||||
Center ();
|
||||
}
|
||||
|
||||
// Event handler for dialog buttons. Just translate the wx ids into
|
||||
// enum values and return them with EndModel() to make the dialog
|
||||
// go away.
|
||||
void LogMsgAskDialog::OnEvent(wxCommandEvent& event)
|
||||
{
|
||||
int id = event.GetId ();
|
||||
int ret = -1;
|
||||
switch (id) {
|
||||
case ID_Continue: ret = CONT; break;
|
||||
case ID_Die: ret = DIE; break;
|
||||
case ID_DumpCore: ret = DUMP; break;
|
||||
case ID_Debugger: ret = DEBUG; break;
|
||||
case ID_Help: showHelp (); return;
|
||||
default:
|
||||
return; // without EndModal
|
||||
}
|
||||
printf ("you pressed button id=%d, return value=%d\n", id, ret);
|
||||
EndModal (ret);
|
||||
}
|
||||
|
||||
void LogMsgAskDialog::showHelp ()
|
||||
{
|
||||
wxMessageBox("No help is available yet.", "No Help", wxOK | wxICON_ERROR );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// utility
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// Unfortunately this step is necessary if you change the text.
|
||||
// Otherwise the sizer that contains the text never realizes that
|
||||
// the size has changed, and the layout is never updated. The
|
||||
// SetItemMinSize trick was reported on comp.soft-sys.wxwindows by
|
||||
// Dirk Birnhardt.
|
||||
void ChangeStaticText (wxSizer *sizer, wxStaticText *win, wxString newtext)
|
||||
{
|
||||
win->SetLabel (newtext);
|
||||
wxSize sz = win->GetSize ();
|
||||
sizer->SetItemMinSize (win, sz.GetWidth (), sz.GetHeight ());
|
||||
}
|
||||
|
||||
#ifdef TEST_DIALOG
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// MyApp declaration
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
class MyApp: public wxApp
|
||||
{
|
||||
virtual bool OnInit();
|
||||
};
|
||||
IMPLEMENT_APP(MyApp)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// MyFrame declaration
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
class MyFrame: public wxFrame
|
||||
{
|
||||
public:
|
||||
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
|
||||
void OnMenuEvent(wxCommandEvent& event);
|
||||
private:
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||
EVT_MENU(ID_ShowDialog_1, MyFrame::OnMenuEvent)
|
||||
EVT_MENU(ID_ShowDialog_2, MyFrame::OnMenuEvent)
|
||||
EVT_MENU(ID_ShowDialog_3, MyFrame::OnMenuEvent)
|
||||
EVT_MENU(ID_Quit, MyFrame::OnMenuEvent)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// MyApp methods
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool MyApp::OnInit()
|
||||
{
|
||||
MyFrame *frame = new MyFrame( "Bochs x86 Emulator", wxPoint(50,50), wxSize(450,340), wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION );
|
||||
frame->Show( TRUE );
|
||||
SetTopWindow( frame );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// MyFrame methods
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, const long style)
|
||||
: wxFrame((wxFrame *)NULL, -1, title, pos, size, style)
|
||||
{
|
||||
wxMenu *menu1 = new wxMenu;
|
||||
menu1->Append( ID_ShowDialog_1, "Show Dialog &1" );
|
||||
menu1->Append( ID_ShowDialog_2, "Show Dialog &2" );
|
||||
menu1->Append( ID_ShowDialog_3, "Show Dialog &3" );
|
||||
menu1->Append( ID_Quit, "&Quit" );
|
||||
wxMenuBar *menuBar = new wxMenuBar;
|
||||
menuBar->Append( menu1, "&File" );
|
||||
SetMenuBar( menuBar );
|
||||
CreateStatusBar();
|
||||
SetStatusText("");
|
||||
}
|
||||
|
||||
void MyFrame::OnMenuEvent(wxCommandEvent& event)
|
||||
{
|
||||
int id = event.GetId ();
|
||||
switch (id) {
|
||||
case ID_ShowDialog_1:
|
||||
{
|
||||
printf ("show dialog 1\n");
|
||||
LogMsgAskDialog dlg(this, -1, "Panic");
|
||||
dlg.EnableButton (dlg.DEBUG, FALSE);
|
||||
dlg.SetContext ("Hard Drive");
|
||||
dlg.SetMessage ("could not open hard drive image file '30M.sample'");
|
||||
int n = dlg.ShowModal ();
|
||||
printf ("modal dialog returned %d\n", n);
|
||||
printf ("and the dontAsk button is %d\n", dlg.GetDontAsk ());
|
||||
}
|
||||
break;
|
||||
case ID_ShowDialog_2:
|
||||
printf ("show dialog 2\n");
|
||||
break;
|
||||
case ID_ShowDialog_3:
|
||||
printf ("show dialog 3\n");
|
||||
break;
|
||||
case ID_Quit:
|
||||
Close (TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
58
bochs/gui/wxdialog.h
Normal file
58
bochs/gui/wxdialog.h
Normal file
@ -0,0 +1,58 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// $Id: wxdialog.h,v 1.1 2002-08-28 03:20:23 bdenney Exp $
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// wxWindows dialogs for Bochs
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// LogMsgAskDialog is a modal dialog box that shows the user a
|
||||
// simulation error message and asks if they want to continue or
|
||||
// not. It looks something like this:
|
||||
// -------------------------------------------------------------
|
||||
// Context: Hard Drive
|
||||
// Message: could not open hard drive image file '30M.sample'
|
||||
//
|
||||
// [ ] Don't ask about future messages like this
|
||||
//
|
||||
// [Continue] [Die] [Dump Core] [Debugger] [Help]
|
||||
// -------------------------------------------------------------
|
||||
// To use this dialog:
|
||||
// After constructor, use SetContext, SetMessage, EnableButton to
|
||||
// determine what will be displayed. Then call n = ShowModal(). The return
|
||||
// value tells which button was pressed (button_t types). Call GetDontAsk()
|
||||
// to see if they checked "Don't ask about..." or not.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
class LogMsgAskDialog: public wxDialog
|
||||
{
|
||||
public:
|
||||
enum button_t {
|
||||
CONT=0, DIE, DUMP, DEBUG, HELP,
|
||||
N_BUTTONS /* number of entries in enum */
|
||||
};
|
||||
#define LOG_MSG_ASK_IDS \
|
||||
{ ID_Continue, ID_Die, ID_DumpCore, ID_Debugger, ID_Help }
|
||||
#define LOG_MSG_ASK_NAMES \
|
||||
{ "Continue", "Die", "Dump Core", "Debugger", "Help" }
|
||||
#define LOG_MSG_DONT_ASK_STRING \
|
||||
"Don't ask about future messages like this"
|
||||
private:
|
||||
wxStaticText *context, *message;
|
||||
wxCheckBox *dontAsk;
|
||||
bool enabled[N_BUTTONS];
|
||||
wxBoxSizer *btnSizer, *vertSizer;
|
||||
void Init (); // called automatically by ShowModal()
|
||||
void showHelp ();
|
||||
public:
|
||||
LogMsgAskDialog(wxWindow* parent,
|
||||
wxWindowID id,
|
||||
const wxString& title);
|
||||
void EnableButton (button_t btn, bool en) { enabled[(int)btn] = en; }
|
||||
void SetContext (char *s);
|
||||
void SetMessage (char *s);
|
||||
bool GetDontAsk () { return dontAsk->GetValue (); }
|
||||
void OnEvent (wxCommandEvent& event);
|
||||
int ShowModal() { Init(); return wxDialog::ShowModal(); }
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// $Id: wxmain.cc,v 1.9 2002-08-27 18:11:13 bdenney Exp $
|
||||
// $Id: wxmain.cc,v 1.10 2002-08-28 03:20:23 bdenney Exp $
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// wxmain.cc implements the wxWindows frame, toolbar, menus, and dialogs.
|
||||
@ -51,7 +51,8 @@
|
||||
#include "osdep.h" // workarounds for missing stuff
|
||||
#include "gui/siminterface.h" // interface to the simulator
|
||||
#include "bxversion.h" // get version string
|
||||
#include "wxmain.h" // interface to the gui
|
||||
#include "wxmain.h" // wxwindows shared stuff
|
||||
#include "wxdialog.h" // custom dialog boxes
|
||||
|
||||
// include XPM icons
|
||||
#include "bitmaps/cdromd.xpm"
|
||||
@ -531,10 +532,6 @@ MyFrame::HandleAskParam (BxEvent *event)
|
||||
void
|
||||
MyFrame::OnSim2CuiEvent (wxCommandEvent& event)
|
||||
{
|
||||
static wxString choices[] = { "Continue", "Continue and Disable", "Die" };
|
||||
int choice;
|
||||
wxString string;
|
||||
|
||||
wxLogDebug ("received a bochs event in the GUI thread");
|
||||
BxEvent *be = (BxEvent *) event.GetEventObject ();
|
||||
wxLogDebug ("event type = %d", (int) be->type);
|
||||
@ -548,31 +545,41 @@ MyFrame::OnSim2CuiEvent (wxCommandEvent& event)
|
||||
// sync must return something; just return a copy of the event.
|
||||
sim_thread->SendSyncResponse(be);
|
||||
wxLogDebug ("after SendSyncResponse");
|
||||
return;
|
||||
case BX_ASYNC_EVT_SHUTDOWN_GUI:
|
||||
wxLogDebug ("configuration interface is exiting");
|
||||
Close (TRUE);
|
||||
wxExit ();
|
||||
return;
|
||||
return;
|
||||
case BX_SYNC_EVT_LOG_ASK:
|
||||
case BX_ASYNC_EVT_LOG_MSG:
|
||||
{
|
||||
wxLogDebug ("log msg: level=%d, prefix='%s', msg='%s'",
|
||||
be->u.logmsg.level,
|
||||
be->u.logmsg.prefix,
|
||||
be->u.logmsg.msg);
|
||||
be->u.logmsg.level,
|
||||
be->u.logmsg.prefix,
|
||||
be->u.logmsg.msg);
|
||||
if (be->type == BX_ASYNC_EVT_LOG_MSG) {
|
||||
// don't ask for user response
|
||||
return;
|
||||
}
|
||||
string.Printf ("%s", be->u.logmsg.msg);
|
||||
choice = ::wxGetSingleChoiceIndex (
|
||||
string,
|
||||
wxString (SIM->get_log_level_name (be->u.logmsg.level)), 3, choices);
|
||||
if (choice<0) choice = 2; // treat cancel the same as "die"
|
||||
be->retcode = choice;
|
||||
wxLogDebug ("you chose %d", choice);
|
||||
wxString levelName (SIM->get_log_level_name (be->u.logmsg.level));
|
||||
LogMsgAskDialog dlg (this, -1, levelName); // panic, error, etc.
|
||||
#if !BX_DEBUGGER
|
||||
dlg.EnableButton (dlg.DEBUG, FALSE);
|
||||
#endif
|
||||
dlg.SetContext (be->u.logmsg.prefix);
|
||||
dlg.SetMessage (be->u.logmsg.msg);
|
||||
int n = dlg.ShowModal ();
|
||||
Boolean dontAsk = dlg.GetDontAsk ();
|
||||
// turn the return value into the constant that logfunctions::ask is
|
||||
// expecting. 0=continue, 1=continue but ignore future messages from this
|
||||
// device, 2=die, 3=dump core, 4=debugger. FIXME: yuck. replace hardcoded
|
||||
// constants in logfunctions::ask with enum or defined constant.
|
||||
if (n==0) {
|
||||
n = dontAsk? 1 : 0;
|
||||
} else {
|
||||
n=n+1;
|
||||
}
|
||||
be->retcode = n;
|
||||
wxLogDebug ("you chose %d", n);
|
||||
sim_thread->SendSyncResponse (be);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
wxLogDebug ("OnSim2CuiEvent: event type %d ignored", (int)be->type);
|
||||
// assume it's a synchronous event and send back a response, to avoid
|
||||
|
Loading…
x
Reference in New Issue
Block a user