/* * File: hello.cc * Purpose: Demo for wxWindows class library * * wxWindows 1.40 * Copyright (c) 1993 Artificial Intelligence Applications Institute, * The University of Edinburgh * * Author: Julian Smart * Date: 18-4-93 * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose is hereby granted without fee, provided * that the above copyright notice, author statement and this permission * notice appear in all copies of this software and related documentation. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH * THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include // Included only for using MS C/C++ precompiled headers #include "wx.h" #include "hello.h" // Declare two frames MyFrame *frame = NULL; wxFrame *subframe = NULL; wxMenuBar *menu_bar = NULL; MyTimer the_timer; Bool timer_on = FALSE; wxBitmap *test_bitmap = NULL; wxIcon *test_icon = NULL; // This statement initialises the whole application MyApp myApp; // For drawing lines in a canvas float xpos = -1; float ypos = -1; // Must initialise these in OnInit, not statically wxPen *red_pen; wxFont *small_font; float zoom_factor = 1.0; // The `main program' equivalent, creating the windows and returning the // main frame wxFrame *MyApp::OnInit(void) { // Create a red pen red_pen = new wxPen("RED", 3, wxSOLID); // Create a small font small_font = new wxFont(10, wxSWISS, wxNORMAL, wxNORMAL); // Create the main frame window frame = new MyFrame(NULL, "Hello wxWindows", 0, 0, 400, 550); // Give it a status line frame->CreateStatusLine(); // Give it an icon test_icon = new wxIcon("aiai_icn"); frame->SetIcon(test_icon); // Make a menubar wxMenu *file_menu = new wxMenu; file_menu->Append(HELLO_LOAD_FILE, "&Load file"); wxMenu *pullright_menu = new wxMenu; pullright_menu->Append(HELLO_TWIPS, "&Twips"); pullright_menu->Append(HELLO_LOMETRIC, "&10th mm"); pullright_menu->Append(HELLO_METRIC, "&Metric"); pullright_menu->Append(HELLO_NORMAL, "&Normal size"); pullright_menu->Append(HELLO_ZOOM, "&Zoom..."); file_menu->Append(HELLO_SCALE, "&Scale picture", pullright_menu); file_menu->AppendSeparator(); file_menu->Append(HELLO_PRINT, "&Print"); #ifdef wx_msw file_menu->Append(HELLO_PRINT_EPS, "Print to &EPS file"); file_menu->Append(HELLO_COPY_MF, "&Copy metafile to clipboard"); #endif file_menu->AppendSeparator(); file_menu->Append(HELLO_QUIT, "&Quit"); wxMenu *timer_menu = new wxMenu; timer_menu->Append(HELLO_TIMER_ON, "Timer &on"); timer_menu->Append(HELLO_TIMER_OFF, "Timer o&ff"); wxMenu *cursor_menu = new wxMenu; cursor_menu->Append(wxCURSOR_ARROW, "Arrow"); cursor_menu->Append(wxCURSOR_WAIT, "Wait"); cursor_menu->Append(wxCURSOR_IBEAM, "Ibeam"); cursor_menu->Append(wxCURSOR_CROSS, "Cross"); cursor_menu->Append(wxCURSOR_SIZENWSE, "Size NWSE"); cursor_menu->Append(wxCURSOR_SIZENESW, "Size NESW"); cursor_menu->Append(wxCURSOR_SIZEWE, "Size WE"); cursor_menu->Append(wxCURSOR_SIZENS, "Size NS"); cursor_menu->Append(wxCURSOR_PENCIL, "Pencil"); cursor_menu->Append(wxCURSOR_BULLSEYE, "Bullseye"); cursor_menu->Append(wxCURSOR_MAGNIFIER, "Magnifier"); cursor_menu->Append(wxCURSOR_HAND, "Hand"); cursor_menu->Append(wxCURSOR_NO_ENTRY, "No Entry"); cursor_menu->Append(wxCURSOR_CHAR, "Char"); cursor_menu->Append(wxCURSOR_LEFT_BUTTON, "Left Button"); cursor_menu->Append(wxCURSOR_RIGHT_BUTTON, "Right Button"); cursor_menu->Append(wxCURSOR_MIDDLE_BUTTON, "Middle Button"); cursor_menu->Append(wxCURSOR_QUESTION_ARROW, "Question arrow"); cursor_menu->Append(wxCURSOR_SIZING, "Sizing"); cursor_menu->Append(wxCURSOR_SPRAYCAN, "Spraycan"); cursor_menu->Append(wxCURSOR_WATCH, "Watch"); cursor_menu->Append(wxCURSOR_POINT_LEFT, "Point left"); cursor_menu->Append(wxCURSOR_POINT_RIGHT, "Point right"); cursor_menu->Append(wxCURSOR_PAINT_BRUSH, "Paint brush"); wxMenu *help_menu = new wxMenu; help_menu->Append(HELLO_ABOUT, "&About"); menu_bar = new wxMenuBar; menu_bar->Append(file_menu, "&File"); menu_bar->Append(timer_menu, "&Timer"); menu_bar->Append(cursor_menu, "&Cursor"); menu_bar->Append(help_menu, "&Help"); // Associate the menu bar with the frame frame->SetMenuBar(menu_bar); menu_bar->Enable(HELLO_TIMER_ON, TRUE); menu_bar->Enable(HELLO_TIMER_OFF, FALSE); // Make a panel frame->panel = new wxPanel(frame, 0, 0, 400, 250, wxBORDER); frame->panel->SetLabelPosition(wxVERTICAL); // Create some panel items (void)new wxButton(frame->panel, (wxFunction)&button_proc, "A button"); (void)new wxText(frame->panel, NULL, "A text item", "Initial value", -1, -1, 200); (void)new wxCheckBox(frame->panel, NULL, "A check box"); frame->panel->NewLine(); char *choice_strings[] = { "Julian", "Hattie", "Ken", "Dick" }; wxChoice *choice = new wxChoice(frame->panel, NULL, "A choice item", -1, -1, -1, -1, 4, choice_strings); choice->SetSelection(0); (void)new wxMessage(frame->panel, "Hello! A simple message"); wxListBox *list = new wxListBox(frame->panel, (wxFunction)&list_proc, "A list", wxSINGLE, -1, -1, 100, 100); list->Append("Apple"); list->Append("Pear"); list->Append("Orange"); list->Append("Banana"); list->Append("Fruit"); frame->panel->NewLine(); (void)new wxSlider(frame->panel, NULL, "A slider", 40, 22, 101, 150); (void)new wxMultiText(frame->panel, (wxFunction)NULL, "Multiline text", "Some text"); // Make a text window frame->text_window = new wxTextWindow(frame, 0, 250, 400, 250); // Make another frame, containing a canvas subframe = new wxFrame(NULL, "Canvas Frame", 300, 300, 400, 300); int width, height; subframe->GetClientSize(&width, &height); MyCanvas *canvas = new MyCanvas(subframe, 0, 0, width, height, wxRETAINED); wxCursor *cursor = new wxCursor(wxCURSOR_PENCIL); canvas->SetCursor(cursor); // Give it scrollbars: the virtual canvas is 20 * 50 = 1000 pixels in each direction canvas->SetScrollbars(20, 20, 50, 50, 4, 4); canvas->SetPen(red_pen); frame->canvas = canvas; frame->Show(TRUE); subframe->Show(TRUE); // Load a file into the text window frame->text_window->LoadFile("welcome.txt"); frame->SetStatusText("Hello, wxWindows"); // Return the main frame window return frame; } // Define my frame constructor MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h): wxFrame(frame, title, x, y, w, h) { panel = NULL; text_window = NULL; } // Intercept menu commands void MyFrame::OnMenuCommand(int id) { wxDC *dc = canvas->GetDC(); switch (id) { case HELLO_LOAD_FILE: { char *s = wxFileSelector("Load text file", NULL, NULL, NULL, "*.txt"); if (s) frame->text_window->LoadFile(s); break; } case HELLO_TWIPS: { dc->SetMapMode(MM_TWIPS); dc->Clear(); Draw(*dc); break; } case HELLO_METRIC: { dc->SetMapMode(MM_METRIC); dc->Clear(); Draw(*dc); break; } case HELLO_LOMETRIC: { dc->SetMapMode(MM_LOMETRIC); dc->Clear(); Draw(*dc); break; } case HELLO_NORMAL: { dc->SetUserScale(1.0, 1.0); dc->SetMapMode(MM_TEXT); dc->Clear(); Draw(*dc); break; } case HELLO_ZOOM: { char *zoom_factor_s = FloatToString(zoom_factor); zoom_factor_s = wxGetTextFromUser("Enter new zoom factor", "Input", zoom_factor_s); if (zoom_factor_s) { StringToFloat(zoom_factor_s, &zoom_factor); dc->SetUserScale(zoom_factor, zoom_factor); dc->Clear(); Draw(*dc); } break; } case HELLO_QUIT: { OnClose(); delete this; break; } case HELLO_PRINT: { wxDC dc(NULL, NULL, NULL); // Defaults to EPS under UNIX, // normal Windows printing under Win 3.1 if (dc.Ok()) { dc.StartDoc("Hello printout"); dc.StartPage(); Draw(dc); dc.EndPage(); dc.EndDoc(); } break; } #ifdef wx_msw case HELLO_PRINT_EPS: // To use the special wxWindows EPS driver // under Windows 3.1, specify "PostScript" { wxDC dc(NULL, "PostScript", NULL); if (dc.Ok()) { dc.StartDoc("Hello printout"); dc.StartPage(); Draw(dc, FALSE); dc.EndPage(); dc.EndDoc(); } break; } case HELLO_COPY_MF: { wxMetaFileDC dc; if (dc.Ok()) { Draw(dc, FALSE); wxMetaFile *mf = dc.Close(); if (mf) { Bool success = mf->SetClipboard(); delete mf; } } break; } #endif case HELLO_ABOUT: { (void)wxMessageBox("wxWindows GUI library demo Vsn 1.40\nAuthor: Julian Smart J.Smart@ed.ac.uk\nAIAI (c) 1993", "About wxHello"); break; } case HELLO_TIMER_ON: { the_timer.Start(5000); timer_on = TRUE; menu_bar->Enable(HELLO_TIMER_ON, FALSE); menu_bar->Enable(HELLO_TIMER_OFF, TRUE); break; } case HELLO_TIMER_OFF: { the_timer.Stop(); menu_bar->Enable(HELLO_TIMER_ON, TRUE); menu_bar->Enable(HELLO_TIMER_OFF, FALSE); break; } default: { wxCursor *cursor = new wxCursor(id); frame->canvas->SetCursor(cursor); break; } } } // Intercept menu item selection - only has an effect in Windows void MyFrame::OnMenuSelect(int id) { char *msg = NULL; switch (id) { case HELLO_LOAD_FILE: msg = "Load a text file"; break; case HELLO_SCALE: msg = "Scale picture"; break; case HELLO_TWIPS: msg = "Twips scale"; break; case HELLO_METRIC: msg = "Metric scale (mm)"; break; case HELLO_LOMETRIC: msg = "Metric scale (0.1 mm)"; break; case HELLO_NORMAL: msg = "Pixel scale"; break; case HELLO_ZOOM: msg = "Zoom by specified amount"; break; case HELLO_QUIT: msg = "Quit program"; break; case HELLO_PRINT: msg = "Print picture"; break; #ifdef wx_msw case HELLO_PRINT_EPS: msg = "Print to EPS file"; break; case HELLO_COPY_MF: msg = "Copy metafile to clipboard"; break; #endif case -1: msg = ""; break; } if (msg) frame->SetStatusText(msg); } // Size the subwindows when the frame is resized void MyFrame::OnSize(int w, int h) { if (panel && text_window) { int width, height; GetClientSize(&width, &height); panel->SetSize(0, 0, width, (int)(height/2)); text_window->SetSize(0, (int)(height/2), width, (int)(height/2)); } } void MyFrame::Draw(wxDC& dc, Bool draw_bitmaps) { dc.SetFont(small_font); dc.SetPen(wxGREEN_PEN); dc.DrawLine(0, 0, 200, 200); dc.DrawLine(200, 0, 0, 200); dc.SetBrush(wxCYAN_BRUSH); dc.SetPen(wxRED_PEN); dc.DrawRectangle(100, 100, 100, 50); dc.DrawRoundedRectangle(150, 150, 100, 50); dc.SetClippingRegion(150, 150, 100, 50); dc.DrawText("This text should be clipped within the rectangle", 150, 170); dc.DestroyClippingRegion(); dc.DrawEllipse(250, 250, 100, 50); dc.DrawSpline(50, 200, 50, 100, 200, 10); dc.DrawLine(50, 230, 200, 230); dc.DrawText("This is a test string", 50, 230); if (draw_bitmaps) { // The easy way to draw bitmaps, using icons dc.DrawIcon(test_icon, 250, 50); /* An alternative way to draw bitmaps. wxDC *temp_dc = dc.CreateCompatibleDC(); temp_dc->SelectObject(test_bitmap); dc.Blit(250, 50, BITMAP_WIDTH, BITMAP_HEIGHT, temp_dc, 0, 0); delete temp_dc; */ } } // Define a constructor for my canvas MyCanvas::MyCanvas(wxFrame *frame, int x, int y, int w, int h, int style): wxCanvas(frame, x, y, w, h, style) { } // Define the repainting behaviour void MyCanvas::OnPaint(void) { frame->Draw(*(GetDC())); } // This implements a tiny doodling program! Drag the mouse using // the left button. void MyCanvas::OnEvent(wxEvent& event) { SetPen(wxBLACK_PEN); float x, y; event.Position(&x, &y); if (xpos > -1 && ypos > -1 && event.Dragging()) { DrawLine(xpos, ypos, x, y); } xpos = x; ypos = y; } // Intercept character input void MyCanvas::OnChar(int ch) { char buf[2]; buf[0] = (char)ch; buf[1] = 0; frame->SetStatusText(buf); } // Define the behaviour for the frame closing // - must delete all frames except for the main one. Bool MyFrame::OnClose(void) { if (subframe) delete subframe; return TRUE; } // Gets some user input, and sets the status line void button_proc(wxButton& but, wxEvent& event) { int choice = wxMessageBox("Press OK to continue", "Try me", wxOK | wxCANCEL); if (choice == wxOK) { char *text = wxGetTextFromUser("Enter some text", "Text input", ""); if (text) { (void)wxMessageBox(text, "Result", wxOK); frame->SetStatusText(text); } } } // Put some text into the text window void list_proc(wxListBox& list, wxEvent& event) { *(frame->text_window) << event.string; } void GenericOk(wxButton& but, wxEvent& event) { wxDialogBox *dialog = (wxDialogBox *)but.GetParent(); dialog->Show(FALSE); } // Timer notify proc void MyTimer::Notify(void) { *(frame->text_window) << "Timer went!" << "\n"; }