2026-01-26 18:56:53 +09:00

416 lines
12 KiB
C#

using Aurora;
using Aurora.View;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
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 AuroraUIComponent.UserControls.Dialog
{
/// <summary>
/// WinCalculator.xaml에 대한 상호 작용 논리
/// </summary>
public partial class WinCalculator : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<S>(
ref S storage,
S value,
[CallerMemberName] string propertyName = null)
{
if (Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged(
[CallerMemberName] string propertyName = null)
=> PropertyChanged?.Invoke(
this,
new PropertyChangedEventArgs(propertyName)
);
public string Unit { get => _Unit; set => SetProperty(ref _Unit, value); }
public string _Unit;
public string Value {
get => _Value;
set {
SetProperty(ref _Value, value);
if (value != "") {
TextDisplay = value;
}
}
}
public string _Value;
public string TextDisplay { get => _TextDisplay; set => SetProperty(ref _TextDisplay, value); }
public string _TextDisplay;
public string TextHistory { get => _TextHistory; set => SetProperty(ref _TextHistory, value); }
public string _TextHistory;
public string TextRange {
get => _TextRange;
set => SetProperty(ref _TextRange, value);
}
public string _TextRange;
public string Op { get; set; }
public double? Op1 { get; set; }
public double Number;
private bool IsFirst = true;
private bool IsCalculated = false;
public int DecimalPlaces {
set {
SetProperty(ref _DecimalPlaces, value);
if (value > 0) {
ButtonPoint.IsEnabled = true;
} else {
ButtonPoint.IsEnabled = false;
}
}
get => _DecimalPlaces;
}
public int _DecimalPlaces;
public bool IsAllowMinus {
set {
ButtonMinus.IsEnabled = value;
if (value) {
ButtonMinus.Visibility = Visibility.Visible;
Grid.SetColumn(Button0, 1);
Grid.SetColumnSpan(Button0, 1);
} else {
ButtonMinus.Visibility = Visibility.Collapsed;
Grid.SetColumn(Button0, 0);
Grid.SetColumnSpan(Button0, 2);
}
}
}
private bool _IsClosing = false;
private Window _OnwerWindow;
private FrameworkElement _Element;
public Action<string> ResultCallback;
public WinCalculator()
{
InitializeComponent();
Deactivated += WindowDeactivated;
DataContext = this;
}
private void WindowDeactivated(object sender, EventArgs e)
{
if (_IsClosing) {
return;
}
Close();
}
private void NumberButton_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
var numStr = button.Content.ToString();
if (Op1 == null) TextHistory = "";
if (IsCalculated) {
Value = "0";
IsCalculated = false;
}
if (Value == "0") {
if (numStr == "0") {
return;
}
Value = numStr;
IsFirst = false;
return;
}
if (Value.StartsWith("-")) {
if (Value.Length > 1) {
if (Value.Substring(1) == "0") {
if (numStr == "0") {
return;
}
Value = "-" + numStr;
IsFirst = false;
return;
}
}
}
if (IsFirst) {
Value = string.Empty;
IsFirst = false;
}
AddChracter(numStr);
}
private void ButtonMinus_Click(object sender, RoutedEventArgs e)
{
if (IsCalculated) {
IsCalculated = false;
}
if (Value.StartsWith("-"))
Value = Value.Substring(1, Value.Length - 1);
else
Value = "-" + Value;
IsFirst = false;
}
private void ButtonPoint_Click(object sender, RoutedEventArgs e)
{
if (IsCalculated) {
Value = "0";
IsCalculated = false;
}
if (Value.Contains(".")) {
return;
}
if (IsFirst) {
IsFirst = false;
}
if (Value.Length == 0) AddChracter("0");
AddChracter(".");
}
private void OperatorButton_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
string op = button.Content.ToString();
if (Value.Length == 0) { // Change Operator
if (Op == TextHistory.Substring(TextHistory.Length - 1)) {
Op = op;
TextHistory = TextHistory.Substring(0, TextHistory.Length - 1) + op;
}
return;
}
double input;
if (double.TryParse(Value, out input)) {
if (Op1 == null) {
TextHistory = "";
Op1 = input;
} else {
Op1 = calculate(Op, (double)Op1, input);
TextDisplay = Op1.ToString();
}
Op = op;
Value = "";
if (input >= 0) {
TextHistory += input.ToString() + Op;
} else {
TextHistory += "(" + input.ToString() + ")" + Op;
}
}
}
private void CalculateButton_Click(object sender, RoutedEventArgs e)
{
double input;
if (Op1 == null || !double.TryParse(Value, out input)) {
return;
}
Value = calculate(Op, (double)Op1, input).ToString();
Op1 = null;
if (input >= 0) {
TextHistory += input.ToString();
} else {
TextHistory += "(" + input.ToString() + ")";
}
IsCalculated = true;
}
private double calculate(string op, double op1, double op2)
{
switch (op) {
case "+": return op1 + op2;
case "-": return op1 - op2;
case "*": return Math.Round(op1 * op2, DecimalPlaces);
case "/": return Math.Round(op1 / op2, DecimalPlaces);
}
return 0;
}
private void ButtonBack_Click(object sender, RoutedEventArgs e)
{
if (IsFirst) {
IsFirst = false;
}
if (!string.IsNullOrEmpty(Value)) {
Value = Value.Substring(0, Value.Length - 1);
}
if (string.IsNullOrEmpty(Value)) {
Value = "0";
return;
}
}
private void ButtonClear_Click(object sender, RoutedEventArgs e)
{
Value = "0";
Op1 = null;
TextHistory = "";
if (IsFirst) {
IsFirst = false;
}
}
private void ButtonOK_Click(object sender, RoutedEventArgs e)
{
if (TextDisplay.Last() == '.') {
TextDisplay = TextDisplay.Substring(0, TextDisplay.Length - 1);
}
if (!double.TryParse(TextDisplay, out Number)) {
return;
}
if (ResultCallback != null)
ResultCallback(TextDisplay);
_IsClosing = true;
Close();
}
private void AddChracter(string text)
{
Value = Value + text;
}
private void ButtonCancel_Click(object sender, RoutedEventArgs e)
{
_IsClosing = true;
Close();
}
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
SetWindowControl(_OnwerWindow, _Element);
}
internal void SetControl(FrameworkElement element)
{
Window main = Application.Current.MainWindow;
SetControl(main, element);
}
public void SetWindowControl(Window window, FrameworkElement element)
{
SetControl(window, element);
}
private void SetControl(Window window, FrameworkElement element)
{
_OnwerWindow = window;
_Element = element;
Window main = Application.Current.MainWindow;
Point mainPosition = main.PointToScreen(new Point(0d, 0d));
Point relativePoint = element.TransformToAncestor(window)
.Transform(new Point(0, 0));
Point position = element.PointToScreen(new Point(0d, 0d)),
controlPosition = window.PointToScreen(new Point(0d, 0d));
// Right
relativePoint.X += controlPosition.X;
relativePoint.Y += controlPosition.Y;
// 1. Right, Middle
Left = relativePoint.X + element.ActualWidth;
Top = relativePoint.Y - 45;
if (Left + this.Width < mainPosition.X + main.Width) {
if (Top + this.Height < mainPosition.Y + main.Height) {
return;
}
}
// 2. MiddleRight, Bottom
Left = Left - this.Width;
Top = relativePoint.Y + element.ActualHeight;
if (Left + this.Width < mainPosition.X + main.Width) {
if (Top + this.Height < mainPosition.Y + main.Height) {
return;
}
// 3. MiddleRight, Top
Top = relativePoint.Y - this.Height;
if (Left + this.Width < mainPosition.X + main.Width) {
if (Top + this.Height < mainPosition.Y + main.Height) {
return;
}
}
}
// 4. Left, Middle
Left = relativePoint.X - this.Width;
Top = relativePoint.Y - 45;
if (Top + this.Height < mainPosition.Y + main.Height) {
if (Left > mainPosition.X) {
return;
}
}
// 3. Middle, Top
Left = relativePoint.X;
Top = relativePoint.Y - this.Height;
// 5. Left, Top
Left = relativePoint.X - this.Width + element.ActualWidth;
}
}
public class VisibleConverter : IValueConverter
{
private Visibility True { get; set; } = Visibility.Visible;
private Visibility False { get; set; } = Visibility.Collapsed;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string str) {
return !string.IsNullOrEmpty(str) ? True : False;
} else {
return False;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}