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

📄 draw.cpp

📁 FreeFem++可以生成高质量的有限元网格。可以用于流体力学
💻 CPP
字号:
// -*- Mode : c++ -*-//// SUMMARY  :      // USAGE    :        // ORG      : // AUTHOR   : Antoine Le Hyaric -// E-MAIL   : lehyaric@ann.jussieu.fr///*  This file is part of Freefem++  Freefem++ is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.  Freefem++  is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.  You should have received a copy of the GNU Lesser General Public License along with Freefem++; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */// Graphics window// ---------------// Antoine Le Hyaric - LJLL Paris 6 - lehyaric@ann.jussieu.fr - 21/10/04// $Id: draw.cpp,v 1.3 2006-09-29 20:30:15 hecht Exp $#include "draw.hpp"#ifdef CLIENT#include <FL/Fl.H>#include "spawn.hpp"#endif// Defines a default width and height for FreeFEM++ graphics, that// will be scaled down to the window size when the actual drawing// takes place. Uses "float" to avoid any rounding problems.const float virtualwidth=800.0, virtualheight=800.0;// We also define a virtual font size. It the size of the font that// fits into a window of size virtualwidth x virtualheight. The actual// font size will be scaled to the actual window size.const float virtualfontsize=15.0;// The rest is only useful in a client#ifdef CLIENT// A drawing list shared between FreeFEM++ server thread and the// drawing window. There are two copies to leave the previous one on// screen while the next one is built.list<drawable*> drawings;list<drawable*> backdrawings;// Clears the front picture and transfers the back picture to the// front.void clearlist(list<drawable*> &l){  for(list<drawable*>::iterator d=l.begin();d!=l.end();d++)    delete *d;  l.resize(0);}void flushdrawings(){  // Delete any previous objects from the list of drawings  clearlist(drawings);  // Copies all the newly built objects to have a stable image  // displayed on screen.   for(list<drawable*>::iterator d=backdrawings.begin();       d!=backdrawings.end();       d++)     drawings.push_back((*d)->clone());}// Zooming coefficientsfloat zoomcenterx=0.0,zoomcentery=0.0,zoomscale=1.0;// Translation coefficientsint translatex=0,translatey=0;// Limiting zoom to reasonable limits (X could crash if we ask for// stupidly big fonts for instance).void limitzoomscale(){  if(zoomscale>50.0) zoomscale=50.0;  if(zoomscale<1/50.0) zoomscale=1/50.0;}// Zooming state (necessary for 1-button mice)bool zoominstate=true;void zoomin(Fl_Widget*,void*){  zoominstate=true;}void zoomout(Fl_Widget*,void*){  zoominstate=false;}int coords::widgetleft,  coords::widgettop,  coords::widgetwidth,  coords::widgetheight;// Job control buttonsFl_Button *runbutton=NULL;Fl_Button *pausebutton=NULL;Fl_Button *stopbutton=NULL;Fl_Round_Button *clickpausebutton=NULL;// The graphics toolbar must be accessible from here to be activated// when some graphical data is displayed.Fl_Group *graphicstoolbar=NULL;// Defines default values for the zoom center, such that the graphics// are well centeredvoid resetzoomcenter(){      // The default zoom center should be the center of the virtual  // graphics  zoomcenterx=virtualwidth/2;  zoomcentery=virtualheight/2;  // The default translation should bring the zoom center to the  // middle of the current graphical window (all the  // window-size-dependant components of "translate*" are added inside  // coords::windowscaling()).  translatex=0;  translatey=0;}Tffgraphics::Tffgraphics(int x,int y,int w,int h,const char *label):  Fl_Box(FL_DOWN_BOX,x,y,w,h,label){  color(FL_WHITE);}void Tffgraphics::draw(){  Fl_Box::draw();  // Update the actual widget size with its current value.  coords::widgetleft=x();  coords::widgettop=y();  coords::widgetwidth=w();  coords::widgetheight=h();  // If there is something to draw  if(drawings.size()!=0){    // Clean window borders    const int edge=3;    fl_push_clip(x()+edge,y()+edge,w()-2*edge,h()-2*edge);    // Just ask all the objects to draw themselves    for(list<drawable*>::iterator d=drawings.begin();d!=drawings.end();d++)      (*d)->draw();        fl_pop_clip();    // on Windows, the line style is not reset automatically after    // this.    fl_line_style(FL_SOLID,1);  }}// Compute the zooming center in virtual coordinates from the// given window coordinatesvoid Tffgraphics::findzoomcenter(){  zoomcenterx=coords::virtualscaling(Fl::event_x(),zoomcenterx,				     coords::widgetwidth,				     coords::widgetleft,translatex);  zoomcentery=coords::virtualscaling(Fl::event_y(),zoomcentery,				     coords::widgetheight,				     coords::widgettop,translatey);  // We want the center of interest to stay under the mouse  // cursor. Remove any window-size-dependant component from the  // translation, to be able to redraw the same scene event when the  // window is resized.  translatex=Fl::event_x()-coords::widgetleft-coords::widgetwidth/2;  translatey=Fl::event_y()-coords::widgettop-coords::widgetheight/2;}// Catches the mouse when it comes by!int Tffgraphics::handle(int event){  switch(event){  case FL_PUSH:    // Do we use mouse clicks to un-pause FreeFem++ or to zoom?    if(clickpausebutton->value()){      freefemthreadcomm.WAIT();      if(freefempaused){	freefempause.Incr();	freefempaused=false;	pausebutton->clear();	messagebar->value("FreeFem++ computation resumed");      }      freefemthreadcomm.Free();    }    else{      oldmousex=Fl::event_x();      oldmousey=Fl::event_y();      mousedrag=false;    }    return 1;  case FL_DRAG:    if(!clickpausebutton->value()){      translatex+=Fl::event_x()-oldmousex;      translatey+=Fl::event_y()-oldmousey;      oldmousex=Fl::event_x();      oldmousey=Fl::event_y();      mousedrag=true;      redraw();    }    return 1;  case FL_RELEASE:    // Only if there is currently something to display in the    // graphical window, and if the mouse action was not a drag.    if(drawings.size()!=0 && !mousedrag){      // Do we use mouse clicks to un-pause FreeFem++ or to zoom?      if(!clickpausebutton->value()){	findzoomcenter();	//  Change zoom scale _after_ computing zoom center coordinates!	switch(Fl::event_button()){	case FL_LEFT_MOUSE: // Zoom in	  if(zoominstate) zoomscale*=1.5;	  else zoomscale/=1.5;	  limitzoomscale();	  break;	case FL_MIDDLE_MOUSE: // Zoom reset	  zoomscale=1.0;	  resetzoomcenter();	  break;	case FL_RIGHT_MOUSE: // Zoom out	  if(zoominstate) zoomscale/=1.5;	  else zoomscale*=1.5;	  limitzoomscale();	  break;	default:	  assert(false);	}	redraw();      }    }    return 1;  case FL_ENTER:    messagebar->value("This is the graphical output window");    return 1;  case FL_LEAVE:    // Remove any message we put there when "FL_ENTER" happened.    messagebar->value("");    return 1;  default:    return Fl_Widget::handle(event);  }}Tffgraphics *graphics=NULL;Fl_Group *graphicsarea=NULL;// Resetting the zoom by clicking on a buttonvoid zoomreset(Fl_Widget*,void*){  zoomscale=1.0;  resetzoomcenter();  graphics->redraw();}// Stores the default color that FreeFem++ selected, because we must// remember it even when FreeFem++ clears the graphics (FF++ sets the// color first, and then clears the image!).color *defaultcolor=NULL;#endif // CLIENT

⌨️ 快捷键说明

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