⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccc_wxw.cpp

📁 BigC++的源码
💻 CPP
字号:
#include <wx/wx.h>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <csetjmp>
#include <cstdio>
#include <iostream>

#include "ccc_wxw.h"

/*-------------------------------------------------------------------------*/

const double DEFAULT_XMIN = -10;
const double DEFAULT_YMIN = 10;
const double DEFAULT_XMAX = 10;
const double DEFAULT_YMAX = -10;

const int ID_TEXT = 1000;

/*-------------------------------------------------------------------------*/

/**
   A window onto which the graphics output is painted.
*/
class GraphicCanvas : public wxWindow
{
public:
   /**
      Initializes the base class.
      @param parent the parent window
   */
   GraphicCanvas(wxWindow* parent);
   void OnPaint(wxPaintEvent& event);
   void OnSize(wxSizeEvent& event);
   void OnMouseEvent(wxMouseEvent& event);
   /**
      Clears the window.
   */
   void clear();
   /**
      Sets the coordinate system.
      @param x1 the minimum x-value
      @param y1 the minimum y-value
      @param x2 the maximum x-value
      @param y2 the maximum y-value
   */
   void coord(double xmin, double ymin, double xmax, double ymax);
   /**
      Adds a point to the set of shapes that need to be displayed.
      @param s the point to add
   */
   void add(Point s);
   /**
      Adds a circle to the set of shapes that need to be displayed.
      @param s the circle to add
   */
   void add(Circle s);
   /**
      Adds a line to the set of shapes that need to be displayed.
      @param s the line to add
   */
   void add(Line s);
   /**
      Adds a message to the set of shapes that need to be displayed.
      @param s the message to add
   */
   void add(Message s);
private:
   /**
      Scales an x-coordinate from user to display coordinates.
      @param x a coordinate position in user coordinates
      @return the scaled coordinate
   */
   int user_to_disp_x(double x) const;
   /**
      Scales a y-coordinate from user to display coordinates.
      @param y a coordinate position in user coordinates
      @return the scaled coordinate
   */
   int user_to_disp_y(double y) const;
   /**
      Scales an x-coordinate from display to user coordinates.
      @param x a coordinate position in display coordinates
      @return the scaled coordinate
   */
   double disp_to_user_x(int x) const;
   /**
      Scales an y-coordinate from display to user coordinates.
      @param y a coordinate position in display coordinates
      @return the scaled coordinate
   */
   double disp_to_user_y(int y) const;

   /**
      Draws a point
      @param dc the device context
      @param s the point to draw
   */
   void draw(wxDC& dc, Point s);
   /**
      Draws a circle
      @param dc the device context
      @param s the circle to draw
   */
   void draw(wxDC& dc, Circle s);
   /**
      Draws a line
      @param dc the device context
      @param s the line to draw
   */
   void draw(wxDC& dc, Line s);
   /**
      Draws a message
      @param dc the device context
      @param s the message to draw
   */
   void draw(wxDC& dc, Message s);

   double _user_xmin; // the user's window's logical window coords
   double _user_xmax;
   double _user_ymin;
   double _user_ymax;
   int _disp_xmax; // the physical window dimension (in pixels)
   int _disp_ymax;
   int _disp_xoff;
   int _disp_yoff;

   vector<Point> points;
   vector<Line> lines;
   vector<Circle> circles;
   vector<Message> messages;

   DECLARE_EVENT_TABLE()
};

/**
   A frame with a window that shows the graphical output.
*/
class GraphicFrame : public wxFrame
{
public:
   /**
      Constructs the window.
   */
   GraphicFrame(const wxString& appName);
   /**
      Runs the ccc_win_main function.
   */
   void run();
   void set_text_focus(bool b);
   void OnEnter(wxCommandEvent& event);

private:
   wxTextCtrl* text;
   GraphicCanvas* window;

   DECLARE_EVENT_TABLE()
};

/**
   An application that generates a simple painting.
*/
class GraphicApp : public wxApp
{
public:
   /**
      Constructs the frame.
   */
   GraphicApp();
   virtual bool OnInit();
private:
   GraphicFrame* frame;
};

DECLARE_APP(GraphicApp)

GraphicWindow cwin;

IMPLEMENT_APP(GraphicApp)

BEGIN_EVENT_TABLE(GraphicCanvas, wxWindow)
   EVT_PAINT(GraphicCanvas::OnPaint)
   EVT_SIZE(GraphicCanvas::OnSize)
   EVT_MOUSE_EVENTS(GraphicCanvas::OnMouseEvent)
