Merge pull request #7 from nventive/dev/jela/wasm-update

Add support for SetExpressionDisplay
This commit is contained in:
Jérôme Laban 2019-05-17 11:24:15 -04:00 committed by GitHub
commit 52d11bc28a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 287 additions and 244 deletions

View file

@ -10,7 +10,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <iostream> #include <iostream>
#if !defined(__EMSCRIPTEN__) #if DEBUG
#if defined(_WINDOWS_)
#include <Windows.h> #include <Windows.h>
#include <strsafe.h> #include <strsafe.h>
@ -25,23 +26,28 @@ VOID _DBGPRINT(LPCWSTR kwszFunction, INT iLineNumber, LPCWSTR kwszDebugFormatStr
va_start(args, kwszDebugFormatString); va_start(args, kwszDebugFormatString);
cbFormatString = _scwprintf(L"[%s:%d] ", kwszFunction, iLineNumber) * sizeof(WCHAR); cbFormatString = _scwDBGPRINT(L"[%s:%d] ", kwszFunction, iLineNumber) * sizeof(WCHAR);
cbFormatString += _vscwprintf(kwszDebugFormatString, args) * sizeof(WCHAR) + 2; cbFormatString += _vscwDBGPRINT(kwszDebugFormatString, args) * sizeof(WCHAR) + 2;
/* Depending on the size of the format string, allocate space on the stack or the heap. */ /* Depending on the size of the format string, allocate space on the stack or the heap. */
wszDebugString = (PWCHAR)_malloca(cbFormatString); wszDebugString = (PWCHAR)_malloca(cbFormatString);
/* Populate the buffer with the contents of the format string. */ /* Populate the buffer with the contents of the format string. */
StringCbPrintfW(wszDebugString, cbFormatString, L"[%s:%d] ", kwszFunction, iLineNumber); StringCbDBGPRINTW(wszDebugString, cbFormatString, L"[%s:%d] ", kwszFunction, iLineNumber);
StringCbLengthW(wszDebugString, cbFormatString, &st_Offset); StringCbLengthW(wszDebugString, cbFormatString, &st_Offset);
StringCbVPrintfW(&wszDebugString[st_Offset / sizeof(WCHAR)], cbFormatString - st_Offset, kwszDebugFormatString, args); StringCbVDBGPRINTW(&wszDebugString[st_Offset / sizeof(WCHAR)], cbFormatString - st_Offset, kwszDebugFormatString, args);
OutputDebugStringW(wszDebugString); OutputDebugStringW(wszDebugString);
_freea(wszDebugString); _freea(wszDebugString);
va_end(args); va_end(args);
} }
#elif defined(__EMSCRIPTEN__)
#define DBGPRINT(kwszDebugFormatString, ...) printf(kwszDebugFormatString, ##__VA_ARGS__);
#endif #endif
#else
#define DBGPRINT(kwszDebugFormatString, ...)
#endif // DEBUG
using namespace CalculationManager; using namespace CalculationManager;
@ -62,60 +68,69 @@ public:
std::wstring_convert<std::codecvt_utf8<wchar_t>> convert; std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
auto str = convert.to_bytes(pszText); auto str = convert.to_bytes(pszText);
printf("Native:SetPrimaryDisplay(%ls, %d)\n", pszText.data(), isError); DBGPRINT("Native:SetPrimaryDisplay(%ls, %d)\n", pszText.data(), isError);
_params.SetPrimaryDisplay(_params.CalculatorState, str.data(), isError); _params.SetPrimaryDisplay(_params.CalculatorState, str.data(), isError);
} }
virtual void SetIsInError(bool isInError) override virtual void SetIsInError(bool isInError) override
{ {
printf("Native:SetIsInError(%d)\n", isInError); DBGPRINT("Native:SetIsInError(%d)\n", isInError);
_params.SetIsInError(_params.CalculatorState, isInError); _params.SetIsInError(_params.CalculatorState, isInError);
} }
virtual void SetExpressionDisplay( virtual void SetExpressionDisplay(
std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& /*tokens*/, std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens,
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& /*commands*/) override std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& commands) override
{ {
printf("Native:SetExpressionDisplay()\n"); DBGPRINT("Native:SetExpressionDisplay()\n");
auto item = std::make_shared<HISTORYITEM>();
item->historyItemVector.expression = L"";
item->historyItemVector.result = L"";
item->historyItemVector.spCommands = commands;
item->historyItemVector.spTokens = tokens;
auto pItem = MarshalHistoryItem(item);
_params.SetExpressionDisplay(_params.CalculatorState, pItem);
} }
virtual void SetParenthesisNumber(unsigned int count) override virtual void SetParenthesisNumber(unsigned int count) override
{ {
printf("Native:SetParenthesisNumber(%d)\n", count); DBGPRINT("Native:SetParenthesisNumber(%d)\n", count);
_params.SetParenthesisNumber(_params.CalculatorState, count); _params.SetParenthesisNumber(_params.CalculatorState, count);
} }
virtual void OnNoRightParenAdded() override virtual void OnNoRightParenAdded() override
{ {
printf("Native:OnNoRightParenAdded()\n"); DBGPRINT("Native:OnNoRightParenAdded()\n");
_params.OnNoRightParenAdded(_params.CalculatorState); _params.OnNoRightParenAdded(_params.CalculatorState);
} }
virtual void MaxDigitsReached() override virtual void MaxDigitsReached() override
{ {
printf("Native:MaxDigitsReached()\n"); DBGPRINT("Native:MaxDigitsReached()\n");
_params.MaxDigitsReached(_params.CalculatorState); _params.MaxDigitsReached(_params.CalculatorState);
} }
virtual void BinaryOperatorReceived() override virtual void BinaryOperatorReceived() override
{ {
printf("Native:BinaryOperatorReceived()\n"); DBGPRINT("Native:BinaryOperatorReceived()\n");
_params.BinaryOperatorReceived(_params.CalculatorState); _params.BinaryOperatorReceived(_params.CalculatorState);
} }
virtual void OnHistoryItemAdded(unsigned int addedItemIndex) override virtual void OnHistoryItemAdded(unsigned int addedItemIndex) override
{ {
printf("Native:OnHistoryItemAdded(%d)\n", addedItemIndex); DBGPRINT("Native:OnHistoryItemAdded(%d)\n", addedItemIndex);
_params.OnHistoryItemAdded(_params.CalculatorState, addedItemIndex); _params.OnHistoryItemAdded(_params.CalculatorState, addedItemIndex);
} }
virtual void SetMemorizedNumbers(const std::vector<std::wstring>& memorizedNumbers) override virtual void SetMemorizedNumbers(const std::vector<std::wstring>& memorizedNumbers) override
{ {
printf("Native:SetMemorizedNumbers(%d)\n", (int)memorizedNumbers.size()); DBGPRINT("Native:SetMemorizedNumbers(%d)\n", (int)memorizedNumbers.size());
auto numbers = new const wchar_t* [memorizedNumbers.size()] {}; auto numbers = new const wchar_t* [memorizedNumbers.size()] {};
@ -139,7 +154,7 @@ public:
virtual void MemoryItemChanged(unsigned int indexOfMemory) override virtual void MemoryItemChanged(unsigned int indexOfMemory) override
{ {
printf("Native:MemoryItemChanged(%d)\n", indexOfMemory); DBGPRINT("Native:MemoryItemChanged(%d)\n", indexOfMemory);
_params.MemoryItemChanged(_params.CalculatorState, indexOfMemory); _params.MemoryItemChanged(_params.CalculatorState, indexOfMemory);
} }
@ -160,7 +175,7 @@ public:
{ {
auto pResult = _params.GetCEngineString(_params.ResourceState, id.data()); auto pResult = _params.GetCEngineString(_params.ResourceState, id.data());
auto str = std::wstring(pResult); auto str = std::wstring(pResult);
printf("Native:GetCEngineString(id=%ls, str.data()=%ls)\n", id.data(), str.data()); DBGPRINT("Native:GetCEngineString(id=%ls, str.data()=%ls)\n", id.data(), str.data());
return str; return str;
} }
}; };
@ -182,6 +197,83 @@ const wchar_t* ToWChar(std::wstring& str)
return out; return out;
} }
GetHistoryItemResult* MarshalHistoryItem(std::shared_ptr<CalculationManager::HISTORYITEM>& historyItem)
{
auto itemResult = new GetHistoryItemResult{};
itemResult->expression = ToWChar(historyItem->historyItemVector.expression);
itemResult->result = ToWChar(historyItem->historyItemVector.result);
unsigned int tokenCount;
historyItem->historyItemVector.spTokens->GetSize(&tokenCount);
itemResult->TokenCount = tokenCount;
//
// Marshal Tokens
//
auto tokenStrings = new const wchar_t* [tokenCount] {};
auto tokenValues = new int32_t[tokenCount]{};
// DBGPRINT(L"TokenCount: %d (int32_t: %d)\n", tokenCount, sizeof(int32_t));
for (uint32_t j = 0; j < tokenCount; j++)
{
std::pair<std::wstring, int> pair;
if (SUCCEEDED(historyItem->historyItemVector.spTokens->GetAt(j, &pair)))
{
tokenStrings[j] = ToWChar(pair.first);
tokenValues[j] = (int32_t)pair.second;
// DBGPRINT(L"\tPair: %ws;%d\n", pair.first.data(), tokenValues[j]);
}
}
itemResult->TokenStrings = tokenStrings;
itemResult->TokenValues = tokenValues;
//
// Marshal Commands
//
unsigned int commandCount;
historyItem->historyItemVector.spCommands->GetSize(&commandCount);
itemResult->CommandCount = commandCount;
auto commands = new void* [commandCount] {};
for (uint32_t commandId = 0; commandId < commandCount; commandId++)
{
std::shared_ptr<IExpressionCommand> command;
if (SUCCEEDED(historyItem->historyItemVector.spCommands->GetAt(commandId, &command)))
{
commands[commandId] = command.get();
}
}
itemResult->Commands = commands;
return itemResult;
}
void* MarshalHistoryItems(std::vector<std::shared_ptr<CalculationManager::HISTORYITEM>>& historyItems)
{
auto result = new GetHistoryItemsResult{};
result->ItemsCount = (int32_t)historyItems.size();
auto resultsArray = new GetHistoryItemResult*[result->ItemsCount];
result->HistoryItems = (void*)resultsArray;
for (size_t i = 0; i < historyItems.size(); i++)
{
auto historyItem = historyItems[i];
resultsArray[i] = MarshalHistoryItem(historyItem);
}
return result;
}
void* CalculatorManager_Create(CalculatorManager_CreateParams* pParams) void* CalculatorManager_Create(CalculatorManager_CreateParams* pParams)
{ {
auto calcDisplay = new CalcDisplay(*pParams); auto calcDisplay = new CalcDisplay(*pParams);
@ -316,82 +408,6 @@ void CalculatorManager_SetInHistoryItemLoadMode(void* manager, bool isHistoryIte
AsManager(manager)->SetInHistoryItemLoadMode(isHistoryItemLoadMode); AsManager(manager)->SetInHistoryItemLoadMode(isHistoryItemLoadMode);
} }
GetHistoryItemResult* MarshalHistoryItem(std::shared_ptr<CalculationManager::HISTORYITEM>& historyItem)
{
auto itemResult = new GetHistoryItemResult{};
itemResult->expression = ToWChar(historyItem->historyItemVector.expression);
itemResult->result = ToWChar(historyItem->historyItemVector.result);
unsigned int tokenCount;
historyItem->historyItemVector.spTokens->GetSize(&tokenCount);
itemResult->TokenCount = tokenCount;
//
// Marshal Tokens
//
auto tokenStrings = new const wchar_t* [tokenCount] {};
auto tokenValues = new int32_t[tokenCount]{};
// DBGPRINT(L"TokenCount: %d (int32_t: %d)\n", tokenCount, sizeof(int32_t));
for (uint32_t j = 0; j < tokenCount; j++)
{
std::pair<std::wstring, int> pair;
if (SUCCEEDED(historyItem->historyItemVector.spTokens->GetAt(j, &pair)))
{
tokenStrings[j] = ToWChar(pair.first);
tokenValues[j] = (int32_t)pair.second;
// DBGPRINT(L"\tPair: %ws;%d\n", pair.first.data(), tokenValues[j]);
}
}
itemResult->TokenStrings = tokenStrings;
itemResult->TokenValues = tokenValues;
//
// Marshal Commands
//
unsigned int commandCount;
historyItem->historyItemVector.spCommands->GetSize(&commandCount);
itemResult->CommandCount = commandCount;
auto commands = new void*[commandCount]{};
for (uint32_t commandId = 0; commandId < commandCount; commandId++)
{
std::shared_ptr<IExpressionCommand> command;
if (SUCCEEDED(historyItem->historyItemVector.spCommands->GetAt(commandId, &command)))
{
commands[commandId] = command.get();
}
}
itemResult->Commands = commands;
return itemResult;
}
void* MarshalHistoryItems(std::vector<std::shared_ptr<CalculationManager::HISTORYITEM>>& historyItems)
{
auto result = new GetHistoryItemsResult{};
result->ItemsCount = (int32_t)historyItems.size();
auto resultsArray = new GetHistoryItemResult*[result->ItemsCount];
result->HistoryItems = (void*)resultsArray;
for (size_t i = 0; i < historyItems.size(); i++)
{
auto historyItem = historyItems[i];
resultsArray[i] = MarshalHistoryItem(historyItem);
}
return result;
}
void* CalculatorManager_GetHistoryItems(void* manager) void* CalculatorManager_GetHistoryItems(void* manager)
{ {
auto historyItems = AsManager(manager)->GetHistoryItems(); auto historyItems = AsManager(manager)->GetHistoryItems();

View file

@ -6,23 +6,12 @@
#include "headers/Rational.h" #include "headers/Rational.h"
#include "headers/ICalcDisplay.h" #include "headers/ICalcDisplay.h"
struct GetHistoryItemResult;
struct TokenPair { struct GetHistoryItemsResult;
char* Item1;
int Item2;
};
struct ExpressionDisplayData {
int TokenCount;
TokenPair* Tokens;
int CommandCount;
void* Commands;
};
typedef void (*SetPrimaryDisplayFunc)(void* state, const char* text, bool isError); typedef void (*SetPrimaryDisplayFunc)(void* state, const char* text, bool isError);
typedef void (*SetIsInErrorFunc)(void* state, bool isInError); typedef void (*SetIsInErrorFunc)(void* state, bool isInError);
typedef void (*SetExpressionDisplayFunc)(void* state, ExpressionDisplayData* data); typedef void (*SetExpressionDisplayFunc)(void* state, GetHistoryItemResult* data);
typedef void (*SetParenthesisNumberFunc)(void* state, unsigned int count); typedef void (*SetParenthesisNumberFunc)(void* state, unsigned int count);
typedef void (*OnNoRightParenAddedFunc)(void* state); typedef void (*OnNoRightParenAddedFunc)(void* state);
typedef void (*MaxDigitsReachedFunc)(void* state); typedef void (*MaxDigitsReachedFunc)(void* state);
@ -57,6 +46,9 @@ struct CalculatorManager_CreateParams {
#define DLL_EXPORT __declspec(dllexport) #define DLL_EXPORT __declspec(dllexport)
#endif #endif
GetHistoryItemResult* MarshalHistoryItem(std::shared_ptr<CalculationManager::HISTORYITEM>& historyItem);
void* MarshalHistoryItems(std::vector<std::shared_ptr<CalculationManager::HISTORYITEM>>& historyItems);
extern "C" { extern "C" {
struct GetHistoryItemsResult struct GetHistoryItemsResult

Binary file not shown.

View file

@ -106,8 +106,12 @@ namespace CalculatorApp
public static string GetAppViewState() public static string GetAppViewState()
{ {
String newViewState; String newViewState;
CoreWindow window = CoreWindow.GetForCurrentThread(); #if NETFX_CORE
if ((window.Bounds.Width >= 560) && (window.Bounds.Height >= 356)) CoreWindow window = CoreWindow.GetForCurrentThread();
#else
var window = Windows.UI.Xaml.Window.Current;
#endif
if ((window.Bounds.Width >= 560) && (window.Bounds.Height >= 356))
{ {
newViewState = ViewState.DockedView; newViewState = ViewState.DockedView;
} }

View file

@ -106,7 +106,7 @@ namespace CalculationManager
public delegate void MemoryItemChangedCallbackFunc(IntPtr state, int indexOfMemory); public delegate void MemoryItemChangedCallbackFunc(IntPtr state, int indexOfMemory);
public delegate void OnHistoryItemAddedCallbackFunc(IntPtr state, int addedItemIndex); public delegate void OnHistoryItemAddedCallbackFunc(IntPtr state, int addedItemIndex);
public delegate void OnNoRightParenAddedCallbackFunc(IntPtr state); public delegate void OnNoRightParenAddedCallbackFunc(IntPtr state);
public delegate void SetExpressionDisplayCallbackFunc(IntPtr state); public delegate void SetExpressionDisplayCallbackFunc(IntPtr state, IntPtr data);
public delegate void SetMemorizedNumbersCallbackFunc(IntPtr state, int count, IntPtr newMemorizedNumbers); public delegate void SetMemorizedNumbersCallbackFunc(IntPtr state, int count, IntPtr newMemorizedNumbers);
public static GetCEngineStringFunc _getCEngineStringCallback = GetCEngineStringCallback; public static GetCEngineStringFunc _getCEngineStringCallback = GetCEngineStringCallback;
@ -127,7 +127,7 @@ namespace CalculationManager
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay; var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.MaxDigitsReached(); manager.MaxDigitsReached();
Debug.WriteLine($"CalculatorManager.MaxDigitsReachedCallback"); DebugTrace($"CalculatorManager.MaxDigitsReachedCallback");
} }
public static void MemoryItemChangedCallback(IntPtr state, int indexOfMemory) public static void MemoryItemChangedCallback(IntPtr state, int indexOfMemory)
@ -135,7 +135,7 @@ namespace CalculationManager
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay; var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.MemoryItemChanged(indexOfMemory); manager.MemoryItemChanged(indexOfMemory);
Debug.WriteLine($"CalculatorManager.MemoryItemChangedCallback({indexOfMemory})"); DebugTrace($"CalculatorManager.MemoryItemChangedCallback({indexOfMemory})");
} }
public static void OnHistoryItemAddedCallback(IntPtr state, int addedItemIndex) public static void OnHistoryItemAddedCallback(IntPtr state, int addedItemIndex)
@ -143,7 +143,7 @@ namespace CalculationManager
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay; var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.OnHistoryItemAdded(addedItemIndex); manager.OnHistoryItemAdded(addedItemIndex);
Debug.WriteLine($"CalculatorManager.OnHistoryItemAddedCallback({addedItemIndex})"); DebugTrace($"CalculatorManager.OnHistoryItemAddedCallback({addedItemIndex})");
} }
public static void OnNoRightParenAddedCallback(IntPtr state) public static void OnNoRightParenAddedCallback(IntPtr state)
@ -151,15 +151,20 @@ namespace CalculationManager
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay; var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.OnNoRightParenAdded(); manager.OnNoRightParenAdded();
Debug.WriteLine($"CalculatorManager.OnNoRightParenAddedCallback"); DebugTrace($"CalculatorManager.OnNoRightParenAddedCallback");
} }
public static void SetExpressionDisplayCallback(IntPtr state) public static void SetExpressionDisplayCallback(IntPtr state, IntPtr historyItem)
{ {
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay; DebugTrace($"CalculatorManager.SetExpressionDisplayCallback({state}, {historyItem})");
// manager.SetExpressionDisplay();
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
var nativeResult = Marshal.PtrToStructure<GetHistoryItemResult>(historyItem);
var itemResult = CalculatorManager.UnmarshalHistoryItemResult(nativeResult);
manager.SetExpressionDisplay(itemResult.historyItemVector.spTokens, itemResult.historyItemVector.spCommands);
Debug.WriteLine($"CalculatorManager.SetExpressionDisplayCallback");
} }
public static void SetMemorizedNumbersCallback(IntPtr state, int count, IntPtr newMemorizedNumbers) public static void SetMemorizedNumbersCallback(IntPtr state, int count, IntPtr newMemorizedNumbers)
@ -175,7 +180,7 @@ namespace CalculationManager
manager.SetMemorizedNumbers(numbers); manager.SetMemorizedNumbers(numbers);
Debug.WriteLine($"CalculatorManager.SetMemorizedNumbersCallback({string.Join(";", numbers)})"); DebugTrace($"CalculatorManager.SetMemorizedNumbersCallback({string.Join(";", numbers)})");
} }
public static void SetParenthesisNumberCallback(IntPtr state, int parenthesisCount) public static void SetParenthesisNumberCallback(IntPtr state, int parenthesisCount)
@ -183,7 +188,7 @@ namespace CalculationManager
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay; var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.SetParenthesisNumber(parenthesisCount); manager.SetParenthesisNumber(parenthesisCount);
Debug.WriteLine($"CalculatorManager.SetParenthesisNumberCallback({parenthesisCount})"); DebugTrace($"CalculatorManager.SetParenthesisNumberCallback({parenthesisCount})");
} }
public static void BinaryOperatorReceivedCallback(IntPtr state) public static void BinaryOperatorReceivedCallback(IntPtr state)
@ -191,7 +196,7 @@ namespace CalculationManager
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay; var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.BinaryOperatorReceived(); manager.BinaryOperatorReceived();
Debug.WriteLine($"CalculatorManager.BinaryOperatorReceivedCallback"); DebugTrace($"CalculatorManager.BinaryOperatorReceivedCallback");
} }
public static void SetPrimaryDisplayCallback(IntPtr state, [MarshalAs(UnmanagedType.LPWStr)] string displayStringValue, bool isError) public static void SetPrimaryDisplayCallback(IntPtr state, [MarshalAs(UnmanagedType.LPWStr)] string displayStringValue, bool isError)
@ -199,7 +204,7 @@ namespace CalculationManager
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay; var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.SetPrimaryDisplay(displayStringValue, isError); manager.SetPrimaryDisplay(displayStringValue, isError);
Debug.WriteLine($"CalculatorManager.SetPrimaryDisplayCallback({displayStringValue}, {isError})"); DebugTrace($"CalculatorManager.SetPrimaryDisplayCallback({displayStringValue}, {isError})");
} }
public static void SetIsInErrorCallback(IntPtr state, bool isError) public static void SetIsInErrorCallback(IntPtr state, bool isError)
@ -207,7 +212,7 @@ namespace CalculationManager
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay; var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.SetIsInError(isError); manager.SetIsInError(isError);
Debug.WriteLine($"CalculatorManager.SetIsInErrorCallback({isError})"); DebugTrace($"CalculatorManager.SetIsInErrorCallback({isError})");
} }
public static IntPtr GetCEngineStringCallback(IntPtr state, IntPtr pResourceId) public static IntPtr GetCEngineStringCallback(IntPtr state, IntPtr pResourceId)
@ -223,7 +228,7 @@ namespace CalculationManager
var pEngineString = Marshal.StringToHGlobalUni(resourceValue); var pEngineString = Marshal.StringToHGlobalUni(resourceValue);
#endif #endif
Debug.WriteLine($"GetCEngineStringCallback({resourceId}, {resourceValue}"); DebugTrace($"GetCEngineStringCallback({resourceId}, {resourceValue})");
return pEngineString; return pEngineString;
} }
@ -236,6 +241,11 @@ namespace CalculationManager
Marshal.WriteInt32(pRet2 + resourceValue.Length * 4, 0); Marshal.WriteInt32(pRet2 + resourceValue.Length * 4, 0);
return pRet2; return pRet2;
} }
private static void DebugTrace(string message)
{
// Debug.WriteLine(message);
}
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]

View file

@ -248,7 +248,7 @@ namespace CalculationManager
return output; return output;
} }
private static HISTORYITEM UnmarshalHistoryItemResult(GetHistoryItemResult historyResultItem) internal static HISTORYITEM UnmarshalHistoryItemResult(GetHistoryItemResult historyResultItem)
{ {
var historyItem = new HISTORYITEM(); var historyItem = new HISTORYITEM();
historyItem.historyItemVector.expression = historyResultItem.expression; historyItem.historyItemVector.expression = historyResultItem.expression;

View file

@ -67,8 +67,8 @@ namespace CalculationManager
public CParentheses(IntPtr pExpressionCommand) => this.pExpressionCommand = pExpressionCommand; public CParentheses(IntPtr pExpressionCommand) => this.pExpressionCommand = pExpressionCommand;
public int GetCommand() => throw new NotImplementedException(); public int GetCommand() => throw new NotImplementedException();
public CalculationManager.CommandType GetCommandType() => throw new NotImplementedException(); public CalculationManager.CommandType GetCommandType() => CommandType.Parentheses;
public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException(); public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException();
} }
public class CUnaryCommand : IUnaryCommand public class CUnaryCommand : IUnaryCommand
@ -80,8 +80,8 @@ namespace CalculationManager
public CUnaryCommand(int command) => throw new NotImplementedException(); public CUnaryCommand(int command) => throw new NotImplementedException();
public CUnaryCommand(int command1, int command2) => throw new NotImplementedException(); public CUnaryCommand(int command1, int command2) => throw new NotImplementedException();
public CalculatorList<int> GetCommands() => throw new NotImplementedException(); public CalculatorList<int> GetCommands() => throw new NotImplementedException();
public CalculationManager.CommandType GetCommandType() => throw new NotImplementedException(); public CalculationManager.CommandType GetCommandType() => CommandType.UnaryCommand;
public void SetCommand(int command) => throw new NotImplementedException(); public void SetCommand(int command) => throw new NotImplementedException();
public void SetCommands(int command1, int command2) => throw new NotImplementedException(); public void SetCommands(int command1, int command2) => throw new NotImplementedException();
public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException(); public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException();
} }
@ -95,7 +95,7 @@ namespace CalculationManager
public CBinaryCommand(int command) => throw new NotImplementedException(); public CBinaryCommand(int command) => throw new NotImplementedException();
public void SetCommand(int command) => throw new NotImplementedException(); public void SetCommand(int command) => throw new NotImplementedException();
public int GetCommand() => throw new NotImplementedException(); public int GetCommand() => throw new NotImplementedException();
public CommandType GetCommandType() => throw new NotImplementedException(); public CalculationManager.CommandType GetCommandType() => CommandType.BinaryCommand;
public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException(); public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException();
} }
@ -117,7 +117,7 @@ namespace CalculationManager
public bool IsSciFmt() => throw new NotImplementedException(); public bool IsSciFmt() => throw new NotImplementedException();
public bool IsDecimalPresent() => throw new NotImplementedException(); public bool IsDecimalPresent() => throw new NotImplementedException();
public string GetToken(char decimalSymbol) => throw new NotImplementedException(); public string GetToken(char decimalSymbol) => throw new NotImplementedException();
public CalculationManager.CommandType GetCommandType() => throw new NotImplementedException(); public CalculationManager.CommandType GetCommandType() => CommandType.OperandCommand;
public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException(); public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException();
public string GetString(uint radix, int precision) => throw new NotImplementedException(); public string GetString(uint radix, int precision) => throw new NotImplementedException();
} }

View file

@ -11,7 +11,7 @@ namespace CalculatorApp
[Windows.UI.Xaml.Data.Bindable] [Windows.UI.Xaml.Data.Bindable]
public sealed class ExpressionItemTemplateSelector : Windows.UI.Xaml.Controls.DataTemplateSelector public sealed class ExpressionItemTemplateSelector : Windows.UI.Xaml.Controls.DataTemplateSelector
{ {
Windows.UI.Xaml.DataTemplate SelectTemplateCore(object item, Windows.UI.Xaml.DependencyObject container) protected override Windows.UI.Xaml.DataTemplate SelectTemplateCore(object item, Windows.UI.Xaml.DependencyObject container)
{ {
DisplayExpressionToken token = (DisplayExpressionToken)(item); DisplayExpressionToken token = (DisplayExpressionToken)(item);
if (token != null) if (token != null)

View file

@ -830,7 +830,7 @@ namespace CalculatorApp.ViewModel
else else
{ {
var expressionToken = new DisplayExpressionToken(currentTokenString, i, isEditable, type); var expressionToken = new DisplayExpressionToken(currentTokenString, i, isEditable, type);
m_ExpressionTokens.Append(expressionToken); m_ExpressionTokens.Add(expressionToken);
} }
} }
} }

View file

@ -907,7 +907,7 @@
<VisualStateGroup> <VisualStateGroup>
<VisualState x:Name="ResultsL"> <VisualState x:Name="ResultsL">
<VisualState.StateTriggers> <VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="800" /> <AdaptiveTrigger x:Name="ResultsMVisualStateTrigger" MinWindowHeight="800" />
</VisualState.StateTriggers> </VisualState.StateTriggers>
<Storyboard /> <Storyboard />
</VisualState> </VisualState>
@ -969,7 +969,7 @@
IsOperatorCommand="{x:Bind Model.IsOperatorCommand, Mode=OneWay}" IsOperatorCommand="{x:Bind Model.IsOperatorCommand, Mode=OneWay}"
TabIndex="1" /> TabIndex="1" />
<controls:OverflowTextBlock x:Name="expressionText" <controls:OverflowTextBlock x:Name="expressionText"
xamarin:Style="{StaticResource overflowTextBlockStyle}" Style="{StaticResource overflowTextBlockStyle}"
Grid.Row="1" Grid.Row="1"
Margin="6,0,6,0" Margin="6,0,6,0"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"

