379 lines
13 KiB
C#
379 lines
13 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using System.Windows;
|
|||
|
using System.Windows.Controls;
|
|||
|
using System.Windows.Data;
|
|||
|
using System.Windows.Documents;
|
|||
|
using System.Windows.Input;
|
|||
|
using System.Windows.Media;
|
|||
|
using System.Windows.Media.Imaging;
|
|||
|
using System.Windows.Navigation;
|
|||
|
using System.Windows.Shapes;
|
|||
|
|
|||
|
namespace Calculator
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// Interaction logic for MainWindow.xaml
|
|||
|
/// </summary>
|
|||
|
public partial class MainWindow : Window
|
|||
|
{
|
|||
|
enum Operator
|
|||
|
{
|
|||
|
None, Sum, Subtraction, Multiplication, Division, Mod, Logn, Pown, NRoot, Combinations, Arrangements
|
|||
|
};
|
|||
|
|
|||
|
enum Stages
|
|||
|
{
|
|||
|
First, FirstDisplay, Second
|
|||
|
};
|
|||
|
|
|||
|
#region Variables
|
|||
|
double memory = 0;
|
|||
|
bool is2ndOn = false, error = false;
|
|||
|
double first = 0, second = 0;
|
|||
|
Stages stage = Stages.First;
|
|||
|
Operator oper = Operator.None;
|
|||
|
|
|||
|
Brush IndicatorColor = (Brushes.Orange);
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Properties
|
|||
|
public bool Is2ndOn
|
|||
|
{
|
|||
|
get { return is2ndOn; }
|
|||
|
set
|
|||
|
{
|
|||
|
is2ndOn = value;
|
|||
|
Indicator2ndf.Background = (value) ? (IndicatorColor) : (Brushes.Transparent);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public bool Error
|
|||
|
{
|
|||
|
get { return error; }
|
|||
|
set
|
|||
|
{
|
|||
|
error = value;
|
|||
|
IndicatorError.Background = (value) ? (IndicatorColor) : (Brushes.Transparent);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public double DisplayValue
|
|||
|
{
|
|||
|
set { Display.Text = value.ToString(); }
|
|||
|
get
|
|||
|
{
|
|||
|
double val;
|
|||
|
string temp = Display.Text;
|
|||
|
|
|||
|
if (temp.EndsWith(".") || temp.Length == 0) temp += '0';
|
|||
|
if (!Double.TryParse(temp, out val))
|
|||
|
{
|
|||
|
Error = true;
|
|||
|
val = 0;
|
|||
|
}
|
|||
|
return val;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public string DisplayText
|
|||
|
{
|
|||
|
get { return Display.Text; }
|
|||
|
set { Display.Text = value; }
|
|||
|
}
|
|||
|
|
|||
|
public double Memory
|
|||
|
{
|
|||
|
get { return memory; }
|
|||
|
set
|
|||
|
{
|
|||
|
memory = value;
|
|||
|
IndicatorMem.Background = (value != 0) ? (IndicatorColor) : (Brushes.Transparent);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Calculator logics
|
|||
|
public MainWindow()
|
|||
|
{
|
|||
|
InitializeComponent();
|
|||
|
}
|
|||
|
|
|||
|
void BinaryOperatorPressed(bool isEqual = false)
|
|||
|
{
|
|||
|
if (stage == Stages.First)
|
|||
|
{
|
|||
|
first = DisplayValue; stage = Stages.FirstDisplay;
|
|||
|
}
|
|||
|
|
|||
|
else if (stage == Stages.Second)
|
|||
|
{
|
|||
|
second = DisplayValue;
|
|||
|
DisplayValue = Calculate();
|
|||
|
|
|||
|
if (isEqual) stage = Stages.First;
|
|||
|
else
|
|||
|
{
|
|||
|
first = DisplayValue;
|
|||
|
stage = Stages.FirstDisplay;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
double Calculate()
|
|||
|
{
|
|||
|
switch (oper)
|
|||
|
{
|
|||
|
case Operator.Sum: return first + second;
|
|||
|
case Operator.Subtraction: return first - second;
|
|||
|
case Operator.Multiplication: return first * second;
|
|||
|
case Operator.Division: return first / second;
|
|||
|
case Operator.Mod: return first % second;
|
|||
|
case Operator.Logn: return Math.Log(first, second);
|
|||
|
case Operator.Pown: return Math.Pow(first, second);
|
|||
|
case Operator.NRoot: return Math.Pow(first, 1.0 / second);
|
|||
|
case Operator.Combinations: return MathHelper.Combinations(first, second);
|
|||
|
case Operator.Arrangements: return MathHelper.Arrangements(first, second);
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
void AddDigit(char digit)
|
|||
|
{
|
|||
|
if (stage == Stages.FirstDisplay) { DisplayText = ""; stage = Stages.Second; }
|
|||
|
DisplayText += digit;
|
|||
|
}
|
|||
|
|
|||
|
void SetValue(double value)
|
|||
|
{
|
|||
|
if (stage == Stages.FirstDisplay) stage = Stages.Second;
|
|||
|
DisplayValue = value;
|
|||
|
}
|
|||
|
|
|||
|
private void Handle_Click(object sender, bool is2nd)
|
|||
|
{
|
|||
|
var s = sender as Button;
|
|||
|
if (s == null) return;
|
|||
|
|
|||
|
is2nd = is2nd || Is2ndOn;
|
|||
|
if (s.Name != "B2ndf") Is2ndOn = false;
|
|||
|
double val = DisplayValue;
|
|||
|
|
|||
|
if (DisplayText == "0") DisplayText = "";
|
|||
|
|
|||
|
switch (s.Name)
|
|||
|
{
|
|||
|
// Column 1
|
|||
|
case "B2ndf": Is2ndOn = !Is2ndOn; break;
|
|||
|
case "BInt":
|
|||
|
if (!is2nd) SetValue(Math.Floor(val));
|
|||
|
else SetValue(val - Math.Floor(val));
|
|||
|
break;
|
|||
|
case "BSin":
|
|||
|
if (!is2nd) SetValue(Math.Sin(val));
|
|||
|
else SetValue(Math.Asin(val));
|
|||
|
break;
|
|||
|
case "BSinh":
|
|||
|
if (!is2nd) SetValue(Math.Sinh(val));
|
|||
|
else SetValue(Math.Log(val + Math.Sqrt(val * val + 1)));
|
|||
|
break;
|
|||
|
case "BPi":
|
|||
|
if (!is2nd) SetValue(Math.PI);
|
|||
|
else SetValue(2 * Math.PI);
|
|||
|
break;
|
|||
|
|
|||
|
// Column 2
|
|||
|
case "BLn":
|
|||
|
if (!is2nd) SetValue(Math.Log(val));
|
|||
|
else SetValue(Math.Exp(val));
|
|||
|
break;
|
|||
|
case "BAbs":
|
|||
|
if (!is2nd) SetValue(Math.Abs(val));
|
|||
|
else SetValue(-Math.Abs(val));
|
|||
|
break;
|
|||
|
case "BCos":
|
|||
|
if (!is2nd) SetValue(Math.Cos(val));
|
|||
|
else SetValue(Math.Acos(val));
|
|||
|
break;
|
|||
|
case "BCosh":
|
|||
|
if (!is2nd) SetValue(Math.Cosh(val));
|
|||
|
else SetValue(Math.Log(val + Math.Sqrt(val * val - 1)));
|
|||
|
break;
|
|||
|
case "BE": SetValue(Math.E); break;
|
|||
|
|
|||
|
// Column 3
|
|||
|
case "BLog":
|
|||
|
if (!is2nd) SetValue(Math.Log10(val));
|
|||
|
else SetValue(Math.Pow(10, val));
|
|||
|
break;
|
|||
|
case "BInverse": SetValue(1 / val);
|
|||
|
break;
|
|||
|
case "BTan":
|
|||
|
if (!is2nd) SetValue(Math.Tan(val));
|
|||
|
else SetValue(Math.Atan(val));
|
|||
|
break;
|
|||
|
case "BTanh":
|
|||
|
if (!is2nd) SetValue(Math.Tanh(val));
|
|||
|
else SetValue(Math.Log((1+val) * (1-val))/2);
|
|||
|
break;
|
|||
|
case "BCombinations":
|
|||
|
if (!is2nd) oper = Operator.Combinations;
|
|||
|
else oper = Operator.Arrangements;
|
|||
|
BinaryOperatorPressed();
|
|||
|
break;
|
|||
|
|
|||
|
// Column 4
|
|||
|
case "BLogn":
|
|||
|
oper = Operator.Logn;
|
|||
|
BinaryOperatorPressed();
|
|||
|
break;
|
|||
|
case "BPown":
|
|||
|
if (!is2nd) oper = Operator.Pown;
|
|||
|
else oper = Operator.NRoot;
|
|||
|
BinaryOperatorPressed();
|
|||
|
break;
|
|||
|
case "BSquare":
|
|||
|
if (!is2nd) SetValue(val * val);
|
|||
|
else SetValue(Math.Pow(val, 1.0 / 2.0));
|
|||
|
break;
|
|||
|
case "BCube":
|
|||
|
if (!is2nd) SetValue(val * val * val);
|
|||
|
else SetValue(Math.Pow(val, 1.0 / 3.0));
|
|||
|
break;
|
|||
|
case "BFact":
|
|||
|
SetValue(MathHelper.Factorial(val));
|
|||
|
break;
|
|||
|
|
|||
|
// Memory operations
|
|||
|
case "BMemAdd": Memory += val; break;
|
|||
|
case "BMemSub": Memory -= val; break;
|
|||
|
case "BMemClear": Memory = 0; break;
|
|||
|
case "BMemSet": Memory = val; break;
|
|||
|
case "BMemRecall": SetValue(Memory); break;
|
|||
|
|
|||
|
// Numbers
|
|||
|
case "BNum7": AddDigit('7'); break;
|
|||
|
case "BNum4": AddDigit('4'); break;
|
|||
|
case "BNum1": AddDigit('1'); break;
|
|||
|
case "BNum0": AddDigit('0'); break;
|
|||
|
|
|||
|
// Numbers
|
|||
|
case "BNum8": AddDigit('8'); break;
|
|||
|
case "BNum5": AddDigit('5'); break;
|
|||
|
case "BNum2": AddDigit('2'); break;
|
|||
|
|
|||
|
// Numbers
|
|||
|
case "BBackspace": if (DisplayText.Length >= 1) DisplayText = DisplayText.Substring(0, DisplayText.Length - 1); break;
|
|||
|
case "BNum9": AddDigit('9'); break;
|
|||
|
case "BNum6": AddDigit('6'); break;
|
|||
|
case "BNum3": AddDigit('3'); break;
|
|||
|
case "BPeriod": if (!DisplayText.Contains('.')) AddDigit('.'); break;
|
|||
|
|
|||
|
// Ops
|
|||
|
case "BClear": SetValue(0); break;
|
|||
|
case "BOpDivide": oper = Operator.Division; BinaryOperatorPressed(); break;
|
|||
|
case "BOpMultiply": oper = Operator.Multiplication; BinaryOperatorPressed(); break;
|
|||
|
case "BOpSub": oper = Operator.Subtraction; BinaryOperatorPressed(); break;
|
|||
|
case "BOpAdd": oper = Operator.Sum; BinaryOperatorPressed(); break;
|
|||
|
|
|||
|
// Ops
|
|||
|
case "BClearAC": stage = Stages.First; oper = Operator.None; DisplayValue = 0; break;
|
|||
|
case "BOpMod": oper = Operator.Mod; BinaryOperatorPressed(); break;
|
|||
|
case "BOpSign": SetValue(val * -1); break;
|
|||
|
case "BEqual":
|
|||
|
if (stage == Stages.Second) BinaryOperatorPressed(true);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
Error = (DisplayText == "NaN");
|
|||
|
if (DisplayText == "") DisplayText = "0";
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region User input
|
|||
|
private void Button_Click(object sender, RoutedEventArgs e)
|
|||
|
{
|
|||
|
Handle_Click(sender, false);
|
|||
|
}
|
|||
|
|
|||
|
private void Button_MouseUp(object sender, MouseButtonEventArgs e)
|
|||
|
{
|
|||
|
if (e.ChangedButton == MouseButton.Left) Handle_Click(sender, false);
|
|||
|
else if (e.ChangedButton == MouseButton.Right) Handle_Click(sender, true);
|
|||
|
}
|
|||
|
|
|||
|
private void Window_KeyDown(object sender, KeyEventArgs e)
|
|||
|
{
|
|||
|
e.Handled = true;
|
|||
|
|
|||
|
if (Keyboard.Modifiers == ModifierKeys.Shift) switch (e.Key)
|
|||
|
{
|
|||
|
case Key.D6: Handle_Click(BPown, false); break;
|
|||
|
case Key.D8: Handle_Click(BOpMultiply, false); break;
|
|||
|
case Key.D5: Handle_Click(BOpMod, false); break;
|
|||
|
}
|
|||
|
|
|||
|
if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.Q)
|
|||
|
this.Close();
|
|||
|
|
|||
|
else if (Keyboard.Modifiers == ModifierKeys.None) switch (e.Key)
|
|||
|
{
|
|||
|
// Numeric keys
|
|||
|
case Key.D0:
|
|||
|
case Key.NumPad0: Handle_Click(BNum0, false); break;
|
|||
|
case Key.D1:
|
|||
|
case Key.NumPad1: Handle_Click(BNum1, false); break;
|
|||
|
case Key.D2:
|
|||
|
case Key.NumPad2: Handle_Click(BNum2, false); break;
|
|||
|
case Key.D3:
|
|||
|
case Key.NumPad3: Handle_Click(BNum3, false); break;
|
|||
|
case Key.D4:
|
|||
|
case Key.NumPad4: Handle_Click(BNum4, false); break;
|
|||
|
case Key.D5:
|
|||
|
case Key.NumPad5: Handle_Click(BNum5, false); break;
|
|||
|
case Key.D6:
|
|||
|
case Key.NumPad6: Handle_Click(BNum6, false); break;
|
|||
|
case Key.D7:
|
|||
|
case Key.NumPad7: Handle_Click(BNum7, false); break;
|
|||
|
case Key.D8:
|
|||
|
case Key.NumPad8: Handle_Click(BNum8, false); break;
|
|||
|
case Key.D9:
|
|||
|
case Key.NumPad9: Handle_Click(BNum9, false); break;
|
|||
|
case Key.OemPeriod:
|
|||
|
case Key.Decimal: Handle_Click(BPeriod, false); break;
|
|||
|
|
|||
|
// Binary Operators
|
|||
|
case Key.Add:
|
|||
|
case Key.OemPlus: Handle_Click(BOpAdd, false); break;
|
|||
|
|
|||
|
case Key.Subtract:
|
|||
|
case Key.OemMinus: Handle_Click(BOpSub, false); break;
|
|||
|
|
|||
|
case Key.Multiply: Handle_Click(BOpMultiply, false); break;
|
|||
|
|
|||
|
case Key.OemBackslash:
|
|||
|
case Key.Divide: Handle_Click(BOpDivide, false); break;
|
|||
|
|
|||
|
// Others
|
|||
|
case Key.Return: Handle_Click(BEqual, false); break;
|
|||
|
case Key.Escape: Handle_Click(BClearAC, false); break;
|
|||
|
case Key.Back: Handle_Click(BBackspace, false); break;
|
|||
|
case Key.Delete: Handle_Click(BClear, false); break;
|
|||
|
case Key.F1: BHelp_Click(this, new RoutedEventArgs()); break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void BHelp_Click(object sender, RoutedEventArgs e)
|
|||
|
{
|
|||
|
DynamicLink.Launcher.StartModule("Help", "Calculator");
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
}
|
|||
|
}
|