END_EVENT_TABLE()

BEGIN_EVENT_TABLE(GraphicFrame, wxFrame)
   EVT_TEXT_ENTER(ID_TEXT, GraphicFrame::OnEnter)
END_EVENT_TABLE()

/*-------------------------------------------------------------------------*/

GraphicCanvas::GraphicCanvas(wxWindow* parent)
   : wxWindow(parent, -1)
{
   _user_xmin = DEFAULT_XMIN;
   _user_xmax = DEFAULT_XMAX;
   _user_ymin = DEFAULT_YMIN;
   _user_ymax = DEFAULT_YMAX;
}

void GraphicCanvas::clear()
{
   points.clear();
   lines.clear();
   circles.clear();
   messages.clear();
}

void GraphicCanvas::add(Point s)
{
   points.push_back(s);
}

void GraphicCanvas::add(Circle s)
{
   circles.push_back(s);
}

void GraphicCanvas::add(Line s)
{
   lines.push_back(s);
}

void GraphicCanvas::add(Message s)
{
   messages.push_back(s);
}

void GraphicCanvas::OnSize(wxSizeEvent& event)
{
   wxSize size = GetSize();
   int width = size.GetWidth();
   int height= size.GetHeight();
   int sz = width < height ? width : height;
   _disp_xmax = sz;
   _disp_ymax = sz;
   _disp_xoff = (width - sz) / 2;
   _disp_yoff = (height - sz) / 2;
}

void GraphicCanvas::OnPaint(wxPaintEvent& event)
{
   wxPaintDC dc(this);
   dc.SetBrush(*wxTRANSPARENT_BRUSH);

   for (int i = 0; i < points.size(); i++)
      draw(dc, points[i]);
   for (int i = 0; i < lines.size(); i++)
      draw(dc, lines[i]);
   for (int i = 0; i < circles.size(); i++)
      draw(dc, circles[i]);
   for (int i = 0; i < messages.size(); i++)
      draw(dc, messages[i]);
}

void GraphicCanvas::OnMouseEvent(wxMouseEvent& event)
{
   if (event.ButtonDown())
      cwin.mouse_input(Point(disp_to_user_x(event.GetX()), 
         disp_to_user_y(event.GetY())));
}

int GraphicCanvas::user_to_disp_x(double x) const
{  
   return (int) (_disp_xoff + (x - _user_xmin) * _disp_xmax / (_user_xmax - _user_xmin));
}

int GraphicCanvas::user_to_disp_y(double y) const
{  
   return (int) (_disp_yoff + (y - _user_ymin) * _disp_ymax / (_user_ymax - _user_ymin));
}

double GraphicCanvas::disp_to_user_x(int x) const
{  
   return (double)(x - _disp_xoff) * (_user_xmax - _user_xmin) / _disp_xmax + _user_xmin;
}

double GraphicCanvas::disp_to_user_y(int y) const
{  
   return (double)(y - _disp_yoff) * (_user_ymax - _user_ymin) / _disp_ymax + _user_ymin;
}

void GraphicCanvas::draw(wxDC& dc, Point s)
{
   const int POINT_RADIUS = 3;
   int disp_x = user_to_disp_x(s.get_x());
   int disp_y = user_to_disp_y(s.get_y());
   dc.DrawEllipse(disp_x - POINT_RADIUS, disp_y - POINT_RADIUS, 
      2 * POINT_RADIUS, 2 * POINT_RADIUS);
}

void GraphicCanvas::draw(wxDC& dc, Circle s)
{
   int disp_x1 = user_to_disp_x(s.get_center().get_x() - s.get_radius());
   int disp_y1 = user_to_disp_y(s.get_center().get_y() - s.get_radius());
   int disp_x2 = user_to_disp_x(s.get_center().get_x() + s.get_radius());
   int disp_y2 = user_to_disp_y(s.get_center().get_y() + s.get_radius());

   dc.DrawEllipse(disp_x1, disp_y1, disp_x2 - disp_x1, disp_y2 - disp_y1);
}

void GraphicCanvas::draw(wxDC& dc, Line s)
{
   int disp_x1 = user_to_disp_x(s.get_start().get_x());
   int disp_y1 = user_to_disp_y(s.get_start().get_y());
   int disp_x2 = user_to_disp_x(s.get_end().get_x());
   int disp_y2 = user_to_disp_y(s.get_end().get_y());
   dc.DrawLine(disp_x1, disp_y1, disp_x2, disp_y2);
}

