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 { /// /// Interaction logic for MainWindow.xaml /// 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 } }