View file

@ -228,21 +228,21 @@ namespace CalculatorApp
state = "Programmer"; state = "Programmer";
Model.IsDecimalEnabled = false; Model.IsDecimalEnabled = false;
// UNO TODO // UNO TODO
// ResultsMVisualStateTrigger.MinWindowHeight = 640; ResultsMVisualStateTrigger.MinWindowHeight = 640;
} }
else if (IsScientific) else if (IsScientific)
{ {
state = "Scientific"; state = "Scientific";
Model.IsDecimalEnabled = true; Model.IsDecimalEnabled = true;
// UNO TODO // UNO TODO
// ResultsMVisualStateTrigger.MinWindowHeight = 544; ResultsMVisualStateTrigger.MinWindowHeight = 544;
} }
else else
{ {
state = "Standard"; state = "Standard";
Model.IsDecimalEnabled = true; Model.IsDecimalEnabled = true;
// UNO TODO // UNO TODO
// ResultsMVisualStateTrigger.MinWindowHeight = 1; ResultsMVisualStateTrigger.MinWindowHeight = 1;
} }
CloseHistoryFlyout(); CloseHistoryFlyout();
@ -376,7 +376,8 @@ namespace CalculatorApp
} }
else else
{ {
AnimateWithoutResult.Begin(); /* UNO TODO */
AnimateWithoutResult?.Begin();
} }
} }
} }