void GraphicCanvas::draw(wxDC& dc, Message s)
{
   int disp_x = user_to_disp_x(s.get_start().get_x());
   int disp_y = user_to_disp_y(s.get_start().get_y());
   string text = s.get_text();
   dc.DrawText(text.c_str(), disp_x, disp_y);
}

void GraphicCanvas::coord(double xmin, double ymin,
   double xmax, double ymax)
{  
   _user_xmin = xmin;
   _user_xmax = xmax;
   _user_ymin = ymin;
   _user_ymax = ymax;
}

/*-------------------------------------------------------------------------*/

GraphicWindow::GraphicWindow()
{
   canvas = NULL;
   frame = NULL;
   waiting_for_mouse_input = false;
   waiting_for_string_input = false;
}

void GraphicWindow::open(GraphicFrame* f, GraphicCanvas* c)
{
   frame = f;
   canvas = c;
   canvas->clear();
   string_input_count = 0;
   mouse_input_count = 0;
}

void GraphicWindow::coord(double xmin, double ymin,
   double xmax, double ymax)
{  
   canvas->coord(xmin, ymin, xmax, ymax);
}

GraphicWindow& GraphicWindow::operator<<(Point p)
{  
   canvas->add(p);
   return *this;
}

GraphicWindow& GraphicWindow::operator<<(Circle c)
{ 
   canvas->add(c);
   return *this;
}

GraphicWindow& GraphicWindow::operator<<(Line s)
{  
   canvas->add(s);
   return *this;
}

GraphicWindow& GraphicWindow::operator<<(Message t)
{  
   canvas->add(t);
   return *this;
}

int GraphicWindow::get_int(const string& out_string) 
{  
   return atoi(get_string(out_string).c_str()); 
}

double GraphicWindow::get_double(const string& out_string) 
{  
   return atof(get_string(out_string).c_str()); 
}

jmp_buf buf;

string GraphicWindow::get_string(string outstr)
{
   string_input_count++;
   if (string_input_count <= string_inputs.size())
      return string_inputs[string_input_count - 1];
   else
   {
      waiting_for_string_input = true;
      frame->SetStatusText(outstr.c_str());
      frame->set_text_focus(true);
      longjmp(buf, 1);
      return ""; 
   }
}

Point GraphicWindow::get_mouse(string outstr)
{
   mouse_input_count++;
   if (mouse_input_count <= mouse_inputs.size())
      return mouse_inputs[mouse_input_count - 1];
   else 
   {
      waiting_for_mouse_input = true;
      frame->SetStatusText(outstr.c_str());
      longjmp(buf, 1);
      return Point(); 
   }
}

void GraphicWindow::mouse_input(Point p)
{
   if (waiting_for_mouse_input)
   {
      mouse_inputs.push_back(p);
      frame->SetStatusText("");
      waiting_for_mouse_input = false;
      frame->run();
   }
}

void GraphicWindow::string_input(string s)
{
   if (waiting_for_string_input)
   {
      string_inputs.push_back(s);
      frame->SetStatusText("");
      frame->set_text_focus(false);
      waiting_for_string_input = false;
      frame->run();
   }
}

/*-------------------------------------------------------------------------*/

extern int ccc_win_main();

GraphicFrame::GraphicFrame(const wxString& appName) 
   : wxFrame(NULL, -1, appName)
{
   window = new GraphicCanvas(this);
   CreateStatusBar();

   text = new wxTextCtrl(this, ID_TEXT, "", 
      wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);

   wxBoxSizer* frame_sizer = new wxBoxSizer(wxVERTICAL);
   frame_sizer->Add(window, 1, wxGROW);
   frame_sizer->Add(text, 0, wxGROW);

   SetAutoLayout(true);
   SetSizer(frame_sizer);
   Layout();

   run();
}

void GraphicFrame::run()
{
   if (setjmp(buf) == 0)
   { 
      cwin.open(this, window);
      ccc_win_main();
   }
   window->Refresh();
}

void GraphicFrame::set_text_focus(bool b)
{
   if (b) text->SetFocus(); else window->SetFocus();
}

void GraphicFrame::OnEnter(wxCommandEvent& event)
{
   string input = text->GetValue().c_str();
   text->SetValue("");
   cwin.string_input(input);   
}

/*-------------------------------------------------------------------------*/

GraphicApp::GraphicApp()
{
   frame = new GraphicFrame(GetAppName());
}

bool GraphicApp::OnInit()
{
   frame->Show(true);
   return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -