diff --git a/src/CalcManager/CCalcManager.cpp b/src/CalcManager/CCalcManager.cpp index efdb020d..448495fb 100644 --- a/src/CalcManager/CCalcManager.cpp +++ b/src/CalcManager/CCalcManager.cpp @@ -83,13 +83,13 @@ public: { DBGPRINT("Native:SetExpressionDisplay()\n"); - auto item = std::make_shared(); + auto item = std::make_shared(); item->historyItemVector.expression = L""; item->historyItemVector.result = L""; item->historyItemVector.spCommands = commands; item->historyItemVector.spTokens = tokens; - auto pItem = MarshalHistoryItem(item); + auto pItem = MarshalHistoryItem(item); _params.SetExpressionDisplay(_params.CalculatorState, pItem); } @@ -187,6 +187,21 @@ IExpressionCommand* AsIExpressionCommand(void* pExpressionCommand) return static_cast(pExpressionCommand); } +COpndCommand* AsCOpndCommand(void* pExpressionCommand) +{ + return static_cast(pExpressionCommand); +} + +CUnaryCommand* AsCUnaryCommand(void* pExpressionCommand) +{ + return static_cast(pExpressionCommand); +} + +CBinaryCommand* AsCBinaryCommand(void* pExpressionCommand) +{ + return static_cast(pExpressionCommand); +} + const wchar_t* ToWChar(std::wstring& str) { auto out = new wchar_t[str.size() + 1]{}; @@ -270,7 +285,6 @@ void* MarshalHistoryItems(std::vectorGetHistoryItem(index); - return MarshalHistoryItem(historyItem); + return MarshalHistoryItem(historyItem); +} + +void Free(void* ptr) +{ + free(ptr); } int IExpressionCommand_GetCommandType(void* pExpressionCommand) { return (int)AsIExpressionCommand(pExpressionCommand)->GetCommandType(); } + +void* COpndCommand_GetCommands(void* pExpressionCommand) +{ + auto res = AsCOpndCommand(pExpressionCommand)->GetCommands(); + + auto pRes = (COpndCommand_GetCommandsResult*)malloc(sizeof(COpndCommand_GetCommandsResult)); + + unsigned int commandCount; + res->GetSize(&commandCount); + pRes->CommandCount = commandCount; + + auto pCommands = (int32_t*)malloc(commandCount * sizeof(int32_t)); + pRes->pCommands = pCommands; + + for (unsigned int i = 0; i < commandCount; i++) + { + int value; + res->GetAt(i, &value); + pCommands[i] = (int32_t)value; + } + + return pRes; +} + +void* CUnaryCommand_GetCommands(void* pExpressionCommand) +{ + auto res = AsCUnaryCommand(pExpressionCommand)->GetCommands(); + + auto pRes = (CUnaryCommand_GetCommandsResult*)malloc(sizeof(CUnaryCommand_GetCommandsResult)); + + unsigned int commandCount; + res->GetSize(&commandCount); + pRes->CommandCount = commandCount; + + auto pCommands = (int32_t*)malloc(commandCount * sizeof(int32_t)); + pRes->pCommands = pCommands; + + for (unsigned int i = 0; i < commandCount; i++) + { + int value; + res->GetAt(i, &value); + pCommands[i] = (int32_t)value; + } + + return pRes; +} + +bool COpndCommand_IsNegative(void* pExpressionCommand) +{ + return (int)AsCOpndCommand(pExpressionCommand)->IsNegative(); +} + +int CBinaryCommand_GetCommand(void* pExpressionCommand) +{ + return (int)AsCBinaryCommand(pExpressionCommand)->GetCommand(); +} diff --git a/src/CalcManager/CCalcManager.h b/src/CalcManager/CCalcManager.h index c5b7468a..7af758a3 100644 --- a/src/CalcManager/CCalcManager.h +++ b/src/CalcManager/CCalcManager.h @@ -22,26 +22,27 @@ typedef void (*MemoryItemChangedFunc)(void* state, unsigned int indexOfMemory); typedef const wchar_t* (*GetCEngineStringFunc)(void* state, const wchar_t* id); -struct CalculatorManager_CreateParams { - void* CalculatorState; +struct CalculatorManager_CreateParams +{ + void* CalculatorState; - SetPrimaryDisplayFunc SetPrimaryDisplay; - SetIsInErrorFunc SetIsInError; - SetExpressionDisplayFunc SetExpressionDisplay; - SetParenthesisNumberFunc SetParenthesisNumber; - OnNoRightParenAddedFunc OnNoRightParenAdded; - MaxDigitsReachedFunc MaxDigitsReached; - BinaryOperatorReceivedFunc BinaryOperatorReceived; - OnHistoryItemAddedFunc OnHistoryItemAdded; - SetMemorizedNumbersFunc SetMemorizedNumbers; - MemoryItemChangedFunc MemoryItemChanged; + SetPrimaryDisplayFunc SetPrimaryDisplay; + SetIsInErrorFunc SetIsInError; + SetExpressionDisplayFunc SetExpressionDisplay; + SetParenthesisNumberFunc SetParenthesisNumber; + OnNoRightParenAddedFunc OnNoRightParenAdded; + MaxDigitsReachedFunc MaxDigitsReached; + BinaryOperatorReceivedFunc BinaryOperatorReceived; + OnHistoryItemAddedFunc OnHistoryItemAdded; + SetMemorizedNumbersFunc SetMemorizedNumbers; + MemoryItemChangedFunc MemoryItemChanged; - void* ResourceState; - GetCEngineStringFunc GetCEngineString; + void* ResourceState; + GetCEngineStringFunc GetCEngineString; }; #if defined(__EMSCRIPTEN__) || defined(__APPLE__) -#define DLL_EXPORT +#define DLL_EXPORT #else #define DLL_EXPORT __declspec(dllexport) #endif @@ -49,9 +50,9 @@ struct CalculatorManager_CreateParams { GetHistoryItemResult* MarshalHistoryItem(std::shared_ptr& historyItem); void* MarshalHistoryItems(std::vector>& historyItems); -extern "C" { - - struct GetHistoryItemsResult +extern "C" +{ + struct GetHistoryItemsResult { int32_t ItemsCount; void* HistoryItems; @@ -70,6 +71,18 @@ extern "C" { void** Commands; }; + struct COpndCommand_GetCommandsResult + { + int32_t CommandCount; + int32_t* pCommands; + }; + + struct CUnaryCommand_GetCommandsResult + { + int32_t CommandCount; + int32_t* pCommands; + }; + DLL_EXPORT void* CalculatorManager_Create(CalculatorManager_CreateParams* params); DLL_EXPORT void CalculatorManager_SendCommand(void* manager, int command); DLL_EXPORT void CalculatorManager_SetRadix(void* manager, RADIX_TYPE iRadixType); @@ -98,6 +111,14 @@ extern "C" { DLL_EXPORT void* CalculatorManager_GetHistoryItems(void* manager); DLL_EXPORT void* CalculatorManager_GetHistoryItem(void* manager, int index); - DLL_EXPORT int IExpressionCommand_GetCommandType(void* pExpressionCommand); -} + DLL_EXPORT void Free(void* ptr); + DLL_EXPORT int IExpressionCommand_GetCommandType(void* pExpressionCommand); + + DLL_EXPORT void* COpndCommand_GetCommands(void* pExpressionCommand); + DLL_EXPORT bool COpndCommand_IsNegative(void* pExpressionCommand); + + DLL_EXPORT void* CUnaryCommand_GetCommands(void* pExpressionCommand); + + DLL_EXPORT int CBinaryCommand_GetCommand(void* pExpressionCommand); +} diff --git a/src/Calculator.Shared/CalcManager/CalculatorList.cs b/src/Calculator.Shared/CalcManager/CalculatorList.cs index 5b77304c..4b716548 100644 --- a/src/Calculator.Shared/CalcManager/CalculatorList.cs +++ b/src/Calculator.Shared/CalcManager/CalculatorList.cs @@ -9,12 +9,17 @@ namespace CalculatorApp { List m_vector; - public CalculatorList() - { - m_vector = new List(); - } + public CalculatorList() + { + m_vector = new List(); + } - public CalculatorList(CalculatorList source) + public CalculatorList(IEnumerable source) + { + m_vector = new List(source); + } + + public CalculatorList(CalculatorList source) { m_vector = new List(source.m_vector); } diff --git a/src/Calculator.Shared/CalcManager/CalculatorManager.Interop.cs b/src/Calculator.Shared/CalcManager/CalculatorManager.Interop.cs index 560803de..90de0552 100644 --- a/src/Calculator.Shared/CalcManager/CalculatorManager.Interop.cs +++ b/src/Calculator.Shared/CalcManager/CalculatorManager.Interop.cs @@ -99,15 +99,32 @@ namespace CalculationManager [DllImport(DllPath)] public static extern IntPtr CalculatorManager_GetHistoryItem(IntPtr nativeManager, int uIdx); + [DllImport(DllPath)] + public static extern int CBinaryCommand_GetCommand(IntPtr m_pExpressionCommand); + + [DllImport(DllPath)] + public static extern void Free(IntPtr ptr); + [DllImport(DllPath)] public static extern CommandType IExpressionCommand_GetCommandType(IntPtr pExpressionCommand); + [DllImport(DllPath)] + public static extern bool COpndCommand_IsNegative(IntPtr pExpressionCommand); + + [DllImport(DllPath)] + public static extern IntPtr COpndCommand_GetCommands(IntPtr pExpressionCommand); + + [DllImport(DllPath)] + public static extern IntPtr CUnaryCommand_GetCommands(IntPtr pExpressionCommand); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate IntPtr GetCEngineStringFunc(IntPtr state, IntPtr id); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void BinaryOperatorReceivedFunc(IntPtr state); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void SetPrimaryDisplayCallbackFunc(IntPtr state, IntPtr pDisplayStringValue, bool isError); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void SetIsInErrorCallbackFunc(IntPtr state, bool isError); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] @@ -353,8 +370,8 @@ namespace CalculationManager [StructLayout(LayoutKind.Sequential)] public struct GetHistoryItemResult { - public string expression; - public string result; + public IntPtr expression; + public IntPtr result; public int TokenCount; public IntPtr TokenStrings; @@ -364,6 +381,19 @@ namespace CalculationManager public IntPtr Commands; } + [StructLayout(LayoutKind.Sequential)] + public struct COpndCommand_GetCommandsResult + { + public int CommandCount; + public IntPtr Commands; + } + + [StructLayout(LayoutKind.Sequential)] + public struct CUnaryCommand_GetCommandsResult + { + public int CommandCount; + public IntPtr Commands; + } public partial class CalculatorManager : ICalcDisplay { @@ -371,6 +401,5 @@ namespace CalculationManager private GCHandle _displayCallbackHandle; private GCHandle _resourceProviderHandle; private readonly IntPtr _nativeManager; - } } diff --git a/src/Calculator.Shared/CalcManager/CalculatorManager.cs b/src/Calculator.Shared/CalcManager/CalculatorManager.cs index ce28e75d..cfc919c8 100644 --- a/src/Calculator.Shared/CalcManager/CalculatorManager.cs +++ b/src/Calculator.Shared/CalcManager/CalculatorManager.cs @@ -251,8 +251,8 @@ namespace CalculationManager internal static HISTORYITEM UnmarshalHistoryItemResult(GetHistoryItemResult historyResultItem) { var historyItem = new HISTORYITEM(); - historyItem.historyItemVector.expression = historyResultItem.expression; - historyItem.historyItemVector.result = historyResultItem.result; + historyItem.historyItemVector.expression = NativeDispatch.PtrToString(historyResultItem.expression); + historyItem.historyItemVector.result = NativeDispatch.PtrToString(historyResultItem.result); historyItem.historyItemVector.spTokens = new CalculatorList<(string, int)>(); for (var i = 0; i < historyResultItem.TokenCount; i++) @@ -274,7 +274,7 @@ namespace CalculationManager switch (commandType) { case CommandType.BinaryCommand: - return new CUnaryCommand(pExpressionCommand); + return new CBinaryCommand(pExpressionCommand); case CommandType.OperandCommand: return new COpndCommand(pExpressionCommand); diff --git a/src/Calculator.Shared/CalcManager/ExpressionCommandInterface.cs b/src/Calculator.Shared/CalcManager/ExpressionCommandInterface.cs index 6a9eaae9..c4b6b5d4 100644 --- a/src/Calculator.Shared/CalcManager/ExpressionCommandInterface.cs +++ b/src/Calculator.Shared/CalcManager/ExpressionCommandInterface.cs @@ -3,6 +3,7 @@ using CalculatorApp; using System; +using System.Runtime.InteropServices; namespace CalculationManager { @@ -73,13 +74,27 @@ namespace CalculationManager public class CUnaryCommand : IUnaryCommand { - private IntPtr pExpressionCommand; + private IntPtr m_pExpressionCommand; - public CUnaryCommand(IntPtr pExpressionCommand) => this.pExpressionCommand = pExpressionCommand; + public CUnaryCommand(IntPtr pExpressionCommand) => this.m_pExpressionCommand = pExpressionCommand; public CUnaryCommand(int command) => throw new NotImplementedException(); public CUnaryCommand(int command1, int command2) => throw new NotImplementedException(); - public CalculatorList GetCommands() => throw new NotImplementedException(); + + public CalculatorList GetCommands() + { + var pResult = NativeDispatch.CUnaryCommand_GetCommands(m_pExpressionCommand); + var result = Marshal.PtrToStructure(pResult); + + int[] commandsArray = new int[result.CommandCount]; + Marshal.Copy(result.Commands, commandsArray, 0, commandsArray.Length); + + NativeDispatch.Free(result.Commands); + NativeDispatch.Free(pResult); + + return new CalculatorList(commandsArray); + } + public CalculationManager.CommandType GetCommandType() => CommandType.UnaryCommand; public void SetCommand(int command) => throw new NotImplementedException(); public void SetCommands(int command1, int command2) => throw new NotImplementedException(); @@ -88,32 +103,45 @@ namespace CalculationManager public class CBinaryCommand : IBinaryCommand { - private IntPtr pExpressionCommand; + private IntPtr m_pExpressionCommand; - public CBinaryCommand(IntPtr pExpressionCommand) => this.pExpressionCommand = pExpressionCommand; + public CBinaryCommand(IntPtr pExpressionCommand) => this.m_pExpressionCommand = pExpressionCommand; public CBinaryCommand(int command) => throw new NotImplementedException(); public void SetCommand(int command) => throw new NotImplementedException(); - public int GetCommand() => throw new NotImplementedException(); + public int GetCommand() => NativeDispatch.CBinaryCommand_GetCommand(m_pExpressionCommand); public CalculationManager.CommandType GetCommandType() => CommandType.BinaryCommand; public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException(); } public class COpndCommand : IOpndCommand { - private IntPtr pExpressionCommand; + private IntPtr m_pExpressionCommand; public COpndCommand(CalculatorList commands, bool fNegative, bool fDecimal, bool fSciFmt) => throw new NotImplementedException(); - public COpndCommand(IntPtr pExpressionCommand) => this.pExpressionCommand = pExpressionCommand; + public COpndCommand(IntPtr pExpressionCommand) => this.m_pExpressionCommand = pExpressionCommand; // public void Initialize(CalcEngine.Rational rat) => throw new NotImplementedException(); - public CalculatorList GetCommands() => throw new NotImplementedException(); - public void SetCommands(CalculatorList commands) => throw new NotImplementedException(); + public CalculatorList GetCommands() + { + var pResult = NativeDispatch.COpndCommand_GetCommands(m_pExpressionCommand); + var result = Marshal.PtrToStructure(pResult); + + int[] commandsArray = new int[result.CommandCount]; + Marshal.Copy(result.Commands, commandsArray, 0, commandsArray.Length); + + NativeDispatch.Free(result.Commands); + NativeDispatch.Free(pResult); + + return new CalculatorList(commandsArray); + } + + public void SetCommands(CalculatorList commands) => throw new NotImplementedException(); public void AppendCommand(int command) => throw new NotImplementedException(); public void ToggleSign() => throw new NotImplementedException(); public void RemoveFromEnd() => throw new NotImplementedException(); - public bool IsNegative() => throw new NotImplementedException(); + public bool IsNegative() => NativeDispatch.COpndCommand_IsNegative(m_pExpressionCommand); public bool IsSciFmt() => throw new NotImplementedException(); public bool IsDecimalPresent() => throw new NotImplementedException(); public string GetToken(char decimalSymbol) => throw new NotImplementedException(); diff --git a/src/Calculator.Shared/Common/LocalizationService.cs b/src/Calculator.Shared/Common/LocalizationService.cs index 1577467f..4b2e74e1 100644 --- a/src/Calculator.Shared/Common/LocalizationService.cs +++ b/src/Calculator.Shared/Common/LocalizationService.cs @@ -167,7 +167,7 @@ namespace CalculatorApp.Common } } - public FlowDirection GetFlowDirection() + public FlowDirection GetFlowDirection() { return m_flowDirection; } diff --git a/src/Calculator.Shared/ViewModels/HistoryViewModel.cs b/src/Calculator.Shared/ViewModels/HistoryViewModel.cs index 08694ceb..bef2f5bc 100644 --- a/src/Calculator.Shared/ViewModels/HistoryViewModel.cs +++ b/src/Calculator.Shared/ViewModels/HistoryViewModel.cs @@ -153,12 +153,12 @@ namespace CalculatorApp calculatorDisplay.SetHistoryCallback(new WeakReference(this)); } - void ShowItem(HistoryItemViewModel e) + public void ShowItem(HistoryItemViewModel e) { HistoryItemClicked(e); } - void DeleteItem(HistoryItemViewModel e) + public void DeleteItem(HistoryItemViewModel e) { int itemIndex= Items.IndexOf(e); if (itemIndex != -1) diff --git a/src/Calculator.Shared/Views/HistoryList.xaml b/src/Calculator.Shared/Views/HistoryList.xaml index c2ece1e3..6c3620d3 100644 --- a/src/Calculator.Shared/Views/HistoryList.xaml +++ b/src/Calculator.Shared/Views/HistoryList.xaml @@ -4,217 +4,199 @@ xmlns:automation="using:CalculatorApp.Common.Automation" xmlns:controls="using:CalculatorApp.Controls" xmlns:converters="using:CalculatorApp.Converters" - xmlns:local="using:CalculatorApp.Views" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="using:CalculatorApp" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:model="using:CalculatorApp.ViewModel" xmlns:muxc="using:Microsoft.UI.Xaml.Controls" AutomationProperties.AutomationId="HistoryList" FlowDirection="LeftToRight" - mc:Ignorable=""> - - + mc:Ignorable="d"> + + - + + + + + + + + - - - - + + - - + - - - - - - + + + + - - + - + Grid.Row="1" + Margin="0,-1,0,0" + Padding="0" + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + Background="{ThemeResource SystemControlChromeMediumLowAcrylicElementMediumBrush}" + BorderBrush="{ThemeResource SystemControlForegroundChromeHighBrush}" + BorderThickness="{ThemeResource HighContrastThicknessTop}"/> - - + - - + + - - + x:Uid="HistoryEmpty" + Margin="12,14,24,0" + Style="{ThemeResource BaseTextBlockStyle}" + Foreground="{ThemeResource SystemControlPageTextBaseHighBrush}" + TextWrapping="Wrap" + Visibility="{Binding ItemSize, Converter={StaticResource ItemSizeToVisibilityConverter}}"/> + MinHeight="60" + Padding="0,12,0,0" + HorizontalAlignment="Stretch" + AutomationProperties.AutomationId="HistoryListView" + IsItemClickEnabled="True" + ItemClick="ListView_ItemClick" + ItemContainerStyle="{StaticResource HistoryItemContainerStyle}" + ItemTemplate="{StaticResource HistoryItemTemplate}" + ItemsSource="{x:Bind Model.Items, Mode=OneWay}" + SelectionMode="None" + TabIndex="0" + Visibility="{x:Bind Model.ItemSize, Mode=OneWay, Converter={StaticResource ItemSizeToVisibilityNegationConverter}}"> - - - + + + -