surkhe 6 months ago
parent
commit
6bed4359b6
  1. 57
      AboutWindow.cpp
  2. 15
      AboutWindow.h
  3. 46
      FileWindow.cpp
  4. 25
      FileWindow.h
  5. 17
      GBCSolution.cpp
  6. 12
      GBCSolution.h
  7. 20
      GNU_Ballistics.cpp
  8. 636
      InputWindow.cpp
  9. 40
      InputWindow.h
  10. 23
      LicenseWindow.cpp
  11. 12
      LicenseWindow.h
  12. 7
      Makefile
  13. 7
      Makefile.win32
  14. 75
      PBRWindow.cpp
  15. 27
      PBRWindow.h
  16. 850
      PlotWindow.cpp
  17. 51
      PlotWindow.h
  18. 181
      RangeWindow.cpp
  19. 11
      RangeWindow.h
  20. 0
      blib/_angle.c
  21. 0
      blib/_atmosphere.c
  22. 113
      blib/_pbr.c
  23. 0
      blib/_retard.c
  24. 0
      blib/_retrieve.c
  25. 0
      blib/_solve.c
  26. 0
      blib/_windage.c
  27. 0
      blib/_zero.c
  28. 1
      blib/ballistics.h
  29. 0
      blib/example.c

57
AboutWindow.cpp

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
AboutWindow::AboutWindow(void) : Fl_Window(600,400,"About GNU Ballistics Computer"){
begin();
lic = new Fl_Text_Display(5,5,590,390);
Fl_Text_Buffer* buf = new Fl_Text_Buffer(36000);
buf->text("GNU Exterior Ballistics Computer v1.00\n\
Created by: Derek R. Yates\n\
Released on: February, 2008\n\
Built using: Mingw32 / GCC compiler\n\
\n\
Note from the Creator:\n\
GNU Exterior Ballistics Computer was created as an open-sourced\n\
alternative to the multitude of commercial ballistics computers.\n\
As an avid shooter, I have purchased several commercial packages\n\
over the years, but never found exactly what I wanted in any of them.\n\
I have created this program, and released it under the GNU GPL\n\
License in order to create what I am looking for in a program, \n\
and to give you a base on which to build and improve what I've \n\
started. The unique features I have included are a multitude of\n\
data export features, making it easy to load your data into a variety\n\
of analysis software, from OpenOffice to Microsoft Excel, and also in\n\
Adobe PDF format. Never before has so much ballistics information been\n\
available so freely.\n\
\n\
This program was written in C++, and uses the excellent GNU Exterior\n\
ballistics library (which I wrote previously for personal use). The \n\
solutions are based on the three degrees of freedom differential equations\n\
and solved numerically to get a very accurate solution. In general the\n\
range data is accurate to within 0.1 yards, and the drop data is accurate\n\
to within a fraction of an inch. Standard drag models from G1-G8 are supported\n\
making this program very flexible for advanced ballistics use.\n\
\n\
The GUI was created using FLTK, to allow both Windows and Linux users\n\
to build the source. PDF creation is done using the LibHaru library, which\n\
is highly recommended should you ever need a C++ library for PDF creation.\n\
\n\
I hope you have as much fun using this program as I have had creating it,\n\
and wish you the best shooting.\n");
lic->buffer(buf);
end();
show();
}
AboutWindow::~AboutWindow(void){
delete lic;
}

15
AboutWindow.h

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
#ifndef __ABOUTWINDOW
#define __ABOUTWINDOW
class AboutWindow : public Fl_Window {
public:
AboutWindow(void);
~AboutWindow(void);
private:
Fl_Text_Display* lic;
};
#endif

46
FileWindow.cpp

@ -1,46 +0,0 @@ @@ -1,46 +0,0 @@
FileWindow::FileWindow(int w, int h, const char* title, char** fName) : Fl_Window(w,h,title){
this->complete=0;
this->set_modal();
char cwd[1024];
getcwd(cwd,1024);
FN = fName;
begin();
iFile = new Fl_File_Input(30,50,150,35,"File Name");
iFile->value(cwd);
btOK = new Fl_Button(w-55,h-35,50,30,"OK");
btOK->callback(cb_bt_OK,this);
show();
end();
}
FileWindow::~FileWindow(){
complete=1;
}
void FileWindow::cb_bt_OK(Fl_Widget* fw, void* t){
FileWindow* T = (FileWindow*)t;
T->fw_exit();
}
void FileWindow::fw_exit(){
char* k = (char*)malloc(sizeof(char)*strlen(iFile->value()));
strcpy(k,iFile->value());
printf("\nLOCATION 1: %s",k);
*FN = k;
this->~FileWindow();
}

25
FileWindow.h

@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
#ifndef _FILEWINDOW_H_
#define _FILEWINDOW_H_
#include <unistd.h>
class FileWindow : public Fl_Window{
public:
FileWindow(int w, int h, const char* title, char** fName);
~FileWindow();
int complete;
private:
char** FN;
Fl_Button* btOK;
Fl_File_Input* iFile;
static void cb_bt_OK(Fl_Widget*, void*);
void fw_exit(void);
};
#include "FileWindow.cpp"
#endif

17
GBCSolution.cpp