View file

@ -14,126 +14,146 @@ using Windows.UI.Xaml;
namespace CalculatorApp.Views.StateTriggers namespace CalculatorApp.Views.StateTriggers
{ {
public enum Aspect public enum Aspect
{ {
Height, Height,
Width Width
} }
public sealed class AspectRatioTrigger : Windows.UI.Xaml.StateTriggerBase public sealed class AspectRatioTrigger : Windows.UI.Xaml.StateTriggerBase
{ {
/* The source for which this class will respond to size changed events. */ /* The source for which this class will respond to size changed events. */
public FrameworkElement Source public FrameworkElement Source
{ {
get { return (FrameworkElement)GetValue(SourceProperty); } get { return (FrameworkElement)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); } set { SetValue(SourceProperty, value); }
} }
public static readonly DependencyProperty SourceProperty = public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source", typeof(FrameworkElement), typeof(AspectRatioTrigger), new PropertyMetadata(null)); DependencyProperty.Register(
name: nameof(Source),
propertyType: typeof(FrameworkElement),
ownerType: typeof(AspectRatioTrigger),
typeMetadata: new PropertyMetadata(
defaultValue: null,
propertyChangedCallback: (s, e) => (s as AspectRatioTrigger)?.OnSourcePropertyChanged(e.OldValue as FrameworkElement, e.NewValue as FrameworkElement))
);
/* Either Height or Width. The property will determine which aspect is used as the numerator when calculating /* Either Height or Width. The property will determine which aspect is used as the numerator when calculating
the aspect ratio. */ the aspect ratio. */
public Aspect NumeratorAspect public Aspect NumeratorAspect
{ {
get { return (Aspect)GetValue(NumeratorAspectProperty); } get { return (Aspect)GetValue(NumeratorAspectProperty); }
set { SetValue(NumeratorAspectProperty, value); } set { SetValue(NumeratorAspectProperty, value); }
} }
// Using a DependencyProperty as the backing store for NumeratorAspect. This enables animation, styling, binding, etc... // Using a DependencyProperty as the backing store for NumeratorAspect. This enables animation, styling, binding, etc...
public static readonly DependencyProperty NumeratorAspectProperty = public static readonly DependencyProperty NumeratorAspectProperty =
DependencyProperty.Register("NumeratorAspect", typeof(Aspect), typeof(AspectRatioTrigger), new PropertyMetadata(Aspect.Height)); DependencyProperty.Register(
name: "NumeratorAspect",
propertyType: typeof(Aspect),
ownerType: typeof(AspectRatioTrigger),
typeMetadata: new PropertyMetadata(Aspect.Height)
);
/* The threshold that will cause the trigger to fire when the aspect ratio exceeds this value. */ /* The threshold that will cause the trigger to fire when the aspect ratio exceeds this value. */
public double Threshold public double Threshold
{ {
get { return (double)GetValue(ThresholdProperty); } get { return (double)GetValue(ThresholdProperty); }
set { SetValue(ThresholdProperty, value); } set { SetValue(ThresholdProperty, value); }
} }
// Using a DependencyProperty as the backing store for Threshold. This enables animation, styling, binding, etc... // Using a DependencyProperty as the backing store for Threshold. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ThresholdProperty = public static readonly DependencyProperty ThresholdProperty =
DependencyProperty.Register("Threshold", typeof(double), typeof(AspectRatioTrigger), new PropertyMetadata(0.0)); DependencyProperty.Register(
name: "Threshold",
propertyType: typeof(double),
ownerType: typeof(AspectRatioTrigger),
typeMetadata: new PropertyMetadata(0.0)
);
/* If true, the trigger will fire if the aspect ratio is greater than or equal to the threshold. */
public bool ActiveIfEqual
{
get { return (bool)GetValue(ActiveIfEqualProperty); }
set { SetValue(ActiveIfEqualProperty, value); }
}
// Using a DependencyProperty as the backing store for ActiveIfEqual. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ActiveIfEqualProperty =
DependencyProperty.Register(
name: "ActiveIfEqual",
propertyType: typeof(bool),
ownerType: typeof(AspectRatioTrigger),
typeMetadata: new PropertyMetadata(false)
);
AspectRatioTrigger()
{
SetActive(false);
}
/* If true, the trigger will fire if the aspect ratio is greater than or equal to the threshold. */ void OnSourcePropertyChanged(FrameworkElement oldValue, FrameworkElement newValue)
public bool ActiveIfEqual {
{ UnregisterSizeChanged(oldValue);
get { return (bool)GetValue(ActiveIfEqualProperty); } RegisterSizeChanged(newValue);
set { SetValue(ActiveIfEqualProperty, value); } }
}
// Using a DependencyProperty as the backing store for ActiveIfEqual. This enables animation, styling, binding, etc... void RegisterSizeChanged(FrameworkElement element)
public static readonly DependencyProperty ActiveIfEqualProperty = {
DependencyProperty.Register("ActiveIfEqual", typeof(bool), typeof(AspectRatioTrigger), new PropertyMetadata(false)); if (element == null)
{
return;
}
if (element != Source)
{
UnregisterSizeChanged(Source);
}
AspectRatioTrigger() element.SizeChanged += OnSizeChanged;
{ }
SetActive(false);
}
void OnSourcePropertyChanged(FrameworkElement oldValue, FrameworkElement newValue) void UnregisterSizeChanged(FrameworkElement element)
{ {
UnregisterSizeChanged(oldValue); if (element != null)
RegisterSizeChanged(newValue); {
} element.SizeChanged -= OnSizeChanged;
}
}
void RegisterSizeChanged(FrameworkElement element) void OnSizeChanged(object sender, SizeChangedEventArgs e)
{ {
if (element == null) UpdateIsActive(e.NewSize);
{ }
return;
}
if (element != Source) void UpdateIsActive(Size sourceSize)
{ {
UnregisterSizeChanged(Source); double numerator, denominator;
} if (NumeratorAspect == Aspect.Height)
{
numerator = sourceSize.Height;
denominator = sourceSize.Width;
}
else
{
numerator = sourceSize.Width;
denominator = sourceSize.Height;
}
element.SizeChanged += OnSizeChanged; bool isActive = false;
} if (denominator > 0)
{
double ratio = numerator / denominator;
double threshold = Math.Abs(Threshold);
void UnregisterSizeChanged(FrameworkElement element) isActive = ((ratio > threshold) || (ActiveIfEqual && (ratio == threshold)));
{ }
if (element != null)
{
element.SizeChanged -= OnSizeChanged;
}
}
void OnSizeChanged(object sender, SizeChangedEventArgs e) SetActive(isActive);
{ }
UpdateIsActive(e.NewSize);
}
void UpdateIsActive(Size sourceSize) }
{
double numerator, denominator;
if (NumeratorAspect == Aspect.Height)
{
numerator = sourceSize.Height;
denominator = sourceSize.Width;
}
else
{
numerator = sourceSize.Width;
denominator = sourceSize.Height;
}
bool isActive = false;
if (denominator > 0)
{
double ratio = numerator / denominator;
double threshold = Math.Abs(Threshold);
isActive = ((ratio > threshold) || (ActiveIfEqual && (ratio == threshold)));
}
SetActive(isActive);
}
}
} }

