@ -1,29 +1,32 @@
@@ -1,29 +1,32 @@
# include "blib/src/ballistics.h"
# include "InputWindow.h"
InputWindow : : InputWindow ( int w , int h , const char * title ) : Fl_Window ( w , h , title ) {
// Solution pointers. Right now we only use gsln as the general solution pointer.
// Solution pointers. Must be initialized to NULL so we don't accidentally try to free them later.
gsln = NULL ;
mem1 = NULL ;
mem2 = 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 ;
// 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 ;
// *** To be removed at next build useSolution=1;
// Start drawing the widgets on screen.
begin ( ) ;
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 ) ;
GBox - > align ( FL_ALIGN_LEFT | FL_ALIGN_TOP | FL_ALIGN_INSIDE ) ;
// Create and place the Drag Function inputs on the form.
inG1 = new Fl_Round_Button ( 270 , 105 , 30 , 15 , " G1 " ) ;
inG2 = new Fl_Round_Button ( 270 , 125 , 30 , 15 , " G2 " ) ;
@ -31,18 +34,18 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
@@ -31,18 +34,18 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
inG6 = new Fl_Round_Button ( 330 , 105 , 30 , 15 , " G6 " ) ;
inG7 = new Fl_Round_Button ( 330 , 125 , 30 , 15 , " G7 " ) ;
inG8 = new Fl_Round_Button ( 330 , 145 , 30 , 15 , " G8 " ) ;
inG1 - > type ( FL_RADIO_BUTTON ) ;
inG2 - > type ( FL_RADIO_BUTTON ) ;
inG5 - > type ( FL_RADIO_BUTTON ) ;
inG6 - > type ( FL_RADIO_BUTTON ) ;
inG7 - > type ( FL_RADIO_BUTTON ) ;
inG8 - > type ( FL_RADIO_BUTTON ) ;
inG1 - > set ( ) ;
// Create and place the input fields on the form.
inName = new Fl_Input ( 55 , 45 , 335 , 20 , " Name " ) ;
inBC = new Fl_Float_Input ( 10 , 80 , 50 , 20 , " Drag Coefficient " ) ;
@ -127,13 +130,7 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
@@ -127,13 +130,7 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
Fl_Menu_Item mc_New = { " &New... " , 0 , ( Fl_Callback * ) cb_mNew , this } ;
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_Analyze = { " &Analyze " , 0 , 0 , 0 , FL_SUBMENU } ;
Fl_Menu_Item mc_Table = { " &Range Table " , 0 , ( Fl_Callback * ) cb_RangeTable , this } ;
@ -143,19 +140,14 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
@@ -143,19 +140,14 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
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 m_Solution = { " &Analysis " , 0 , 0 , 0 , FL_SUBMENU } ;
//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 = { " &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_PBR , this } ;
Fl_Menu_Item mc_CalcBC = { " &Calculate Drag Coefficient " , 0 , ( Fl_Callback * ) cb_Nothing } ;
@ -163,9 +155,6 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
@@ -163,9 +155,6 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
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.
@ -176,17 +165,11 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
@@ -176,17 +165,11 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
// These are planned features, but haven't been done yet.
////// 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_RangeCard . deactivate ( ) ;
mc_ClickChart . deactivate ( ) ;
//mc_RangeTable.deactivate();
//mc_Table.deactivate();
mc_CalcBC . deactivate ( ) ;
//mc_OptimizePBR.deactivate();
//mc_Plot.deactivate();
m_Solution . deactivate ( ) ;
m_Compare . deactivate ( ) ;
@ -197,19 +180,12 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
@@ -197,19 +180,12 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
mc_Save ,
mc_Quit ,
{ 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 } , // 12
m_Tools ,
mc_OptimizePBR ,
@ -218,24 +194,20 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
@@ -218,24 +194,20 @@ InputWindow::InputWindow(int w, int h, const char* title):Fl_Window(w,h,title){
m_Compare , //17
mc_Store1 , //18
mc_Store2 , //19
//mc_Store3,
//mc_Store4,
//mc_Store5,
{ 0 } ,
m_Help , //26
mc_Help ,
mc_License ,
mc_About ,
mc_Bug ,
{ 0 } , //31
{ 0 }
} ;
menu - > copy ( menuitems ) ;
end ( ) ;
show ( ) ;
{ 0 }
} ;
menu - > copy ( menuitems ) ;
end ( ) ;
show ( ) ;
}
@ -272,6 +244,31 @@ InputWindow::~InputWindow(){
@@ -272,6 +244,31 @@ InputWindow::~InputWindow(){
Solution = NULL ;
}
delete inG1 ;
delete inG2 ;
delete inG5 ;
delete inG6 ;
delete inG7 ;
delete inG8 ;
delete inName ;
delete inBC ;
delete inWeight ;
delete inMV ;
delete inZero ;
delete inSH ;
delete inAngle ;
delete inVwind ;
delete inAwind ;
delete ckWeather ;
delete inAltitude ;
delete inTemp ;
delete inPressure ;
delete inHumidity ;
delete oStatus ;
delete btSolve ;
delete btReset ;
}
void InputWindow : : cb_ckWeather ( Fl_Widget * o , void * v ) {
InputWindow * T = ( InputWindow * ) v ;
@ -298,12 +295,12 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
@@ -298,12 +295,12 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
// 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 ;
GBCSolution * lsln = NULL ;
double * lSolution = NULL ;
double bc = - 1 ; // The ballistic coefficient for the projectile.
double v = - 1 ; // Intial velocity, in ft/s
double sh = - 1 ; // The Sight height over bore, in inches.
@ -314,9 +311,9 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
@@ -314,9 +311,9 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
int df = 0 ;
int numRows = 0 ;
char txt1 [ 1024 ] ;
double zeroangle = - 1 ; // The bore / sight angle.
bc = atof ( T - > inBC - > value ( ) ) ;
v = atof ( T - > inMV - > value ( ) ) ;
sh = atof ( T - > inSH - > value ( ) ) ;
@ -324,32 +321,32 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
@@ -324,32 +321,32 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
zero = atof ( T - > inZero - > value ( ) ) ;
windspeed = atof ( T - > inVwind - > value ( ) ) ;
windangle = atof ( T - > inAwind - > value ( ) ) ;
if ( T - > inG1 - > value ( ) = = 1 ) df = G1 ;
else if ( T - > inG2 - > value ( ) = = 1 ) df = G2 ;
else if ( T - > inG5 - > value ( ) = = 1 ) df = G5 ;
else if ( T - > inG6 - > value ( ) = = 1 ) df = G6 ;
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 ( ) ) ;
double Barometer = atof ( T - > inPressure - > value ( ) ) ;
double Temperature = atof ( T - > inTemp - > value ( ) ) ;
double RH = atof ( T - > inHumidity - > value ( ) ) / 100 ;
bc = AtmCorrect ( bc , Altitude , Barometer , Temperature , RH ) ;
}
}
// Find the zero angle of the bore relative to the sighting system.
zeroangle = ZeroAngle ( df , bc , v , sh , zero , 0 ) ;
// 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.
@ -371,8 +368,9 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
@@ -371,8 +368,9 @@ 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 ] ,
T - > ckWeather - > value ( )
( int ) lSolution [ 10 * __BCOMP_MAXRANGE__ + 1 ] ,
T - > ckWeather - > value ( ) ,
df
) ;
// Update the maximum valid range of the solution.
@ -394,23 +392,22 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* vd) {
@@ -394,23 +392,22 @@ void InputWindow::cb_Solve(Fl_Widget* o, void* 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 ) ;
if ( T - > gsln ! = NULL ) {
//if (T->gsln->sln != NULL) printf("398: T->gsln->sln = %p",T->gsln->sln); //free(T->gsln->sln);
delete ( T - > gsln ) ;
}
T - > gsln = lsln ;
}
return ;
}
}
T - > gsln = lsln ;
}
return ;
}
void InputWindow : : EnableMenu ( void * v ) {
InputWindow * T = ( InputWindow * ) v ;
@ -461,7 +458,7 @@ void InputWindow::cb_Quit(Fl_Widget*, void* v) {
@@ -461,7 +458,7 @@ void InputWindow::cb_Quit(Fl_Widget*, void* v) {
void InputWindow : : cb_Clear ( Fl_Widget * o , void * 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 ) ;
@ -481,6 +478,14 @@ void InputWindow::cb_Clear(Fl_Widget* o, void* v) {
@@ -481,6 +478,14 @@ void InputWindow::cb_Clear(Fl_Widget* o, void* v) {
T - > ckWeather - > clear ( ) ;
T - > cb_ckWeather ( o , v ) ;
T - > oStatus - > value ( " GNU Ballistic Computer: Solution Reset " ) ;
T - > inG1 - > value ( 1 ) ;
T - > inG2 - > value ( 0 ) ;
T - > inG5 - > value ( 0 ) ;
T - > inG6 - > value ( 0 ) ;
T - > inG7 - > value ( 0 ) ;
T - > inG8 - > value ( 0 ) ;
// Free up any memory we have been using.
if ( T - > Solution ! = NULL ) {
@ -489,11 +494,16 @@ void InputWindow::cb_Clear(Fl_Widget* o, void* v) {
@@ -489,11 +494,16 @@ void InputWindow::cb_Clear(Fl_Widget* o, void* v) {
}
if ( T - > gsln ! = NULL ) {
if ( T - > gsln - > sln ! = NULL ) free ( T - > gsln - > sln ) ;
if ( T - > gsln - > sln ! = NULL ) {
free ( T - > gsln - > sln ) ;
T - > gsln - > sln = NULL ;
}
T - > gsln - > ~ GBCSolution ( ) ;
delete ( T - > gsln ) ;
T - > gsln = NULL ;
}
delete ( T - > gsln ) ;
T - > gsln = NULL ;
}
if ( T - > mem1 ! = NULL ) {
if ( T - > mem1 - > sln ! = NULL ) free ( T - > mem1 - > sln ) ;
@ -660,58 +670,72 @@ void InputWindow::cb_Save(Fl_Widget*, void*v){
@@ -660,58 +670,72 @@ void InputWindow::cb_Save(Fl_Widget*, void*v){
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.
// 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 ) ;
if ( lsln ! = NULL ) {
free ( lsln ) ;
lsln = NULL ;
}
// Assign some new memory for lsln.
lsln = ( GBCSolution * ) malloc ( sizeof ( GBCSolution ) ) ;
if ( lsln = = NULL ) {
if ( lsln = = NULL ) {
T - > oStatus - > value ( " GNU Ballistic Computer: Memory allocation error. " ) ;
return ;
}
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 ) ;
fclose ( ofile ) ;
if ( read ! = sizeof ( GBCSolution ) ) {
T - > oStatus - > value ( " GNU Ballistic Computer: Error reading file data! \n Please ensure the file is a valid GNUBC solution. " ) ;
if ( lsln ! = NULL ) free ( lsln ) ;
if ( T - > gsln ! = NULL ) free ( T - > gsln ) ;
return ;
}
if ( lsln ! = NULL ) {
free ( lsln ) ;
lsln = NULL ;
}
if ( T - > gsln ! = NULL ) {
free ( T - > gsln ) ;
T - > gsln = NULL ;
}
return ;
}
// Set the parent's solution pointer to the local one we just imported.
T - > gsln = lsln ;
T - > gsln = lsln ;
// Load the solution data into the INPUT fields in the InputWindow.
char buff [ 1024 ] ;
T - > inName - > value ( lsln - > Name ( ) ) ;
@ -730,20 +754,37 @@ void InputWindow::cb_Open(Fl_Widget* o, void*v){
@@ -730,20 +754,37 @@ void InputWindow::cb_Open(Fl_Widget* o, void*v){
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 ;
}
T - > inG1 - > value ( 0 ) ;
T - > inG2 - > value ( 0 ) ;
T - > inG5 - > value ( 0 ) ;
T - > inG6 - > value ( 0 ) ;
T - > inG7 - > value ( 0 ) ;
T - > inG8 - > value ( 0 ) ;
if ( lsln - > df = = G1 ) T - > inG1 - > set ( ) ;
if ( lsln - > df = = G2 ) T - > inG2 - > set ( ) ;
if ( lsln - > df = = G5 ) T - > inG5 - > set ( ) ;
if ( lsln - > df = = G6 ) T - > inG6 - > set ( ) ;
if ( lsln - > df = = G7 ) T - > inG7 - > set ( ) ;
if ( lsln - > df = = G8 ) T - > inG8 - > set ( ) ;
// We don't actually have a valid solution, so make sure to set the solution
// double* pointer to NULL before we call solve.
T - > gsln - > sln = NULL ;
// 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 ;
@ -788,10 +829,10 @@ void InputWindow::cb_Store2(Fl_Widget* o, void* v){
@@ -788,10 +829,10 @@ void InputWindow::cb_Store2(Fl_Widget* o, void* v){
if ( T - > mem2 ! = NULL ) {
if ( T - > mem2 - > sln ! = NULL ) free ( T - > mem2 - > sln ) ;
delete ( T - > mem1 ) ;
delete ( T - > mem2 ) ;
}
if ( T - > Smem2 ! = NULL ) free ( T - > Smem1 ) ;
if ( T - > Smem2 ! = NULL ) free ( T - > Smem2 ) ;
T - > mem2 = T - > gsln ;
T - > Smem2 = T - > Solution ;