void CalcView::Evaluate() { BString expression = fExpressionTextView->Text(); if (expression.Length() == 0) { beep(); return; } _AudioFeedback(false); // evaluate expression BString value; try { ExpressionParser parser; parser.SetDegreeMode(fOptions->degree_mode); value = parser.Evaluate(expression.String()); } catch (ParseException e) { BString error(e.message.String()); error << " at " << (e.position + 1); fExpressionTextView->SetText(error.String()); return; } // render new result to display fExpressionTextView->SetValue(value.String()); }
void CalcView::Evaluate() { if (fExpressionTextView->TextLength() == 0) { beep(); return; } fEvaluateThread = spawn_thread(_EvaluateThread, "Evaluate Thread", B_LOW_PRIORITY, this); if (fEvaluateThread < B_OK) { // failed to create evaluate thread, error out fExpressionTextView->SetText(strerror(fEvaluateThread)); return; } _AudioFeedback(false); _SetEnabled(false); // Disable input while we evaluate status_t threadStatus = resume_thread(fEvaluateThread); if (threadStatus != B_OK) { // evaluate thread failed to start, error out fExpressionTextView->SetText(strerror(threadStatus)); _SetEnabled(true); return; } if (fEvaluateMessageRunner == NULL) { BMessage message(kMsgCalculating); fEvaluateMessageRunner = new (std::nothrow) BMessageRunner( BMessenger(this), &message, kCalculatingInterval, 1); status_t runnerStatus = fEvaluateMessageRunner->InitCheck(); if (runnerStatus != B_OK) printf("Evaluate Message Runner: %s\n", strerror(runnerStatus)); } }
void CalcView::_PressKey(int key) { assert(key < (fRows * fColumns)); assert(key >= 0); if (strcmp(fKeypad[key].label, "BS") == 0) { // BS means backspace fExpressionTextView->BackSpace(); } else if (strcmp(fKeypad[key].label, "C") == 0) { // C means clear fExpressionTextView->Clear(); } else if (strcmp(fKeypad[key].label, "acos") == 0 || strcmp(fKeypad[key].label, "asin") == 0 || strcmp(fKeypad[key].label, "atan") == 0 || strcmp(fKeypad[key].label, "cbrt") == 0 || strcmp(fKeypad[key].label, "ceil") == 0 || strcmp(fKeypad[key].label, "cos") == 0 || strcmp(fKeypad[key].label, "cosh") == 0 || strcmp(fKeypad[key].label, "exp") == 0 || strcmp(fKeypad[key].label, "floor") == 0 || strcmp(fKeypad[key].label, "log") == 0 || strcmp(fKeypad[key].label, "ln") == 0 || strcmp(fKeypad[key].label, "sin") == 0 || strcmp(fKeypad[key].label, "sinh") == 0 || strcmp(fKeypad[key].label, "sqrt") == 0 || strcmp(fKeypad[key].label, "tan") == 0 || strcmp(fKeypad[key].label, "tanh") == 0) { int32 labelLen = strlen(fKeypad[key].label); int32 startSelection = 0; int32 endSelection = 0; fExpressionTextView->GetSelection(&startSelection, &endSelection); if (endSelection > startSelection) { // There is selected text, put it inbetween the parens fExpressionTextView->Insert(startSelection, fKeypad[key].label, labelLen); fExpressionTextView->Insert(startSelection + labelLen, "(", 1); fExpressionTextView->Insert(endSelection + labelLen + 1, ")", 1); // Put the cursor after the ending paren // Need to cast to BTextView because Select() is protected // in the InputTextView class static_cast<BTextView*>(fExpressionTextView)->Select( endSelection + labelLen + 2, endSelection + labelLen + 2); } else { // There is no selected text, insert at the cursor location fExpressionTextView->Insert(fKeypad[key].label); fExpressionTextView->Insert("()"); // Put the cursor inside the parens so you can enter an argument // Need to cast to BTextView because Select() is protected // in the InputTextView class static_cast<BTextView*>(fExpressionTextView)->Select( endSelection + labelLen + 1, endSelection + labelLen + 1); } } else { // check for evaluation order if (fKeypad[key].code[0] == '\n') { fExpressionTextView->ApplyChanges(); } else { // insert into expression text fExpressionTextView->Insert(fKeypad[key].code); } } _AudioFeedback(true); }