View file

@ -2,6 +2,6 @@
splashScreenImage: "Assets/SplashScreen.scale-200.png", splashScreenImage: "Assets/SplashScreen.scale-200.png",
splashScreenColor: "#00f", splashScreenColor: "#00f",
displayName: "WindowsCalculator" displayName: "Calculator"
} }

View file

@ -22,8 +22,8 @@
var fMaxDigitsReachedCallback = Module.addFunction((state) => _maxDigitsReachedCallback(state), 'vii'); var fMaxDigitsReachedCallback = Module.addFunction((state) => _maxDigitsReachedCallback(state), 'vii');
var fMemoryItemChangedCallback = Module.addFunction((state, indexOfMemory) => _memoryItemChangedCallback(state, indexOfMemory), 'vii'); var fMemoryItemChangedCallback = Module.addFunction((state, indexOfMemory) => _memoryItemChangedCallback(state, indexOfMemory), 'vii');
var fOnHistoryItemAddedCallback = Module.addFunction((state, addedItemIndex) => _onHistoryItemAddedCallback(state, addedItemIndex), 'vii'); var fOnHistoryItemAddedCallback = Module.addFunction((state, addedItemIndex) => _onHistoryItemAddedCallback(state, addedItemIndex), 'vii');
var fOnNoRightParenAddedCallback = Module.addFunction((state) => _onNoRightParenAddedCallback (state), 'vi'); var fOnNoRightParenAddedCallback = Module.addFunction((state) => _onNoRightParenAddedCallback(state), 'vi');
var fSetExpressionDisplayCallback = Module.addFunction((state) => _setExpressionDisplayCallback (state), 'vi'); var fSetExpressionDisplayCallback = Module.addFunction((state, historyItem) => _setExpressionDisplayCallback(state, historyItem), 'vii');
var fSetMemorizedNumbersCallback = Module.addFunction((state, size, numbers) => _setMemorizedNumbersCallback(state, size, numbers), 'viii'); var fSetMemorizedNumbersCallback = Module.addFunction((state, size, numbers) => _setMemorizedNumbersCallback(state, size, numbers), 'viii');
var ret = `${fGetCEngineStringCallback};` var ret = `${fGetCEngineStringCallback};`