@ -2,7 +2,7 @@ GBCSolution::GBCSolution(void){ @@ -2,7 +2,7 @@ GBCSolution::GBCSolution(void){
}
GBCSolution::GBCSolution(double* isolution, const char* iname, double ibc, double isightheight, int iweight, int imv, int iangle, int izerorange, int iwindspeed, int iwindangle, int itemp, int ihumidity, double ipressure, int ialtitude, int entries){
GBCSolution::GBCSolution(double* isolution, const char* iname, double ibc, double isightheight, int iweight, int imv, int iangle, int izerorange, int iwindspeed, int iwindangle, int itemp, int ihumidity, double ipressure, int ialtitude, int entries, int useweather){
sln=isolution;
strcpy(name,iname);
@ -19,6 +19,7 @@ GBCSolution::GBCSolution(double* isolution, const char* iname, double ibc, doubl @@ -19,6 +19,7 @@ GBCSolution::GBCSolution(double* isolution, const char* iname, double ibc, doubl
pressure=ipressure;
altitude=ialtitude;
rows=entries;
ckweather=useweather;
}
@ -26,6 +27,7 @@ GBCSolution::GBCSolution(double* isolution, const char* iname, double ibc, doubl @@ -26,6 +27,7 @@ GBCSolution::GBCSolution(double* isolution, const char* iname, double ibc, doubl
GBCSolution::~GBCSolution(){
//delete[] name;
}
@ -152,12 +154,25 @@ double GBCSolution::GetVy(int yardage){ @@ -152,12 +154,25 @@ double GBCSolution::GetVy(int yardage){
else return 0;
}
double GBCSolution::GetEnergy(int k){
return (double)weight*GetVelocity(k)*GetVelocity(k)/450436;
}
int GBCSolution::MaxRows(void){
return rows;
}
int GBCSolution::MaxRows(int mr){
rows=mr;
return rows;
}
int GBCSolution::Weight(void){
return weight;
}
int GBCSolution::UseWeather(void){
return ckweather;
}

12
GBCSolution.h

@ -17,7 +17,8 @@ class GBCSolution { @@ -17,7 +17,8 @@ class GBCSolution {
int ihumidity,
double ipressure,
int ialtitude,
int rows
int rows,
int ckweather
);
~GBCSolution();
@ -37,7 +38,8 @@ class GBCSolution { @@ -37,7 +38,8 @@ class GBCSolution {
int Altitude(void);
int Weight(void);
int MaxRows(void);
int MaxRows(int);
int UseWeather(void);
double GetRange(int yardage);
double GetPath(int yardage);
@ -48,12 +50,11 @@ class GBCSolution { @@ -48,12 +50,11 @@ class GBCSolution {
double GetVelocity(int yardage);
double GetVx(int yardage);
double GetVy(int yardage);
double GetEnergy(int yardage);
private:
double* solution;
char name[1024];
char name[255];
int weight;
double bc;
double sightheight;
@ -63,6 +64,7 @@ class GBCSolution { @@ -63,6 +64,7 @@ class GBCSolution {
int windspeed;
int windangle;
int temp;
int ckweather;
double pressure;
int humidity;

20
GNU_Ballistics.cpp

@ -12,22 +12,34 @@ @@ -12,22 +12,34 @@
#include <FL/Fl_Float_Input.H>
#include <FL/Fl_Multiline_Output.H>
#include <FL/Fl_BMP_Image.H>
#include <FL/Fl_Multi_Browser.H>
#include <FL/Fl_File_Input.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/Fl_Text_Display.H>
#include <FL/Fl_Help_Dialog.H>
#include <FL/Fl_Chart.H>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "AboutWindow.h"
#include "LicenseWindow.h"
#include "GBCSolution.h"
#include "ballistics.h"
#include "blib/ballistics.h"
#include "InputWindow.h"
#include "RangeWindow.h"
#include "PlotWindow.h"
#include "PBRWindow.h"
#include "PlotWindow.cpp"
#include "InputWindow.cpp"
#include "RangeWindow.cpp"
#include "GBCSolution.cpp"
#include "LicenseWindow.cpp"
#include "AboutWindow.cpp"
#include "PBRWindow.cpp"
using namespace std;

636
InputWindow.cpp

@ -1,11 +1,24 @@ @@ -1,11 +1,24 @@
InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
begin();
// Solution pointers. Right now we only use gsln as the general solution pointer.
gsln=NULL;
mem1=NULL;
mem2=NULL;
Solution=NULL;
// A (double*) pointer to the actual solution data. Initialize to
// Null so we can make sure to free any memory it has after a solution
// is closed.
Solution=NULL;
Smem1=NULL;
Smem2=NULL;
useSolution=1;
// Start drawing the widgets on screen.
begin();
// Draw any general purpose borders or labels.
Fl_Box* GBox = new Fl_Box(250,80,140,95,"Drag Function");
GBox->box(FL_BORDER_BOX);
@ -62,7 +75,7 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){ @@ -62,7 +75,7 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
inSH->value("1.6");
// Put a checkbox to enable atmospheric corrections.
// Put a checkbox to enable or disable atmospheric corrections.
ckWeather = new Fl_Check_Button(10,290,20,20,"Enable Atmospheric Corrections");
ckWeather->align(FL_ALIGN_RIGHT);
ckWeather->callback(cb_ckWeather,this);
@ -78,30 +91,32 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){ @@ -78,30 +91,32 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
inAltitude->align(FL_ALIGN_RIGHT);
inHumidity->align(FL_ALIGN_RIGHT);
// Set the default to standard atmosphere.
inTemp->value("59");
inAltitude->value("0");
inPressure->value("29.53");
inHumidity->value("78");
// Disable the atmospheric conditions at first.
// Disable the atmospheric conditions at first since many users may not want to use it.
ckWeather->activate();
inTemp->deactivate();
inAltitude->deactivate();
inPressure->deactivate();
inHumidity->deactivate();
// Initialize the output window display.
oStatus = new Fl_Multiline_Output(10,420,380,70,"Solution Status");
oStatus->align(FL_ALIGN_LEFT | FL_ALIGN_TOP | FL_ALIGN_INSIDE);
oStatus->value("GNU Ballistic Computer: Waiting for Input");
oStatus->value("GNU Ballistic Computer: Waiting for input.");
// Create and place buttons on the form.
btSolve = new Fl_Button( 340, 380, 50, 30, "So&lve");
btReset = new Fl_Button( 280, 380, 50, 30, "&Reset");
btSolve = new Fl_Button( 280, 380, 50, 30, "So&lve");
btReset = new Fl_Button( 340, 380, 50, 30, "&Reset");
btSolve->callback(cb_Solve,this);
btReset->callback(cb_Clear, this);
// Declare the menu bar variables
// m for menu, mc for menu choice.
@ -110,132 +125,102 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){ @@ -110,132 +125,102 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
Fl_Menu_Item m_File = {"&File",0,0,0,FL_SUBMENU};
Fl_Menu_Item mc_New = {"&New...",0,(Fl_Callback*)cb_mNew,this};
Fl_Menu_Item mc_Open = {"&Open...",0,(Fl_Callback*)cb_mOpen,this};
Fl_Menu_Item mc_Save = {"&Save...",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Export = {"&Export Data...",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Open = {"&Open...",0,(Fl_Callback*)cb_Open,this};
Fl_Menu_Item mc_Save = {"&Save...",0,(Fl_Callback*)cb_Save,this};
//Fl_Menu_Item mc_Export = {"&Export Data...",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Quit = {"&Quit",0,(Fl_Callback*)cb_Quit};
Fl_Menu_Item m_Edit = {"&Edit",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_Copy = {"&Copy",0,(Fl_Callback*)cb_Copy,this};
Fl_Menu_Item mc_Paste = {"&Paste",0,(Fl_Callback*)cb_Paste,this};
Fl_Menu_Item mc_Options = {"&Options",0,(Fl_Callback*)cb_Nothing};
//Fl_Menu_Item m_Edit = {"&Edit",0,0,0, FL_SUBMENU};
//Fl_Menu_Item mc_Copy = {"&Copy",0,(Fl_Callback*)cb_Copy,this};
//Fl_Menu_Item mc_Paste = {"&Paste",0,(Fl_Callback*)cb_Paste,this};
//Fl_Menu_Item mc_Options = {"&Options",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item m_Analyze = {"&Analyze",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_Table = {"&Range Table",0,(Fl_Callback*)cb_RangeTable,this};
Fl_Menu_Item mc_Plot = {"&Plot...",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Plot = {"&Plot...",0,(Fl_Callback*)cb_Plot, this};
Fl_Menu_Item mc_Compare = {"&Compare...",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item m_Aids = {"Shooting &Aids",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_RangeCard = {"&Range Card",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_ClickChart = {"&Click Chart",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_RangeTable = {"&Range Table",0,(Fl_Callback*)cb_Nothing};
//Fl_Menu_Item mc_RangeTable = {"&Range Table",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item m_Solution = {"&Analysis",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_Solve = {"&Solve",0,(Fl_Callback*)cb_Solve,this};
//Fl_Menu_Item mc_Solve = {"&Solve",0,(Fl_Callback*)cb_Solve,this};
Fl_Menu_Item mc_Advanced = {"&Advanced Settings",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item m_Help = {"&Help",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_Help = {"&Online Help",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_License = {"&License",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_About = {"&About",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Bug = {"&Bug Report",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Help = {"&Help",0,(Fl_Callback*)cb_HelpWindow};
Fl_Menu_Item mc_License = {"&License",0,(Fl_Callback*)cb_LicenseWindow};
Fl_Menu_Item mc_About = {"&About",0,(Fl_Callback*)cb_AboutWindow};
Fl_Menu_Item m_Tools = {"&Tools",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_OptimizePBR = {"&Optimize PBR",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_OptimizePBR = {"&Optimize PBR",0,(Fl_Callback*)cb_PBR,this};
Fl_Menu_Item mc_CalcBC = {"&Calculate Drag Coefficient",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item m_Compare = {"&Compare",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_Store1 = {"Store Solution 1",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Store2 = {"Store Solution 2",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Store3 = {"Store Solution 3",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Store4 = {"Store Solution 4",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_Store5 = {"Store Solution 5",0,(Fl_Callback*)cb_Nothing,0,FL_MENU_DIVIDER};
Fl_Menu_Item mc_CompareTable = {"Table",0,0,0,FL_SUBMENU};
Fl_Menu_Item mc_CompareDrop = {"Drop Table",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_CompareVelocity = {"Velocity Table",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_CompareEnergy = {"Energy Table",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_CompareWind = {"Windage Table",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_ComparePlot = {"Plot",0,0,0,FL_SUBMENU};
Fl_Menu_Item mc_PlotDrop = {"Drop Plot",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_PlotVelocity = {"Velocity Plot",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_PlotEnergy = {"Energy Plot",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item mc_PlotWind = {"Wind drift Plot",0,(Fl_Callback*)cb_Nothing};
Fl_Menu_Item m_Compare = {"&Solution Memory",0,0,0, FL_SUBMENU};
Fl_Menu_Item mc_Store1 = {"Store to Memory 1 ",0,(Fl_Callback*)cb_Store1,this};
Fl_Menu_Item mc_Store2 = {"Store to Memory 2 ",0,(Fl_Callback*)cb_Store2,this};
//Fl_Menu_Item mc_Store3 = {"Save to Memory 3 ",0,(Fl_Callback*)cb_Store3,this};
//Fl_Menu_Item mc_Store4 = {"Save to Memory 4 ",0,(Fl_Callback*)cb_Store4,this};
//Fl_Menu_Item mc_Store5 = {"Save to Memory 5 ",0,(Fl_Callback*)cb_Store5,this,FL_MENU_DIVIDER};
// Set initial condition for menu items.
m_Analyze.deactivate();
m_Aids.deactivate();
//mc_Export.deactivate(); // Data exports from the RangeTable window.
// These are planned features, but haven't been done yet.
mc_Open.deactivate(); // The open and save will be done together.
mc_Save.deactivate();
mc_Export.deactivate(); // Lower priority, but needs to be done.
////// TODO //////
////// TODO //////
mc_Advanced.deactivate(); // Maybe no need?
mc_Copy.deactivate(); // Can't figure out how to make this work. User can use Ctrl-c until I get some help.
mc_Options.deactivate(); // Eventually add support for metric
mc_Compare.deactivate();
mc_Plot.deactivate();
mc_RangeCard.deactivate();
mc_ClickChart.deactivate();
mc_RangeTable.deactivate();
mc_Table.deactivate();
//mc_RangeTable.deactivate();
//mc_Table.deactivate();
mc_CalcBC.deactivate();
mc_OptimizePBR.deactivate();
mc_Store1.deactivate();
mc_Store2.deactivate();
mc_Store3.deactivate();
mc_Store4.deactivate();
mc_Store5.deactivate();
mc_CompareTable.deactivate();
mc_ComparePlot.deactivate();
//mc_OptimizePBR.deactivate();
//mc_Plot.deactivate();
m_Solution.deactivate();
m_Compare.deactivate();
Fl_Menu_Item menuitems[] = {
m_File, //1
m_File, //0
mc_New,
mc_Open,
mc_Save,
mc_Export,
mc_Quit,
{0},//7
m_Edit,
mc_Copy,
mc_Paste,
mc_Options,
{0},
m_Solution, //12
mc_Solve,
{0},//5
//m_Edit,
//mc_Copy,
//mc_Paste,
//mc_Options,
//{0},
m_Solution, //6
//mc_Solve,
mc_Table,
mc_Plot,
mc_Compare,
mc_RangeCard,
mc_ClickChart,
mc_RangeTable,
{0}, // 21
//mc_RangeTable,
{0}, // 12
m_Tools,
mc_OptimizePBR,
mc_CalcBC,
{0},
m_Compare,
mc_Store1,
mc_Store2,
mc_Store3,
mc_Store4,
mc_Store5,
mc_CompareTable,
mc_CompareDrop,
mc_CompareVelocity,
mc_CompareEnergy,
mc_CompareWind,
{0},
mc_ComparePlot,
mc_PlotDrop,
mc_PlotVelocity,
mc_PlotEnergy,
mc_PlotWind,
{0},
m_Compare, //17
mc_Store1, //18
mc_Store2, //19
//mc_Store3,
//mc_Store4,
//mc_Store5,
{0},
m_Help, //26
mc_Help,
@ -248,23 +233,44 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){ @@ -248,23 +233,44 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
menu->copy(menuitems);
end();
//resizable(this);
show();
}
InputWindow::~InputWindow(){
// Free any memory we are using.
if (Solution!=NULL) {
free(Solution);
Solution=NULL;
}
if (Smem1!=NULL) {
free(Smem1);
Solution=NULL;
}
if (Smem2!=NULL) {
free(Smem2);
Solution=NULL;
}
if (gsln!=NULL) {
free(gsln);
Solution=NULL;
}
if (mem1!=NULL) {
free(mem1);
Solution=NULL;
}
if (mem2!=NULL) {
free(mem2);
Solution=NULL;
}
}
void InputWindow::cb_ckWeather(Fl_Widget* o, void* v){
@ -286,14 +292,17 @@ void InputWindow::cb_ckWeather(Fl_Widget* o, void* v){ @@ -286,14 +292,17 @@ void InputWindow::cb_ckWeather(Fl_Widget* o, void* v){
}
void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
DisableMenu(vd);
InputWindow* T = (InputWindow*)vd;
void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
if (T->Solution != NULL) {
free(T->Solution);
T->Solution=NULL;
}
// If we have an old solution, clean up its memory areas now.
// Disable the analysis menu.
DisableMenu(vd);
InputWindow* T = (InputWindow*)vd;
// Make some local pointers to use in the function, before we assign the solution
// to the currently selected "working" solution on the UI.
GBCSolution* lsln = NULL;
double* lSolution = NULL;
double bc=-1; // The ballistic coefficient for the projectile.
double v=-1; // Intial velocity, in ft/s
@ -323,6 +332,8 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) { @@ -323,6 +332,8 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
else if (T->inG7->value()==1) df=G7;
else if (T->inG8->value()==1) df=G8;
// If the Enable Weather checkbox is activated, we correct the
// Ballistic coefficient for the non-std weather conditions.
if (T->ckWeather->value()==1){
double Altitude = atof(T->inAltitude->value());
@ -331,20 +342,22 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) { @@ -331,20 +342,22 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
double RH = atof(T->inHumidity->value())/100;
bc = AtmCorrect(bc, Altitude,Barometer,Temperature,RH);
}
zeroangle=ZeroAngle(df,bc,v,1.6,zero,0);
numRows = SolveAll(df,bc,v,sh,angle,zeroangle,windspeed,windangle,&(T->Solution));
// Find the zero angle of the bore relative to the sighting system.
zeroangle=ZeroAngle(df,bc,v,sh,zero,0);
if (numRows>0 && T->Solution!=NULL){ // Solution is valid with no errors.
// Generate a solution using the GNU Ballistics library call.
numRows = SolveAll(df,bc,v,sh,angle,zeroangle,windspeed,windangle,&(lSolution));
// If we get a valid solution, store it as a new GBC Solution.
// T->gsln was cleaned up at the beginning of this function,
// so we know it points to NULL already.
if (numRows>0 && lSolution!=NULL){ // Solution is valid with no errors.
// Store some general data about the load and weather conditions in the 2048 extra bytes.
T->gsln = new GBCSolution(
T->Solution,
lsln = new GBCSolution(
lSolution,
T->inName->value(),
atof(T->inBC->value()),
atof(T->inSH->value()),
@ -358,71 +371,100 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) { @@ -358,71 +371,100 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
atoi(T->inHumidity->value()),
atof(T->inPressure->value()),
atoi(T->inAltitude->value()),
(int)T->Solution[10*__BCOMP_MAXRANGE__+1]
(int)T->Solution[10*__BCOMP_MAXRANGE__+1],
T->ckWeather->value()
);
// Inform the user of our success.
sprintf(txt1,"GNU Ballistics Computer: Solution Valid.\nSolution's maximum valid range is %d yards\nUse the options in the 'Solution' menu to view results.",numRows-2);
// SEGMENTATION FAULT IS CAUSED BY THIS LINE ???
// Update the maximum valid range of the solution.
// We do this separately because I'm too lazy to update the GBCSolution() constructor,
// but we need this data to pass into the RangeWindow for maximum distances.
lsln->MaxRows(numRows);
if (lsln == NULL){
// Inform the user of our failure.
sprintf(txt1,"GNU Ballistics Computer: Solution failed! Unknown error.");
T->oStatus->value(txt1);
EnableMenu((InputWindow*) vd);
}
return;
}
// Otherwise we assume success, and inform the user of our success.
sprintf(txt1,"GNU Ballistics Computer: Solution Valid.\nSolution's maximum valid range is %d yards\nUse the options in the 'Solution' menu to view results.",numRows-2);
T->oStatus->value(txt1);
EnableMenu((InputWindow*) vd);
// Now we need to figure out which solution the user wanted to store this as, and
// assign our local pointers to the user's requested solution.
if (T->gsln!=NULL){
if (T->gsln->sln != NULL) free(T->gsln->sln);
delete(T->gsln);
}
T->gsln=lsln;
return;
}
return;
}
void InputWindow::EnableMenu(void* v){
InputWindow* T = (InputWindow*)v;
// Enable the Analyze and Shooting Aids menu items.
// Enable the Analyze menu. This function is a crude way to do it, but it works.
// I'm looking for a better way to do this, but have yet to find one.
Fl_Menu_Item* mp;
mp=(Fl_Menu_Item*)&(T->menu->menu()[14]);
mp=(Fl_Menu_Item*)&(T->menu->menu()[6]);
mp->activate();
// mp=(Fl_Menu_Item*)&(T->menu->menu()[17]);
// mp->activate();
mp=(Fl_Menu_Item*)&(T->menu->menu()[17]);
mp->activate();
T->redraw();
}
void InputWindow::DisableMenu(void* v){
InputWindow* T = (InputWindow*)v;
// Enable the Analyze and Shooting Aids menu items.
// Disable the Analyze menu. This function is a crude way to do it.
Fl_Menu_Item* mp;
mp=(Fl_Menu_Item*)&(T->menu->menu()[14]);
mp=(Fl_Menu_Item*)&(T->menu->menu()[6]);
mp->deactivate();
// mp=(Fl_Menu_Item*)&(T->menu->menu()[17]);
// mp->deactivate();
mp=(Fl_Menu_Item*)&(T->menu->menu()[17]);
mp->deactivate();
T->redraw();
}
void InputWindow::cb_copy_i() {
// out->value(inp->value());
}
void InputWindow::cb_File(Fl_Widget*, void* v) {
// out->value(inp->value());
}
// While I get the program running, some buttons will
// do nothing. For that they get to point to this callback.
void InputWindow::cb_Nothing(Fl_Widget*, void* v) {
// out->value(inp->value());
;
}
void InputWindow::cb_Quit(Fl_Widget*, void* v) {
exit(0);
// The example program I used to create this used this function to
// Exit the program. I think the destructor might work better.
exit(0);
// But I haven't figured out how to call it yet.
//InputWindow* T = (InputWindow*)v;
//T->~InputWindow();
// Above code results in a program crash???
}
// We seem to have a memory leak here??
// When the use clicks "solve" and "reset" and "solve" again, there is an extra 460 kb lost.
void InputWindow::cb_Clear(Fl_Widget* o, void* v) {
DisableMenu(v);
InputWindow* T=(InputWindow*)v;
// When the "Reset" button is clicked, we want to
// clear out the old solution and restore std. conditions.
DisableMenu(v);
T->inBC->value("0.465");
T->inMV->value("2650");
T->inZero->value("200");
@ -435,52 +477,97 @@ void InputWindow::cb_Clear(Fl_Widget* o, void* v) { @@ -435,52 +477,97 @@ void InputWindow::cb_Clear(Fl_Widget* o, void* v) {
T->inAltitude->value("0");
T->inPressure->value("29.53");
T->inHumidity->value("78");
T->inName->value("308 Win Match, 168gr Sierra Match King");
T->ckWeather->clear();
T->cb_ckWeather(o,v);
T->oStatus->value("GNU Ballistic Computer: Solution Reset");
// Free up any memory we have been using.
if (T->Solution != NULL) {
free(T->Solution);
T->Solution=NULL;
}
if (T->gsln != NULL) {
if (T->gsln->sln!=NULL) free (T->gsln->sln);
T->gsln->~GBCSolution();
delete(T->gsln);
T->gsln=NULL;
}
if (T->mem1 != NULL) {
if (T->mem1->sln!=NULL) free (T->mem1->sln);
T->mem1->~GBCSolution();
delete(T->mem1);
T->mem1=NULL;
}
if (T->Smem1 != NULL) {
free(T->Smem1);
T->Smem1=NULL;
}
if (T->mem2 != NULL) {
if (T->mem2->sln!=NULL) free(T->mem2->sln);
T->mem2->~GBCSolution();
delete(T->mem2);
T->mem2=NULL;
}
if (T->Smem2 != NULL) {
free(T->Smem2);
T->Smem1=NULL;
}
// Turn the memory labels back to black to show they are null.
Fl_Menu_Item* mp;
mp=(Fl_Menu_Item*)&(T->menu->menu()[18]);
mp->labelcolor(FL_BLACK);
mp=(Fl_Menu_Item*)&(T->menu->menu()[19]);
mp->labelcolor(FL_BLACK);
}
// Using the "New" Menu button does the same thing as the reset button.
void InputWindow::cb_mNew(Fl_Widget* o, void* v){
DisableMenu(v);
InputWindow* T=(InputWindow*)v;
T->cb_Clear(o,v);
T->oStatus->value("GNU Ballistic Computer: Solution cleared. \nNow begin new Solution");
}
void InputWindow::cb_quit(Fl_Widget* o, void* v) {
( (InputWindow*)v )->cb_quit_i();
}
void InputWindow::cb_quit_i() {
hide();
}
void InputWindow::cb_mOpen(Fl_Widget* o, void* v) {
DisableMenu(v);
InputWindow* T = (InputWindow*)v;
T->oStatus->value("Select file to load...");
}
// Don't remember where these came from... I'm not sure they're used at all in fact.
// I've commented them out for now. The next release will have them removed if no
// break-downs are found due to removal. I think they are from when I first started
// making the program, but didn't really know what to do yet for FLTK.
//void InputWindow::cb_quit(Fl_Widget* o, void* v) {
// ( (InputWindow*)v )->cb_quit_i();
//}
//void InputWindow::cb_quit_i() {
// hide();
//}
//void InputWindow::cb_mOpen(Fl_Widget* o, void* v) {
// DisableMenu(v);
// InputWindow* T = (InputWindow*)v;
// T->oStatus->value("Select file to load...");
//}
void InputWindow::cb_RangeTable(Fl_Widget*, void* v){
InputWindow* T = (InputWindow*)v;
char str[100];
strcpy(str,"Range Table: ");
RangeWindow* Rw = new RangeWindow(600,400,T->gsln);
// Spawn a new RangeWindow using the current solution to populate it.
if (T->gsln != NULL && T->gsln->sln != NULL){
new RangeWindow(600,400,T->gsln);
}
else {
T->oStatus->value("Error creating Range Window. Unknown Error.");
}
}
}
// Implement the paste function. This I did actually figure out how to do.
// The Cut function isn't working yet, but Ctrl-C and Ctrl-V are fortunately
// built into FLTK, so they both work.
void InputWindow::cb_Paste(Fl_Widget* r, void* v){
InputWindow* T = (InputWindow*)v;
T->Paste();
@ -488,10 +575,9 @@ void InputWindow::cb_Paste(Fl_Widget* r, void* v){ @@ -488,10 +575,9 @@ void InputWindow::cb_Paste(Fl_Widget* r, void* v){
void InputWindow::cb_Copy(Fl_Widget* r, void* v){
InputWindow* T = (InputWindow*)v;
T->Copy();
T->Copy();
}
void InputWindow::Paste(){
Fl::paste(*this,1);
}
@ -509,7 +595,223 @@ void InputWindow::Copy(){ @@ -509,7 +595,223 @@ void InputWindow::Copy(){
// Can't figure out how to do this?? very strange...
}
void InputWindow::cb_HelpWindow(Fl_Widget* r, void* vtt){
// Spawn a new help window, this will show whatever is in HelpFile.html
Fl_Help_Dialog* hd = new Fl_Help_Dialog();
hd->load("HelpFile.html");
hd->show();
}
void InputWindow::cb_LicenseWindow(Fl_Widget* r, void*v){
// The LicenseWindow has all the license hard-coded into it,
// so we just need to spawn it and forget about it.
// I don't think this will make a memory leak since it will
// call it's own destructor when it exits.
new LicenseWindow();
}
void InputWindow::cb_AboutWindow(Fl_Widget*,void*v){
// Spawn a new AboutWindow.
new AboutWindow();
}
void InputWindow::cb_Save(Fl_Widget*, void*v){
// If we save the whole solution its like 4mb, so just save the parameters
// and we can regenerate the solution after we reload the parameters.
InputWindow* T = (InputWindow*)v;
if (T->gsln != NULL){
// Get the file name we want to save the data as, using the FLTK standard file picker function.
char* fname=NULL;
fname = fl_file_chooser("Please select a location to save the data.","*.gbc","OutputData.gbc",0);
if (fname==NULL) return;
// Open the file for binary writing.
FILE* ofile = fopen(fname,"wb");
// Write the current solution class to the file, then close it.
int wrote;
wrote=fwrite(T->gsln,1,sizeof(GBCSolution),ofile);
fclose(ofile);
// Update the status display to show our success.
if (wrote == sizeof(GBCSolution)){
T->oStatus->value("GNU Ballistic Computer: File saved successfully.");
}
else {
T->oStatus->value("GNU Ballistic Computer: There was an error writing the file. Please check the path and try again.");
}
}
else {
T->oStatus->value("GNU Ballistic Computer: Can not save, since the solution \nis not yet created. Please create the solution using the \n'Solve' button before you save it.");
}
return;
}
void InputWindow::cb_Open(Fl_Widget* o, void*v){
InputWindow* T = (InputWindow*)v;
// A solution for locally working with gsln (hence the name lsln)
GBCSolution* lsln = NULL;
// Get the file name to load
char* fname=NULL;
fname = fl_file_chooser("Please select a file to open.","*.gbc","",0);
if (fname==NULL) {
T->oStatus->value("GNU Ballistic Computer: Error opening file!");
return;
}
// and open it for binary read.
FILE* ofile = fopen(fname,"rb");
// Free an old solution if there is one, because we want to
// write over it.
if (T->gsln != NULL) {
free(T->gsln);
T->gsln=NULL;
}
// Allocate some space for the loaded solution.
if (lsln != NULL) free(lsln);
lsln = (GBCSolution*)malloc(sizeof(GBCSolution));
if (lsln==NULL){
T->oStatus->value("GNU Ballistic Computer: Memory allocation error.");
return;
}
// Read the GBCSolution class from the file and load it into program
// memory. check to make sure we read the right amount of data.
int read;
read=fread(lsln,1,sizeof(GBCSolution),ofile);
fclose(ofile);
if (read!=sizeof(GBCSolution)){
T->oStatus->value("GNU Ballistic Computer: Error reading file data!\nPlease ensure the file is a valid GNUBC solution.");
if (lsln!=NULL) free(lsln);
if (T->gsln!=NULL) free(T->gsln);
return;
}
// Set the parent's solution pointer to the local one we just imported.
T->gsln = lsln;
// Load the solution data into the INPUT fields in the InputWindow.
char buff[1024];
T->inName->value(lsln->Name());
sprintf(buff,"%.3f",lsln->BC()); T->inBC->value(buff);
sprintf(buff,"%.2f",lsln->SightHeight()); T->inSH->value(buff);
sprintf(buff,"%d",lsln->MuzzleVelocity()); T->inMV->value(buff);
sprintf(buff,"%d",lsln->ShootingAngle()); T->inAngle->value(buff);
sprintf(buff,"%d",lsln->ZeroRange()); T->inZero->value(buff);
sprintf(buff,"%d",lsln->WindSpeed()); T->inVwind->value(buff);
sprintf(buff,"%d",lsln->WindAngle()); T->inAwind->value(buff);
sprintf(buff,"%d",lsln->Temp()); T->inTemp->value(buff);
sprintf(buff,"%.2f",lsln->Pressure()); T->inPressure->value(buff);
sprintf(buff,"%d",lsln->Humidity()); T->inHumidity->value(buff);
sprintf(buff,"%d",lsln->Altitude()); T->inAltitude->value(buff);
sprintf(buff,"%d",lsln->Weight()); T->inWeight->value(buff);
T->ckWeather->value(lsln->UseWeather());
T->cb_ckWeather(o,v);
// And now solve the loaded parameters.
DisableMenu(T);
T->cb_Solve(o,v);
// Finally inform the user of our success.
T->oStatus->value("GNU Ballistics Computer: File loaded successfully.");
return;
}
void InputWindow::cb_Plot(Fl_Widget* o, void* v){
InputWindow* T = (InputWindow*)v;
GBCSolution* sln = T->gsln;
GBCSolution* lmem1 = T->mem1;
GBCSolution* lmem2 = T->mem2;
new PlotWindow(700,500,sln,lmem1,lmem2);
}
void InputWindow::cb_Store1(Fl_Widget* o, void* v){
InputWindow* T = (InputWindow*)v;
T->oStatus->value("GNU Ballistics Computer: Stored to Memory 1");
if (T->mem1 != NULL) {
if (T->mem1->sln!=NULL) free (T->mem1->sln);
delete(T->mem1);
}
if (T->Smem1!= NULL) free(T->Smem1);
T->mem1=T->gsln;
T->Smem1=T->Solution;
T->gsln=NULL;
T->Solution=NULL;
// Turn the label blue to indicate it's been used.
Fl_Menu_Item* mp;
mp=(Fl_Menu_Item*)&(T->menu->menu()[18]);
mp->labelcolor(FL_RED);
cb_Solve(o,v);
}
void InputWindow::cb_Store2(Fl_Widget* o, void* v){
InputWindow* T = (InputWindow*)v;
T->oStatus->value("GNU Ballistics Computer: Stored to Memory 2");
if (T->mem2 != NULL) {
if (T->mem2->sln!=NULL) free(T->mem2->sln);
delete(T->mem1);
}
if (T->Smem2!= NULL) free(T->Smem1);
T->mem2=T->gsln;
T->Smem2=T->Solution;
T->gsln=NULL;
T->Solution=NULL;
// Turn the label blue to indicate it's been used.
Fl_Menu_Item* mp;
mp=(Fl_Menu_Item*)&(T->menu->menu()[19]);
mp->labelcolor(FL_GREEN);
cb_Solve(o,v);
}
void InputWindow::cb_PBR(Fl_Widget* o, void* v){
InputWindow* T = (InputWindow*)v;
new PBRWindow(T);
}

40
InputWindow.h

@ -15,8 +15,17 @@ class InputWindow : public Fl_Window{ @@ -15,8 +15,17 @@ class InputWindow : public Fl_Window{
Fl_Button* btCompare;
Fl_Button* btSaveSolution;
Fl_Button* btLoadSolution;
double* Solution;
double* Smem1;
double* Smem2;
GBCSolution* gsln;
GBCSolution* mem1;
GBCSolution* mem2;
int useSolution;
// Drag function selection pointers.
Fl_Round_Button* inG1;
@ -40,7 +49,6 @@ class InputWindow : public Fl_Window{ @@ -40,7 +49,6 @@ class InputWindow : public Fl_Window{
Fl_Float_Input* inPressure;
Fl_Int_Input* inHumidity;
Fl_Int_Input* inAltitude;
//Fl_Input* inStepSize;
Fl_Menu_Bar *menu;
Fl_Menu_Item *pmenuitems;
@ -81,28 +89,48 @@ class InputWindow : public Fl_Window{ @@ -81,28 +89,48 @@ class InputWindow : public Fl_Window{
Fl_Multiline_Output* oStatus;
// Fl_Menu_Item mc_Store1,mc_Store2, mc_Store3, mc_Store4, mc_Store5;
// FL Outputs
Fl_Output* out;
private:
static void cb_Solve(Fl_Widget*, void*);
inline void cb_copy_i();
static void cb_quit(Fl_Widget*, void*);
inline void cb_quit_i();
static void cb_File(Fl_Widget*, void*);
//inline void cb_copy_i();
//static void cb_quit(Fl_Widget*, void*);
//inline void cb_quit_i();
static void cb_Quit(Fl_Widget*, void*);
static void cb_Nothing(Fl_Widget*, void*);
static void cb_ckWeather(Fl_Widget*, void*);
static void cb_Clear(Fl_Widget*, void*);
static void cb_mNew(Fl_Widget*, void*);
static void cb_mOpen(Fl_Widget* , void* );
//static void cb_mOpen(Fl_Widget* , void* );
static void EnableMenu(void*);
static void DisableMenu(void*);
static void cb_RangeTable(Fl_Widget*, void* );
static void cb_Paste(Fl_Widget*, void* v);
static void cb_Copy(Fl_Widget*, void* v);
static void cb_HelpWindow(Fl_Widget*, void*v);
static void cb_LicenseWindow(Fl_Widget*, void*v);
static void cb_AboutWindow(Fl_Widget*,void*v);
static void cb_Save(Fl_Widget*, void*);
static void cb_Open(Fl_Widget*, void*);
static void cb_Plot(Fl_Widget*, void*);
static void cb_Store1(Fl_Widget*, void*);
static void cb_Store2(Fl_Widget*, void*);
//static void cb_Store3(Fl_Widget*, void*);
//static void cb_Store4(Fl_Widget*, void*);
//static void cb_Store5(Fl_Widget*, void*);
static void cb_PBR(Fl_Widget*, void*);
void Paste(void);
void Copy(void);
};

23
LicenseWindow.cpp

File diff suppressed because one or more lines are too long

12
LicenseWindow.h

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
#ifndef __LICENSEWINDOW
#define __LICENSEWINDOW
class LicenseWindow : public Fl_Window {
public:
LicenseWindow(void);
~LicenseWindow(void);
};
#endif

7
Makefile

@ -1,4 +1,7 @@ @@ -1,4 +1,7 @@
All:
fltk-config --use-images --compile GNU_Ballistics.cpp
CFLAGS = -I/usr/local/include -I/usr/local/include/FL/images -mwindows -DWIN32 -mno-cygwin
LDFLAGS = -L/usr/local/lib -mwindows -mno-cygwin -lfltk -lfltk_images -lfltk_png -lfltk_z -lfltk_jpeg -lfltk -lole32 -luuid -lcomctl32 -lwsock32 -lhpdf -lz -lm
All:
g++ -Wall -g ${CFLAGS} -o GNU_Ballistics.exe GNU_ballistics.cpp ${LDFLAGS}

7
Makefile.win32

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
CFLAGS = -I/usr/local/include -I/usr/local/include/FL/images -mwindows -DWIN32 -mno-cygwin
LDFLAGS = -L/usr/local/lib -mwindows -mno-cygwin -lfltk -lfltk_images -lfltk_png -lfltk_z -lfltk_jpeg -lfltk -lole32 -luuid -lcomctl32 -lwsock32 -lhpdf -lz -lm
All:
g++ ${CFLAGS} -o GNU_Ballistics.exe GNU_ballistics.cpp ${LDFLAGS}

75
PBRWindow.cpp

@ -0,0 +1,75 @@ @@ -0,0 +1,75 @@
PBRWindow::PBRWindow(InputWindow* IW):Fl_Window(250,270,"Optimize Point Blank Range") {
inW = IW;
if (inW==NULL) return;
begin();
CD = new Fl_Float_Input(30,20,60,25,"Drag Coefficient");
VI = new Fl_Int_Input(30,50,60,25,"Initial Velocity (ft/s)");
SH = new Fl_Float_Input(30,80,60,25,"Sight Height (inches)");
VitalSize = new Fl_Float_Input(30,110,60,25,"Vital Zone Size (inches)");
VI->value(IW->inMV->value());
VitalSize->value("3.0");
CD->value(IW->inBC->value());
SH->value(IW->inSH->value());
VI->align(FL_ALIGN_RIGHT);
VitalSize->align(FL_ALIGN_RIGHT);
CD->align(FL_ALIGN_RIGHT);
SH->align(FL_ALIGN_RIGHT);
Calc = new Fl_Button(65,150,120,25,"Optimize PBR");
Calc->callback(cb_calc, this);
oStatus = new Fl_Multiline_Output(10,190,230,70,"");
oStatus->value("Waiting for input...");
end();
show();
}
PBRWindow::~PBRWindow(void){
delete CD;
delete VI;
delete SH;
delete VitalSize;
delete Calc;
delete oStatus;
}
void PBRWindow::cb_calc(Fl_Widget* o, void* v){
PBRWindow* T = (PBRWindow*)v;
int result[4];
int df=0;
// Use the InputWindow selected drag function since I forgot
// to put a selector on this window, and most people won't want
// to change it anyway.
if (T->inW->inG1->value()==1) df=G1;
if (T->inW->inG2->value()==1) df=G2;
if (T->inW->inG5->value()==1) df=G5;
if (T->inW->inG6->value()==1) df=G6;
if (T->inW->inG7->value()==1) df=G7;
if (T->inW->inG8->value()==1) df=G8;
double cd = atof(T->CD->value());
double mv = atof(T->VI->value());
double sh = atof(T->SH->value());
double vs = atof(T->VitalSize->value());
pbr(df,cd,mv, sh, vs,(int*)&result);
char txt[64];
sprintf(txt,"Optimum Zero Range: %d yards\nMinimum PBR: %d yards\nMaximum PBR: %d yards",result[0], result[1], result[2]);
T->oStatus->value(txt);
}

27
PBRWindow.h

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
#ifndef __PBRWINDOW
#define __PBRWINDOW
class PBRWindow : public Fl_Window {
public:
PBRWindow(InputWindow*);
~PBRWindow();
private:
InputWindow* inW;
Fl_Int_Input* VI;
Fl_Float_Input* CD;
Fl_Float_Input* SH;
Fl_Float_Input* VitalSize;
Fl_Button* Calc;
Fl_Multiline_Output* oStatus;
static void cb_calc(Fl_Widget*, void*);
};
#endif

850
PlotWindow.cpp

@ -0,0 +1,850 @@ @@ -0,0 +1,850 @@
PlotWindow::PlotWindow(int w, int h, GBCSolution* Gsln, GBCSolution* GMEM1, GBCSolution* GMEM2) : Fl_Window(w,h,"Solution Visualization Tools"){
// Store a pointer to the calling solution.
gsln=Gsln;
mem1=GMEM1;
mem2=GMEM2;
x_click=0;
y_click=0;
begin();
// Put a simple menu, for saving or closing the window.
Fl_Menu_Bar* menu = new Fl_Menu_Bar(0,0,w,25,"MENU");
Fl_Menu_Item items[]= {
{"&File",0,0,0,FL_SUBMENU},
{"Save as..",0,0,0,FL_SUBMENU | FL_MENU_INACTIVE},
{"PNG (.png)",0,(Fl_Callback*)cb_nothing,this,0},
{"JPEG (.jpg)",0,(Fl_Callback*)cb_nothing,this,0},
{"Bitmap (.bmp)",0,(Fl_Callback*)cb_nothing,this,0},
{"Adobe PDF (.pdf)",0,(Fl_Callback*)cb_nothing,this,0}<