mirror of
https://github.com/Microsoft/calculator.git
synced 2025-07-13 08:42:53 -07:00
Decrease CPU usage of OverflowTextBlock + optimization (#403)
Fixes #402 and #414 Divide by 4 the CPU usage of OverflowTextBlock when buttons are pressed very quickly. Description of the changes: Xaml-side: OverflowTextBlock has some performance issues: double scrollviewer: the listview was in a scrollviewer, while the control already containing one -> it breaks the virtualization of the listview and impacts on UI performance. The listview used a StackPanel, this panel doesn't support virtualization of ListViewItems contrary to ItemsStackPanel No ListView-specific features were used, an ItemsControl is more efficient and lighter. refactor how we manage the visibility of the left/right buttons in OverflowTextBlock, the new version is more reactive and will not display the right arrow when not necessary (see GIF below). remove the ItemContainerSelector ExpressionItemContainerStyle, not really used by OverflowTextBlock remove UI glitches generated by ChangeView when users type fast (control partially hidden and scrolling issues, see the GIF below). only modify the accessibility view when it's necessary ViewModel-side: stop fully refreshing ExpressionTokens in StandardCalculatorViewModel when a new command were sent, instead, use a IObservableVector to only send new tokens to the UI (in average only 1 or 2 UI items are refreshed while the full expression was refreshed before) How changes were validated: Manually
This commit is contained in:
parent
d21a47d5a1
commit
de65db6197
11 changed files with 145 additions and 322 deletions
|
@ -66,6 +66,7 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() :
|
|||
m_BinaryDisplayValue(L"0"),
|
||||
m_OctalDisplayValue(L"0"),
|
||||
m_standardCalculatorManager(&m_calculatorDisplay, &m_resourceProvider),
|
||||
m_ExpressionTokens(ref new Vector<DisplayExpressionToken^>()),
|
||||
m_MemorizedNumbers(ref new Vector<MemoryItemViewModel^>()),
|
||||
m_IsMemoryEmpty(true),
|
||||
m_IsFToEChecked(false),
|
||||
|
@ -314,59 +315,67 @@ void StandardCalculatorViewModel::SetTokens(_Inout_ shared_ptr<CalculatorVector<
|
|||
{
|
||||
AreTokensUpdated = false;
|
||||
|
||||
if (m_ExpressionTokens == nullptr)
|
||||
{
|
||||
m_ExpressionTokens = ref new Vector<DisplayExpressionToken^>();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ExpressionTokens->Clear();
|
||||
}
|
||||
|
||||
unsigned int nTokens = 0;
|
||||
tokens->GetSize(&nTokens);
|
||||
|
||||
if (nTokens == 0)
|
||||
{
|
||||
m_ExpressionTokens->Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
pair <wstring, int> currentToken;
|
||||
const auto& localizer = LocalizationSettings::GetInstance();
|
||||
|
||||
const wstring separator = L" ";
|
||||
for (unsigned int i = 0; i < nTokens; ++i)
|
||||
{
|
||||
if (SUCCEEDED(tokens->GetAt(i, ¤tToken)))
|
||||
{
|
||||
Common::TokenType type;
|
||||
const wstring separator = L" ";
|
||||
bool isEditable = (currentToken.second == -1) ? false : true;
|
||||
localizer.LocalizeDisplayValue(&(currentToken.first));
|
||||
|
||||
if (!isEditable)
|
||||
{
|
||||
if (currentToken.first == separator)
|
||||
{
|
||||
type = TokenType::Separator;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = TokenType::Operator;
|
||||
}
|
||||
type = currentToken.first == separator ? TokenType::Separator : TokenType::Operator;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
shared_ptr<IExpressionCommand> command;
|
||||
IFTPlatformException(m_commands->GetAt(static_cast<unsigned int>(currentToken.second), &command));
|
||||
type = command->GetCommandType() == CommandType::OperandCommand ? TokenType::Operand : TokenType::Operator;
|
||||
}
|
||||
|
||||
if (command->GetCommandType() == CommandType::OperandCommand)
|
||||
auto currentTokenString = ref new String(currentToken.first.c_str());
|
||||
if (i < m_ExpressionTokens->Size)
|
||||
{
|
||||
auto existingItem = m_ExpressionTokens->GetAt(i);
|
||||
if (type == existingItem->Type && existingItem->Token->Equals(currentTokenString))
|
||||
{
|
||||
type = TokenType::Operand;
|
||||
existingItem->TokenPosition = i;
|
||||
existingItem->IsTokenEditable = isEditable;
|
||||
existingItem->CommandIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = TokenType::Operator;
|
||||
auto expressionToken = ref new DisplayExpressionToken(currentTokenString, i, isEditable, type);
|
||||
m_ExpressionTokens->InsertAt(i, expressionToken);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
auto expressionToken = ref new DisplayExpressionToken(currentTokenString, i, isEditable, type);
|
||||
m_ExpressionTokens->Append(expressionToken);
|
||||
}
|
||||
DisplayExpressionToken^ expressionToken = ref new DisplayExpressionToken(ref new String(currentToken.first.c_str()), i, isEditable, type);
|
||||
m_ExpressionTokens->Append(expressionToken);
|
||||
}
|
||||
}
|
||||
|
||||
while (m_ExpressionTokens->Size != nTokens)
|
||||
{
|
||||
m_ExpressionTokens->RemoveAtEnd();
|
||||
}
|
||||
}
|
||||
|
||||
String^ StandardCalculatorViewModel::GetCalculatorExpressionAutomationName()
|
||||
|
@ -524,7 +533,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
|
|||
{
|
||||
if (commandIndex == 0)
|
||||
{
|
||||
delete [] temp;
|
||||
delete[] temp;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -545,7 +554,7 @@ void StandardCalculatorViewModel::HandleUpdatedOperandData(Command cmdenum)
|
|||
length = m_selectedExpressionLastData->Length() + 1;
|
||||
if (length > 50)
|
||||
{
|
||||
delete [] temp;
|
||||
delete[] temp;
|
||||
return;
|
||||
}
|
||||
for (; i < length; ++i)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue