Add a scientific mode to Deskcalc.
Deskcalc already contains support for all the functions in scientific mode but up until now you had to know what they were called and type them in to figure them out. Scientific mode gives you access to most of the available functions via buttons. Pushing one of the the scientific mode buttons inserts the function name along with an innertube () at the current cursor location. If you have some text highlighted when you push a scientific mode button it will put that text inside the innertube. So you can type 0.5, then highlight the text with the mouse, and then push the sin button and you will get sin(0.5). The contextual menu has been altered to support the new mode. Instead of having a single show keypad option in the contextual menu there are 3 new options instead. Compact mode, Basic mode, and Scientific mode. Basic mode is the default mode showing the basic keypad. Compact mode is the same as show keypad turned off, showing just a bare text field. Scientific mode is the new mode which adds buttons for the different transcendental functions and constants that Deskcalc supports. You can also use Alt+0, Alt+1, and Alt+2 keyboard modifiers to switch between the modes. In addition to accepting the word 'pi' for the circumference of the unit circle, Deskcalc now also recognizes the UTF-8 character π which has a dedicated button in scientific mode. I also changed the parser so that lowercase 'e' always means Euler's number and uppercase 'E' always means 'times 10 to the' so 1E5 means 1 times 10 to the 5th. Another small tweak I did was to adjust the minimum basic mode width so that the window is flush with the tab. I also renamed fColums to fColumns, took out some spaces and other style changes and bumped the version to 2.2.0. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@43199 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006 Haiku, Inc. All Rights Reserved.
|
* Copyright 2006-2011 Haiku, Inc. All Rights Reserved.
|
||||||
* Copyright 1997, 1998 R3 Software Ltd. All Rights Reserved.
|
* Copyright 1997, 1998 R3 Software Ltd. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ CalcOptions::CalcOptions()
|
|||||||
:
|
:
|
||||||
auto_num_lock(false),
|
auto_num_lock(false),
|
||||||
audio_feedback(false),
|
audio_feedback(false),
|
||||||
show_keypad(true)
|
keypad_mode(KEYPAD_MODE_BASIC)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +29,7 @@ void
|
|||||||
CalcOptions::LoadSettings(const BMessage* archive)
|
CalcOptions::LoadSettings(const BMessage* archive)
|
||||||
{
|
{
|
||||||
bool option;
|
bool option;
|
||||||
|
uint8 keypad_mode_option;
|
||||||
|
|
||||||
if (archive->FindBool("auto num lock", &option) == B_OK)
|
if (archive->FindBool("auto num lock", &option) == B_OK)
|
||||||
auto_num_lock = option;
|
auto_num_lock = option;
|
||||||
@@ -36,8 +37,8 @@ CalcOptions::LoadSettings(const BMessage* archive)
|
|||||||
if (archive->FindBool("audio feedback", &option) == B_OK)
|
if (archive->FindBool("audio feedback", &option) == B_OK)
|
||||||
audio_feedback = option;
|
audio_feedback = option;
|
||||||
|
|
||||||
if (archive->FindBool("show keypad", &option) == B_OK)
|
if (archive->FindUInt8("keypad mode", &keypad_mode_option) == B_OK)
|
||||||
show_keypad = option;
|
keypad_mode = keypad_mode_option;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ CalcOptions::SaveSettings(BMessage* archive) const
|
|||||||
ret = archive->AddBool("audio feedback", audio_feedback);
|
ret = archive->AddBool("audio feedback", audio_feedback);
|
||||||
|
|
||||||
if (ret == B_OK)
|
if (ret == B_OK)
|
||||||
ret = archive->AddBool("show keypad", show_keypad);
|
ret = archive->AddUInt8("keypad mode", keypad_mode);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,18 @@
|
|||||||
|
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
KEYPAD_MODE_COMPACT,
|
||||||
|
KEYPAD_MODE_BASIC,
|
||||||
|
KEYPAD_MODE_SCIENTIFIC
|
||||||
|
};
|
||||||
|
|
||||||
class BMessage;
|
class BMessage;
|
||||||
|
|
||||||
struct CalcOptions {
|
struct CalcOptions {
|
||||||
bool auto_num_lock; // automatically activate numlock
|
bool auto_num_lock; // automatically activate numlock
|
||||||
bool audio_feedback; // provide audio feedback
|
bool audio_feedback; // provide audio feedback
|
||||||
bool show_keypad; // show or hide the buttons
|
uint8 keypad_mode; // keypad mode options
|
||||||
|
|
||||||
CalcOptions();
|
CalcOptions();
|
||||||
|
|
||||||
|
|||||||
+234
-94
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2009, Haiku, Inc. All rights reserved.
|
* Copyright 2006-2011, Haiku, Inc. All rights reserved.
|
||||||
* Copyright 1997, 1998 R3 Software Ltd. All Rights Reserved.
|
* Copyright 1997, 1998 R3 Software Ltd. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
@@ -54,21 +54,36 @@ const float kDisplayScaleY = 0.2f;
|
|||||||
|
|
||||||
static const bigtime_t kFlashOnOffInterval = 100000;
|
static const bigtime_t kFlashOnOffInterval = 100000;
|
||||||
|
|
||||||
enum {
|
static const float kMinimumWidthCompact = 130.0f;
|
||||||
MSG_OPTIONS_AUTO_NUM_LOCK = 'opan',
|
static const float kMaximumWidthCompact = 400.0f;
|
||||||
MSG_OPTIONS_AUDIO_FEEDBACK = 'opaf',
|
static const float kMinimumHeightCompact = 20.0f;
|
||||||
MSG_OPTIONS_SHOW_KEYPAD = 'opsk',
|
static const float kMaximumHeightCompact = 60.0f;
|
||||||
|
|
||||||
MSG_UNFLASH_KEY = 'uflk'
|
// Basic mode size limits are defined in CalcView.h so
|
||||||
};
|
// that they can be used by the CalcWindow constructor.
|
||||||
|
|
||||||
// default calculator key pad layout
|
static const float kMinimumWidthScientific = 240.0f;
|
||||||
const char *kDefaultKeypadDescription =
|
static const float kMaximumWidthScientific = 400.0f;
|
||||||
|
static const float kMinimumHeightScientific = 200.0f;
|
||||||
|
static const float kMaximumHeightScientific = 400.0f;
|
||||||
|
|
||||||
|
// basic mode keypad layout (default)
|
||||||
|
const char *kKeypadDescriptionBasic =
|
||||||
"7 8 9 ( ) \n"
|
"7 8 9 ( ) \n"
|
||||||
"4 5 6 * / \n"
|
"4 5 6 * / \n"
|
||||||
"1 2 3 + - \n"
|
"1 2 3 + - \n"
|
||||||
"0 . BS = C \n";
|
"0 . BS = C \n";
|
||||||
|
|
||||||
|
// scientific mode keypad layout
|
||||||
|
const char *kKeypadDescriptionScientific =
|
||||||
|
"ln sin cos tan π \n"
|
||||||
|
"log asin acos atan sqrt \n"
|
||||||
|
"exp sinh cosh tanh cbrt \n"
|
||||||
|
"! ceil floor E ^ \n"
|
||||||
|
"7 8 9 ( ) \n"
|
||||||
|
"4 5 6 * / \n"
|
||||||
|
"1 2 3 + - \n"
|
||||||
|
"0 . BS = C \n";
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
FLAGS_FLASH_KEY = 1 << 0,
|
FLAGS_FLASH_KEY = 1 << 0,
|
||||||
@@ -98,7 +113,7 @@ CalcView::CalcView(BRect frame, rgb_color rgbBaseColor, BMessage* settings)
|
|||||||
:
|
:
|
||||||
BView(frame, "DeskCalc", B_FOLLOW_ALL_SIDES,
|
BView(frame, "DeskCalc", B_FOLLOW_ALL_SIDES,
|
||||||
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
|
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
|
||||||
fColums(5),
|
fColumns(5),
|
||||||
fRows(4),
|
fRows(4),
|
||||||
|
|
||||||
fBaseColor(rgbBaseColor),
|
fBaseColor(rgbBaseColor),
|
||||||
@@ -107,7 +122,7 @@ CalcView::CalcView(BRect frame, rgb_color rgbBaseColor, BMessage* settings)
|
|||||||
fWidth(1),
|
fWidth(1),
|
||||||
fHeight(1),
|
fHeight(1),
|
||||||
|
|
||||||
fKeypadDescription(strdup(kDefaultKeypadDescription)),
|
fKeypadDescription(strdup(kKeypadDescriptionBasic)),
|
||||||
fKeypad(NULL),
|
fKeypad(NULL),
|
||||||
|
|
||||||
#ifdef __HAIKU__
|
#ifdef __HAIKU__
|
||||||
@@ -119,14 +134,13 @@ CalcView::CalcView(BRect frame, rgb_color rgbBaseColor, BMessage* settings)
|
|||||||
fPopUpMenu(NULL),
|
fPopUpMenu(NULL),
|
||||||
fAutoNumlockItem(NULL),
|
fAutoNumlockItem(NULL),
|
||||||
fAudioFeedbackItem(NULL),
|
fAudioFeedbackItem(NULL),
|
||||||
fShowKeypadItem(NULL),
|
fOptions(new CalcOptions())
|
||||||
fOptions(new CalcOptions()),
|
|
||||||
fShowKeypad(true)
|
|
||||||
{
|
{
|
||||||
// create expression text view
|
// create expression text view
|
||||||
fExpressionTextView = new ExpressionTextView(_ExpressionRect(), this);
|
fExpressionTextView = new ExpressionTextView(_ExpressionRect(), this);
|
||||||
AddChild(fExpressionTextView);
|
AddChild(fExpressionTextView);
|
||||||
|
|
||||||
|
// read data from archive
|
||||||
_LoadSettings(settings);
|
_LoadSettings(settings);
|
||||||
|
|
||||||
// tell the app server not to erase our b/g
|
// tell the app server not to erase our b/g
|
||||||
@@ -141,6 +155,7 @@ CalcView::CalcView(BRect frame, rgb_color rgbBaseColor, BMessage* settings)
|
|||||||
// create pop-up menu system
|
// create pop-up menu system
|
||||||
_CreatePopUpMenu();
|
_CreatePopUpMenu();
|
||||||
|
|
||||||
|
// Fetch the calc icon for compact view
|
||||||
_FetchAppIcon(fCalcIcon);
|
_FetchAppIcon(fCalcIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +163,7 @@ CalcView::CalcView(BRect frame, rgb_color rgbBaseColor, BMessage* settings)
|
|||||||
CalcView::CalcView(BMessage* archive)
|
CalcView::CalcView(BMessage* archive)
|
||||||
:
|
:
|
||||||
BView(archive),
|
BView(archive),
|
||||||
fColums(5),
|
fColumns(5),
|
||||||
fRows(4),
|
fRows(4),
|
||||||
|
|
||||||
fBaseColor((rgb_color){ 128, 128, 128, 255 }),
|
fBaseColor((rgb_color){ 128, 128, 128, 255 }),
|
||||||
@@ -157,7 +172,7 @@ CalcView::CalcView(BMessage* archive)
|
|||||||
fWidth(1),
|
fWidth(1),
|
||||||
fHeight(1),
|
fHeight(1),
|
||||||
|
|
||||||
fKeypadDescription(strdup(kDefaultKeypadDescription)),
|
fKeypadDescription(strdup(kKeypadDescriptionBasic)),
|
||||||
fKeypad(NULL),
|
fKeypad(NULL),
|
||||||
|
|
||||||
#ifdef __HAIKU__
|
#ifdef __HAIKU__
|
||||||
@@ -169,9 +184,7 @@ CalcView::CalcView(BMessage* archive)
|
|||||||
fPopUpMenu(NULL),
|
fPopUpMenu(NULL),
|
||||||
fAutoNumlockItem(NULL),
|
fAutoNumlockItem(NULL),
|
||||||
fAudioFeedbackItem(NULL),
|
fAudioFeedbackItem(NULL),
|
||||||
fShowKeypadItem(NULL),
|
fOptions(new CalcOptions())
|
||||||
fOptions(new CalcOptions()),
|
|
||||||
fShowKeypad(true)
|
|
||||||
{
|
{
|
||||||
// Do not restore the follow mode, in shelfs, we never follow.
|
// Do not restore the follow mode, in shelfs, we never follow.
|
||||||
SetResizingMode(B_FOLLOW_NONE);
|
SetResizingMode(B_FOLLOW_NONE);
|
||||||
@@ -182,12 +195,11 @@ CalcView::CalcView(BMessage* archive)
|
|||||||
|
|
||||||
// read data from archive
|
// read data from archive
|
||||||
_LoadSettings(archive);
|
_LoadSettings(archive);
|
||||||
// replicant means size and window limit dont need changes
|
|
||||||
fShowKeypad = fOptions->show_keypad;
|
|
||||||
|
|
||||||
// create pop-up menu system
|
// create pop-up menu system
|
||||||
_CreatePopUpMenu();
|
_CreatePopUpMenu();
|
||||||
|
|
||||||
|
// Fetch the calc icon for compact view
|
||||||
_FetchAppIcon(fCalcIcon);
|
_FetchAppIcon(fCalcIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,8 +221,7 @@ CalcView::AttachedToWindow()
|
|||||||
BRect frame(Frame());
|
BRect frame(Frame());
|
||||||
FrameResized(frame.Width(), frame.Height());
|
FrameResized(frame.Width(), frame.Height());
|
||||||
|
|
||||||
fPopUpMenu->SetTargetForItems(this);
|
SetKeypadMode(fOptions->keypad_mode);
|
||||||
_ShowKeypad(fOptions->show_keypad);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -254,22 +265,6 @@ CalcView::MessageReceived(BMessage* message)
|
|||||||
AboutRequested();
|
AboutRequested();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSG_OPTIONS_AUTO_NUM_LOCK:
|
|
||||||
fOptions->auto_num_lock = !fOptions->auto_num_lock;
|
|
||||||
fAutoNumlockItem->SetMarked(fOptions->auto_num_lock);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MSG_OPTIONS_AUDIO_FEEDBACK:
|
|
||||||
fOptions->audio_feedback = !fOptions->audio_feedback;
|
|
||||||
fAudioFeedbackItem->SetMarked(fOptions->audio_feedback);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MSG_OPTIONS_SHOW_KEYPAD:
|
|
||||||
fOptions->show_keypad = !fOptions->show_keypad;
|
|
||||||
fShowKeypadItem->SetMarked(fOptions->show_keypad);
|
|
||||||
_ShowKeypad(fOptions->show_keypad);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MSG_UNFLASH_KEY:
|
case MSG_UNFLASH_KEY:
|
||||||
{
|
{
|
||||||
int32 key;
|
int32 key;
|
||||||
@@ -299,7 +294,7 @@ CalcView::Draw(BRect updateRect)
|
|||||||
SetHighColor(fBaseColor);
|
SetHighColor(fBaseColor);
|
||||||
BRect expressionRect(_ExpressionRect());
|
BRect expressionRect(_ExpressionRect());
|
||||||
if (updateRect.Intersects(expressionRect)) {
|
if (updateRect.Intersects(expressionRect)) {
|
||||||
if (!fShowKeypad
|
if (fOptions->keypad_mode == KEYPAD_MODE_COMPACT
|
||||||
&& expressionRect.Height() >= fCalcIcon->Bounds().Height()) {
|
&& expressionRect.Height() >= fCalcIcon->Bounds().Height()) {
|
||||||
// render calc icon
|
// render calc icon
|
||||||
expressionRect.left = fExpressionTextView->Frame().right + 2;
|
expressionRect.left = fExpressionTextView->Frame().right + 2;
|
||||||
@@ -328,7 +323,7 @@ CalcView::Draw(BRect updateRect)
|
|||||||
// render border around expression text view
|
// render border around expression text view
|
||||||
expressionRect = fExpressionTextView->Frame();
|
expressionRect = fExpressionTextView->Frame();
|
||||||
expressionRect.InsetBy(-2, -2);
|
expressionRect.InsetBy(-2, -2);
|
||||||
if (fShowKeypad && drawBackground) {
|
if (fOptions->keypad_mode != KEYPAD_MODE_COMPACT && drawBackground) {
|
||||||
expressionRect.InsetBy(-2, -2);
|
expressionRect.InsetBy(-2, -2);
|
||||||
StrokeRect(expressionRect);
|
StrokeRect(expressionRect);
|
||||||
expressionRect.InsetBy(1, 1);
|
expressionRect.InsetBy(1, 1);
|
||||||
@@ -379,7 +374,7 @@ CalcView::Draw(BRect updateRect)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fShowKeypad)
|
if (fOptions->keypad_mode == KEYPAD_MODE_COMPACT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// calculate grid sizes
|
// calculate grid sizes
|
||||||
@@ -392,7 +387,7 @@ CalcView::Draw(BRect updateRect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
float sizeDisp = keypadRect.top;
|
float sizeDisp = keypadRect.top;
|
||||||
float sizeCol = (keypadRect.Width() + 1) / (float)fColums;
|
float sizeCol = (keypadRect.Width() + 1) / (float)fColumns;
|
||||||
float sizeRow = (keypadRect.Height() + 1) / (float)fRows;
|
float sizeRow = (keypadRect.Height() + 1) / (float)fRows;
|
||||||
|
|
||||||
if (!updateRect.Intersects(keypadRect))
|
if (!updateRect.Intersects(keypadRect))
|
||||||
@@ -403,7 +398,7 @@ CalcView::Draw(BRect updateRect)
|
|||||||
if (be_control_look != NULL) {
|
if (be_control_look != NULL) {
|
||||||
CalcKey* key = fKeypad;
|
CalcKey* key = fKeypad;
|
||||||
for (int row = 0; row < fRows; row++) {
|
for (int row = 0; row < fRows; row++) {
|
||||||
for (int col = 0; col < fColums; col++) {
|
for (int col = 0; col < fColumns; col++) {
|
||||||
BRect frame;
|
BRect frame;
|
||||||
frame.left = keypadRect.left + col * sizeCol;
|
frame.left = keypadRect.left + col * sizeCol;
|
||||||
frame.right = keypadRect.left + (col + 1) * sizeCol - 1;
|
frame.right = keypadRect.left + (col + 1) * sizeCol - 1;
|
||||||
@@ -445,13 +440,13 @@ CalcView::Draw(BRect updateRect)
|
|||||||
FillRect(updateRect & keypadRect);
|
FillRect(updateRect & keypadRect);
|
||||||
|
|
||||||
// render key main grid
|
// render key main grid
|
||||||
BeginLineArray(((fColums + fRows) << 1) + 1);
|
BeginLineArray(((fColumns + fRows) << 1) + 1);
|
||||||
|
|
||||||
// render cols
|
// render cols
|
||||||
AddLine(BPoint(0.0, sizeDisp),
|
AddLine(BPoint(0.0, sizeDisp),
|
||||||
BPoint(0.0, fHeight),
|
BPoint(0.0, fHeight),
|
||||||
fLightColor);
|
fLightColor);
|
||||||
for (int col = 1; col < fColums; col++) {
|
for (int col = 1; col < fColumns; col++) {
|
||||||
AddLine(BPoint(col * sizeCol - 1.0, sizeDisp),
|
AddLine(BPoint(col * sizeCol - 1.0, sizeDisp),
|
||||||
BPoint(col * sizeCol - 1.0, fHeight),
|
BPoint(col * sizeCol - 1.0, fHeight),
|
||||||
fDarkColor);
|
fDarkColor);
|
||||||
@@ -459,8 +454,8 @@ CalcView::Draw(BRect updateRect)
|
|||||||
BPoint(col * sizeCol, fHeight),
|
BPoint(col * sizeCol, fHeight),
|
||||||
fLightColor);
|
fLightColor);
|
||||||
}
|
}
|
||||||
AddLine(BPoint(fColums * sizeCol, sizeDisp),
|
AddLine(BPoint(fColumns * sizeCol, sizeDisp),
|
||||||
BPoint(fColums * sizeCol, fHeight),
|
BPoint(fColumns * sizeCol, fHeight),
|
||||||
fDarkColor);
|
fDarkColor);
|
||||||
|
|
||||||
// render rows
|
// render rows
|
||||||
@@ -489,7 +484,7 @@ CalcView::Draw(BRect updateRect)
|
|||||||
* (1.0 - kFontScaleY) * 0.5;
|
* (1.0 - kFontScaleY) * 0.5;
|
||||||
CalcKey* key = fKeypad;
|
CalcKey* key = fKeypad;
|
||||||
for (int row = 0; row < fRows; row++) {
|
for (int row = 0; row < fRows; row++) {
|
||||||
for (int col = 0; col < fColums; col++) {
|
for (int col = 0; col < fColumns; col++) {
|
||||||
float halfSymbolWidth = StringWidth(key->label) * 0.5f;
|
float halfSymbolWidth = StringWidth(key->label) * 0.5f;
|
||||||
DrawString(key->label,
|
DrawString(key->label,
|
||||||
BPoint(col * sizeCol + halfSizeCol - halfSymbolWidth,
|
BPoint(col * sizeCol + halfSizeCol - halfSymbolWidth,
|
||||||
@@ -524,7 +519,7 @@ CalcView::MouseDown(BPoint point)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fShowKeypad) {
|
if (fOptions->keypad_mode == KEYPAD_MODE_COMPACT) {
|
||||||
if (fCalcIcon != NULL) {
|
if (fCalcIcon != NULL) {
|
||||||
BRect bounds(Bounds());
|
BRect bounds(Bounds());
|
||||||
bounds.left = bounds.right - fCalcIcon->Bounds().Width();
|
bounds.left = bounds.right - fCalcIcon->Bounds().Width();
|
||||||
@@ -538,7 +533,7 @@ CalcView::MouseDown(BPoint point)
|
|||||||
|
|
||||||
// calculate grid sizes
|
// calculate grid sizes
|
||||||
float sizeDisp = fHeight * kDisplayScaleY;
|
float sizeDisp = fHeight * kDisplayScaleY;
|
||||||
float sizeCol = fWidth / (float)fColums;
|
float sizeCol = fWidth / (float)fColumns;
|
||||||
float sizeRow = (fHeight - sizeDisp) / (float)fRows;
|
float sizeRow = (fHeight - sizeDisp) / (float)fRows;
|
||||||
|
|
||||||
// calculate location within grid
|
// calculate location within grid
|
||||||
@@ -546,11 +541,11 @@ CalcView::MouseDown(BPoint point)
|
|||||||
int gridRow = (int)floorf((point.y - sizeDisp) / sizeRow);
|
int gridRow = (int)floorf((point.y - sizeDisp) / sizeRow);
|
||||||
|
|
||||||
// check limits
|
// check limits
|
||||||
if ((gridCol >= 0) && (gridCol < fColums)
|
if ((gridCol >= 0) && (gridCol < fColumns)
|
||||||
&& (gridRow >= 0) && (gridRow < fRows)) {
|
&& (gridRow >= 0) && (gridRow < fRows)) {
|
||||||
|
|
||||||
// process key press
|
// process key press
|
||||||
int key = gridRow * fColums + gridCol;
|
int key = gridRow * fColumns + gridCol;
|
||||||
_FlashKey(key, FLAGS_MOUSE_DOWN);
|
_FlashKey(key, FLAGS_MOUSE_DOWN);
|
||||||
_PressKey(key);
|
_PressKey(key);
|
||||||
|
|
||||||
@@ -563,10 +558,10 @@ CalcView::MouseDown(BPoint point)
|
|||||||
void
|
void
|
||||||
CalcView::MouseUp(BPoint point)
|
CalcView::MouseUp(BPoint point)
|
||||||
{
|
{
|
||||||
if (!fShowKeypad)
|
if (fOptions->keypad_mode == KEYPAD_MODE_COMPACT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int keys = fRows * fColums;
|
int keys = fRows * fColumns;
|
||||||
for (int i = 0; i < keys; i++) {
|
for (int i = 0; i < keys; i++) {
|
||||||
if (fKeypad[i].flags & FLAGS_MOUSE_DOWN) {
|
if (fKeypad[i].flags & FLAGS_MOUSE_DOWN) {
|
||||||
_FlashKey(i, 0);
|
_FlashKey(i, 0);
|
||||||
@@ -617,7 +612,7 @@ CalcView::KeyDown(const char* bytes, int32 numBytes)
|
|||||||
|
|
||||||
default: {
|
default: {
|
||||||
// scan the keymap array for match
|
// scan the keymap array for match
|
||||||
int keys = fRows * fColums;
|
int keys = fRows * fColumns;
|
||||||
for (int i = 0; i < keys; i++) {
|
for (int i = 0; i < keys; i++) {
|
||||||
if (fKeypad[i].keymap[0] == bytes[0]) {
|
if (fKeypad[i].keymap[0] == bytes[0]) {
|
||||||
_PressKey(i);
|
_PressKey(i);
|
||||||
@@ -647,6 +642,14 @@ CalcView::MakeFocus(bool focused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CalcView::ResizeTo(float width, float height)
|
||||||
|
{
|
||||||
|
BView::ResizeTo(width, height);
|
||||||
|
FrameResized(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CalcView::FrameResized(float width, float height)
|
CalcView::FrameResized(float width, float height)
|
||||||
{
|
{
|
||||||
@@ -655,19 +658,18 @@ CalcView::FrameResized(float width, float height)
|
|||||||
|
|
||||||
// layout expression text view
|
// layout expression text view
|
||||||
BRect frame = _ExpressionRect();
|
BRect frame = _ExpressionRect();
|
||||||
if (fShowKeypad)
|
if (fOptions->keypad_mode == KEYPAD_MODE_COMPACT) {
|
||||||
frame.InsetBy(4, 4);
|
|
||||||
else
|
|
||||||
frame.InsetBy(2, 2);
|
frame.InsetBy(2, 2);
|
||||||
|
|
||||||
if (!fShowKeypad)
|
|
||||||
frame.right -= ceilf(fCalcIcon->Bounds().Width() * 1.5);
|
frame.right -= ceilf(fCalcIcon->Bounds().Width() * 1.5);
|
||||||
|
} else
|
||||||
|
frame.InsetBy(4, 4);
|
||||||
|
|
||||||
fExpressionTextView->MoveTo(frame.LeftTop());
|
fExpressionTextView->MoveTo(frame.LeftTop());
|
||||||
fExpressionTextView->ResizeTo(frame.Width(), frame.Height());
|
fExpressionTextView->ResizeTo(frame.Width(), frame.Height());
|
||||||
|
|
||||||
// configure expression text view font size and color
|
// configure expression text view font size and color
|
||||||
float sizeDisp = fShowKeypad ? fHeight * kDisplayScaleY : fHeight;
|
float sizeDisp = fOptions->keypad_mode == KEYPAD_MODE_COMPACT
|
||||||
|
? fHeight : fHeight * kDisplayScaleY;
|
||||||
BFont font(be_bold_font);
|
BFont font(be_bold_font);
|
||||||
font.SetSize(sizeDisp * kExpressionFontScaleY);
|
font.SetSize(sizeDisp * kExpressionFontScaleY);
|
||||||
fExpressionTextView->SetFontAndColor(&font, B_FONT_ALL);
|
fExpressionTextView->SetFontAndColor(&font, B_FONT_ALL);
|
||||||
@@ -797,15 +799,15 @@ CalcView::_LoadSettings(BMessage* archive)
|
|||||||
// record calculator description
|
// record calculator description
|
||||||
const char* calcDesc;
|
const char* calcDesc;
|
||||||
if (archive->FindString("calcDesc", &calcDesc) < B_OK)
|
if (archive->FindString("calcDesc", &calcDesc) < B_OK)
|
||||||
calcDesc = kDefaultKeypadDescription;
|
calcDesc = kKeypadDescriptionBasic;
|
||||||
|
|
||||||
// save calculator description for reference
|
// save calculator description for reference
|
||||||
free(fKeypadDescription);
|
free(fKeypadDescription);
|
||||||
fKeypadDescription = strdup(calcDesc);
|
fKeypadDescription = strdup(calcDesc);
|
||||||
|
|
||||||
// read grid dimensions
|
// read grid dimensions
|
||||||
if (archive->FindInt16("cols", &fColums) < B_OK)
|
if (archive->FindInt16("cols", &fColumns) < B_OK)
|
||||||
fColums = 5;
|
fColumns = 5;
|
||||||
if (archive->FindInt16("rows", &fRows) < B_OK)
|
if (archive->FindInt16("rows", &fRows) < B_OK)
|
||||||
fRows = 4;
|
fRows = 4;
|
||||||
|
|
||||||
@@ -862,7 +864,7 @@ CalcView::SaveSettings(BMessage* archive) const
|
|||||||
|
|
||||||
// record grid dimensions
|
// record grid dimensions
|
||||||
if (ret == B_OK)
|
if (ret == B_OK)
|
||||||
ret = archive->AddInt16("cols", fColums);
|
ret = archive->AddInt16("cols", fColumns);
|
||||||
if (ret == B_OK)
|
if (ret == B_OK)
|
||||||
ret = archive->AddInt16("rows", fRows);
|
ret = archive->AddInt16("rows", fRows);
|
||||||
|
|
||||||
@@ -935,6 +937,97 @@ CalcView::FlashKey(const char* bytes, int32 numBytes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CalcView::ToggleAutoNumlock(void)
|
||||||
|
{
|
||||||
|
fOptions->auto_num_lock = !fOptions->auto_num_lock;
|
||||||
|
fAutoNumlockItem->SetMarked(fOptions->auto_num_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CalcView::ToggleAudioFeedback(void)
|
||||||
|
{
|
||||||
|
fOptions->audio_feedback = !fOptions->audio_feedback;
|
||||||
|
fAudioFeedbackItem->SetMarked(fOptions->audio_feedback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CalcView::SetKeypadMode(uint8 mode)
|
||||||
|
{
|
||||||
|
if (fOptions->keypad_mode == mode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BWindow* window = Window();
|
||||||
|
if (window == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fOptions->keypad_mode = mode;
|
||||||
|
_MarkKeypadItems(fOptions->keypad_mode);
|
||||||
|
|
||||||
|
float width = fWidth;
|
||||||
|
float height = fHeight;
|
||||||
|
|
||||||
|
switch (fOptions->keypad_mode) {
|
||||||
|
case KEYPAD_MODE_COMPACT:
|
||||||
|
{
|
||||||
|
if (window->Bounds() == Frame()) {
|
||||||
|
window->SetSizeLimits(kMinimumWidthCompact,
|
||||||
|
kMaximumWidthCompact,
|
||||||
|
kMinimumHeightCompact,
|
||||||
|
kMaximumHeightCompact);
|
||||||
|
window->ResizeTo(width, height * kDisplayScaleY);
|
||||||
|
} else
|
||||||
|
ResizeTo(width, height * kDisplayScaleY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case KEYPAD_MODE_SCIENTIFIC:
|
||||||
|
{
|
||||||
|
free(fKeypadDescription);
|
||||||
|
fKeypadDescription = strdup(kKeypadDescriptionScientific);
|
||||||
|
fRows = 8;
|
||||||
|
_ParseCalcDesc(fKeypadDescription);
|
||||||
|
|
||||||
|
window->SetSizeLimits(kMinimumWidthScientific,
|
||||||
|
kMaximumWidthScientific,
|
||||||
|
kMinimumHeightScientific,
|
||||||
|
kMaximumHeightScientific);
|
||||||
|
if (width < kMinimumWidthScientific)
|
||||||
|
width = kMinimumWidthScientific;
|
||||||
|
if (width > kMaximumWidthScientific)
|
||||||
|
width = kMaximumWidthScientific;
|
||||||
|
if (height < kMinimumHeightScientific)
|
||||||
|
height = kMinimumHeightScientific;
|
||||||
|
if (height > kMaximumHeightScientific)
|
||||||
|
height = kMaximumHeightScientific;
|
||||||
|
ResizeTo(width, height);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: // KEYPAD_MODE_BASIC is the default
|
||||||
|
{
|
||||||
|
free(fKeypadDescription);
|
||||||
|
fKeypadDescription = strdup(kKeypadDescriptionBasic);
|
||||||
|
fRows = 4;
|
||||||
|
_ParseCalcDesc(fKeypadDescription);
|
||||||
|
|
||||||
|
window->SetSizeLimits(kMinimumWidthBasic, kMaximumWidthBasic,
|
||||||
|
kMinimumHeightBasic, kMaximumHeightBasic);
|
||||||
|
if (width < kMinimumWidthBasic)
|
||||||
|
width = kMinimumWidthBasic;
|
||||||
|
if (width > kMaximumWidthBasic)
|
||||||
|
width = kMaximumWidthBasic;
|
||||||
|
if (height < kMinimumHeightBasic)
|
||||||
|
height = kMinimumHeightBasic;
|
||||||
|
if (height > kMaximumHeightBasic)
|
||||||
|
height = kMaximumHeightBasic;
|
||||||
|
ResizeTo(width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -942,7 +1035,7 @@ void
|
|||||||
CalcView::_ParseCalcDesc(const char* keypadDescription)
|
CalcView::_ParseCalcDesc(const char* keypadDescription)
|
||||||
{
|
{
|
||||||
// TODO: should calculate dimensions from desc here!
|
// TODO: should calculate dimensions from desc here!
|
||||||
fKeypad = new CalcKey[fRows * fColums];
|
fKeypad = new CalcKey[fRows * fColumns];
|
||||||
|
|
||||||
// scan through calculator description and assemble keypad
|
// scan through calculator description and assemble keypad
|
||||||
CalcKey* key = fKeypad;
|
CalcKey* key = fKeypad;
|
||||||
@@ -984,15 +1077,56 @@ CalcView::_ParseCalcDesc(const char* keypadDescription)
|
|||||||
void
|
void
|
||||||
CalcView::_PressKey(int key)
|
CalcView::_PressKey(int key)
|
||||||
{
|
{
|
||||||
assert(key < (fRows * fColums));
|
assert(key < (fRows * fColumns));
|
||||||
assert(key >= 0);
|
assert(key >= 0);
|
||||||
|
|
||||||
// check for backspace
|
|
||||||
if (strcmp(fKeypad[key].label, "BS") == 0) {
|
if (strcmp(fKeypad[key].label, "BS") == 0) {
|
||||||
|
// BS means backspace
|
||||||
fExpressionTextView->BackSpace();
|
fExpressionTextView->BackSpace();
|
||||||
} else if (strcmp(fKeypad[key].label, "C") == 0) {
|
} else if (strcmp(fKeypad[key].label, "C") == 0) {
|
||||||
// C means clear
|
// C means clear
|
||||||
fExpressionTextView->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 {
|
} else {
|
||||||
// check for evaluation order
|
// check for evaluation order
|
||||||
if (fKeypad[key].code[0] == '\n') {
|
if (fKeypad[key].code[0] == '\n') {
|
||||||
@@ -1019,7 +1153,7 @@ CalcView::_PressKey(const char* label)
|
|||||||
int32
|
int32
|
||||||
CalcView::_KeyForLabel(const char* label) const
|
CalcView::_KeyForLabel(const char* label) const
|
||||||
{
|
{
|
||||||
int keys = fRows * fColums;
|
int keys = fRows * fColumns;
|
||||||
for (int i = 0; i < keys; i++) {
|
for (int i = 0; i < keys; i++) {
|
||||||
if (strcmp(fKeypad[i].label, label) == 0) {
|
if (strcmp(fKeypad[i].label, label) == 0) {
|
||||||
return i;
|
return i;
|
||||||
@@ -1032,7 +1166,7 @@ CalcView::_KeyForLabel(const char* label) const
|
|||||||
void
|
void
|
||||||
CalcView::_FlashKey(int32 key, uint32 flashFlags)
|
CalcView::_FlashKey(int32 key, uint32 flashFlags)
|
||||||
{
|
{
|
||||||
if (!fShowKeypad)
|
if (fOptions->keypad_mode == KEYPAD_MODE_COMPACT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (flashFlags != 0)
|
if (flashFlags != 0)
|
||||||
@@ -1105,13 +1239,17 @@ CalcView::_CreatePopUpMenu()
|
|||||||
new BMessage(MSG_OPTIONS_AUTO_NUM_LOCK));
|
new BMessage(MSG_OPTIONS_AUTO_NUM_LOCK));
|
||||||
fAudioFeedbackItem = new BMenuItem(B_TRANSLATE("Audio Feedback"),
|
fAudioFeedbackItem = new BMenuItem(B_TRANSLATE("Audio Feedback"),
|
||||||
new BMessage(MSG_OPTIONS_AUDIO_FEEDBACK));
|
new BMessage(MSG_OPTIONS_AUDIO_FEEDBACK));
|
||||||
fShowKeypadItem = new BMenuItem(B_TRANSLATE("Show keypad"),
|
fKeypadModeCompactItem = new BMenuItem(B_TRANSLATE("Compact"),
|
||||||
new BMessage(MSG_OPTIONS_SHOW_KEYPAD));
|
new BMessage(MSG_OPTIONS_KEYPAD_MODE_COMPACT), '0');
|
||||||
|
fKeypadModeBasicItem = new BMenuItem(B_TRANSLATE("Basic"),
|
||||||
|
new BMessage(MSG_OPTIONS_KEYPAD_MODE_BASIC), '1');
|
||||||
|
fKeypadModeScientificItem = new BMenuItem(B_TRANSLATE("Scientific"),
|
||||||
|
new BMessage(MSG_OPTIONS_KEYPAD_MODE_SCIENTIFIC), '2');
|
||||||
|
|
||||||
// apply current settings
|
// apply current settings
|
||||||
fAutoNumlockItem->SetMarked(fOptions->auto_num_lock);
|
fAutoNumlockItem->SetMarked(fOptions->auto_num_lock);
|
||||||
fAudioFeedbackItem->SetMarked(fOptions->audio_feedback);
|
fAudioFeedbackItem->SetMarked(fOptions->audio_feedback);
|
||||||
fShowKeypadItem->SetMarked(fOptions->show_keypad);
|
_MarkKeypadItems(fOptions->keypad_mode);
|
||||||
|
|
||||||
// construct menu
|
// construct menu
|
||||||
fPopUpMenu = new BPopUpMenu("pop-up", false, false);
|
fPopUpMenu = new BPopUpMenu("pop-up", false, false);
|
||||||
@@ -1120,7 +1258,10 @@ CalcView::_CreatePopUpMenu()
|
|||||||
// TODO: Enabled when we use beep events which can be configured in the Sounds
|
// TODO: Enabled when we use beep events which can be configured in the Sounds
|
||||||
// preflet.
|
// preflet.
|
||||||
// fPopUpMenu->AddItem(fAudioFeedbackItem);
|
// fPopUpMenu->AddItem(fAudioFeedbackItem);
|
||||||
fPopUpMenu->AddItem(fShowKeypadItem);
|
fPopUpMenu->AddSeparatorItem();
|
||||||
|
fPopUpMenu->AddItem(fKeypadModeCompactItem);
|
||||||
|
fPopUpMenu->AddItem(fKeypadModeBasicItem);
|
||||||
|
fPopUpMenu->AddItem(fKeypadModeScientificItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1128,7 +1269,7 @@ BRect
|
|||||||
CalcView::_ExpressionRect() const
|
CalcView::_ExpressionRect() const
|
||||||
{
|
{
|
||||||
BRect r(0.0, 0.0, fWidth, fHeight);
|
BRect r(0.0, 0.0, fWidth, fHeight);
|
||||||
if (fShowKeypad) {
|
if (fOptions->keypad_mode != KEYPAD_MODE_COMPACT) {
|
||||||
r.bottom = floorf(fHeight * kDisplayScaleY) + 1;
|
r.bottom = floorf(fHeight * kDisplayScaleY) + 1;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
@@ -1139,7 +1280,7 @@ BRect
|
|||||||
CalcView::_KeypadRect() const
|
CalcView::_KeypadRect() const
|
||||||
{
|
{
|
||||||
BRect r(0.0, 0.0, -1.0, -1.0);
|
BRect r(0.0, 0.0, -1.0, -1.0);
|
||||||
if (fShowKeypad) {
|
if (fOptions->keypad_mode != KEYPAD_MODE_COMPACT) {
|
||||||
r.right = fWidth;
|
r.right = fWidth;
|
||||||
r.bottom = fHeight;
|
r.bottom = fHeight;
|
||||||
r.top = floorf(fHeight * kDisplayScaleY);
|
r.top = floorf(fHeight * kDisplayScaleY);
|
||||||
@@ -1149,26 +1290,25 @@ CalcView::_KeypadRect() const
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CalcView::_ShowKeypad(bool show)
|
CalcView::_MarkKeypadItems(uint8 keypad_mode)
|
||||||
{
|
{
|
||||||
if (fShowKeypad == show)
|
switch (keypad_mode) {
|
||||||
return;
|
case KEYPAD_MODE_COMPACT:
|
||||||
|
fKeypadModeCompactItem->SetMarked(true);
|
||||||
|
fKeypadModeBasicItem->SetMarked(false);
|
||||||
|
fKeypadModeScientificItem->SetMarked(false);
|
||||||
|
break;
|
||||||
|
|
||||||
fShowKeypad = show;
|
case KEYPAD_MODE_SCIENTIFIC:
|
||||||
if (fShowKeypadItem && fShowKeypadItem->IsMarked() ^ fShowKeypad)
|
fKeypadModeCompactItem->SetMarked(false);
|
||||||
fShowKeypadItem->SetMarked(fShowKeypad);
|
fKeypadModeBasicItem->SetMarked(false);
|
||||||
|
fKeypadModeScientificItem->SetMarked(true);
|
||||||
|
break;
|
||||||
|
|
||||||
float height
|
default: // KEYPAD_MODE_BASIC is the default
|
||||||
= fShowKeypad ? fHeight / kDisplayScaleY : fHeight * kDisplayScaleY;
|
fKeypadModeCompactItem->SetMarked(false);
|
||||||
|
fKeypadModeBasicItem->SetMarked(true);
|
||||||
BWindow* window = Window();
|
fKeypadModeScientificItem->SetMarked(false);
|
||||||
if (window) {
|
|
||||||
if (window->Bounds() == Frame()) {
|
|
||||||
window->SetSizeLimits(100.0, 400.0,
|
|
||||||
fShowKeypad ? 100.0 : 20.0, fShowKeypad ? 400.0 : 60.0);
|
|
||||||
window->ResizeTo(fWidth, height);
|
|
||||||
} else
|
|
||||||
ResizeTo(fWidth, height);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,20 @@
|
|||||||
|
|
||||||
#include <View.h>
|
#include <View.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MSG_OPTIONS_AUTO_NUM_LOCK = 'oanl',
|
||||||
|
MSG_OPTIONS_AUDIO_FEEDBACK = 'oafb',
|
||||||
|
MSG_OPTIONS_KEYPAD_MODE_COMPACT = 'okmc',
|
||||||
|
MSG_OPTIONS_KEYPAD_MODE_BASIC = 'okmb',
|
||||||
|
MSG_OPTIONS_KEYPAD_MODE_SCIENTIFIC = 'okms',
|
||||||
|
MSG_UNFLASH_KEY = 'uflk'
|
||||||
|
};
|
||||||
|
|
||||||
|
static const float kMinimumWidthBasic = 130.0f;
|
||||||
|
static const float kMaximumWidthBasic = 400.0f;
|
||||||
|
static const float kMinimumHeightBasic = 130.0f;
|
||||||
|
static const float kMaximumHeightBasic = 400.0f;
|
||||||
|
|
||||||
class BString;
|
class BString;
|
||||||
class BMenuItem;
|
class BMenuItem;
|
||||||
class BPopUpMenu;
|
class BPopUpMenu;
|
||||||
@@ -42,6 +56,7 @@ class CalcView : public BView {
|
|||||||
virtual void MouseUp(BPoint point);
|
virtual void MouseUp(BPoint point);
|
||||||
virtual void KeyDown(const char* bytes, int32 numBytes);
|
virtual void KeyDown(const char* bytes, int32 numBytes);
|
||||||
virtual void MakeFocus(bool focused = true);
|
virtual void MakeFocus(bool focused = true);
|
||||||
|
virtual void ResizeTo(float width, float height);
|
||||||
virtual void FrameResized(float width, float height);
|
virtual void FrameResized(float width, float height);
|
||||||
|
|
||||||
// Present about box for view (replicant).
|
// Present about box for view (replicant).
|
||||||
@@ -62,10 +77,22 @@ class CalcView : public BView {
|
|||||||
// Save current settings
|
// Save current settings
|
||||||
status_t SaveSettings(BMessage* archive) const;
|
status_t SaveSettings(BMessage* archive) const;
|
||||||
|
|
||||||
|
// Evaluate the expression
|
||||||
void Evaluate();
|
void Evaluate();
|
||||||
|
|
||||||
|
// Flash the key on the keypad
|
||||||
void FlashKey(const char* bytes, int32 numBytes);
|
void FlashKey(const char* bytes, int32 numBytes);
|
||||||
|
|
||||||
|
// Toggle whether or not the Num Lock key starts on
|
||||||
|
void ToggleAutoNumlock(void);
|
||||||
|
|
||||||
|
// Toggle whether or not to provide audio feedback
|
||||||
|
// (option currently disabled)
|
||||||
|
void ToggleAudioFeedback(void);
|
||||||
|
|
||||||
|
// Set the keypad mode
|
||||||
|
void SetKeypadMode(uint8 mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _ParseCalcDesc(const char* keypadDescription);
|
void _ParseCalcDesc(const char* keypadDescription);
|
||||||
|
|
||||||
@@ -82,13 +109,14 @@ class CalcView : public BView {
|
|||||||
BRect _ExpressionRect() const;
|
BRect _ExpressionRect() const;
|
||||||
BRect _KeypadRect() const;
|
BRect _KeypadRect() const;
|
||||||
|
|
||||||
void _ShowKeypad(bool show);
|
void _MarkKeypadItems(uint8 mode);
|
||||||
|
|
||||||
void _FetchAppIcon(BBitmap* into);
|
void _FetchAppIcon(BBitmap* into);
|
||||||
|
|
||||||
status_t _LoadSettings(BMessage* archive);
|
status_t _LoadSettings(BMessage* archive);
|
||||||
|
|
||||||
// grid dimensions
|
// grid dimensions
|
||||||
int16 fColums;
|
int16 fColumns;
|
||||||
int16 fRows;
|
int16 fRows;
|
||||||
|
|
||||||
// color scheme
|
// color scheme
|
||||||
@@ -119,11 +147,12 @@ class CalcView : public BView {
|
|||||||
BPopUpMenu* fPopUpMenu;
|
BPopUpMenu* fPopUpMenu;
|
||||||
BMenuItem* fAutoNumlockItem;
|
BMenuItem* fAutoNumlockItem;
|
||||||
BMenuItem* fAudioFeedbackItem;
|
BMenuItem* fAudioFeedbackItem;
|
||||||
BMenuItem* fShowKeypadItem;
|
BMenuItem* fKeypadModeCompactItem;
|
||||||
|
BMenuItem* fKeypadModeBasicItem;
|
||||||
|
BMenuItem* fKeypadModeScientificItem;
|
||||||
|
|
||||||
// calculator options.
|
// calculator options.
|
||||||
CalcOptions* fOptions;
|
CalcOptions* fOptions;
|
||||||
bool fShowKeypad;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _CALC_VIEW_H
|
#endif // _CALC_VIEW_H
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <Dragger.h>
|
#include <Dragger.h>
|
||||||
#include <Screen.h>
|
#include <Screen.h>
|
||||||
|
|
||||||
|
#include "CalcOptions.h"
|
||||||
#include "CalcView.h"
|
#include "CalcView.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -36,7 +37,9 @@ CalcWindow::CalcWindow(BRect frame, BMessage* settings)
|
|||||||
BScreen screen(this);
|
BScreen screen(this);
|
||||||
rgb_color baseColor = screen.DesktopColor();
|
rgb_color baseColor = screen.DesktopColor();
|
||||||
|
|
||||||
SetSizeLimits(100.0, 400.0, 100.0, 400.0);
|
// Size Limits are defined in CalcView.h
|
||||||
|
SetSizeLimits(kMinimumWidthBasic, kMaximumWidthBasic,
|
||||||
|
kMinimumHeightBasic, kMaximumHeightBasic);
|
||||||
|
|
||||||
frame.OffsetTo(B_ORIGIN);
|
frame.OffsetTo(B_ORIGIN);
|
||||||
fCalcView = new CalcView(frame, baseColor, settings);
|
fCalcView = new CalcView(frame, baseColor, settings);
|
||||||
@@ -57,6 +60,14 @@ CalcWindow::CalcWindow(BRect frame, BMessage* settings)
|
|||||||
SetFrame(rect);
|
SetFrame(rect);
|
||||||
else
|
else
|
||||||
SetFrame(frame, true);
|
SetFrame(frame, true);
|
||||||
|
|
||||||
|
// Add shortcut keys to menu options
|
||||||
|
AddShortcut('0', B_COMMAND_KEY,
|
||||||
|
new BMessage(MSG_OPTIONS_KEYPAD_MODE_COMPACT));
|
||||||
|
AddShortcut('1', B_COMMAND_KEY,
|
||||||
|
new BMessage(MSG_OPTIONS_KEYPAD_MODE_BASIC));
|
||||||
|
AddShortcut('2', B_COMMAND_KEY,
|
||||||
|
new BMessage(MSG_OPTIONS_KEYPAD_MODE_SCIENTIFIC));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -65,6 +76,37 @@ CalcWindow::~CalcWindow()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CalcWindow::MessageReceived(BMessage* msg)
|
||||||
|
{
|
||||||
|
switch (msg->what) {
|
||||||
|
case MSG_OPTIONS_AUTO_NUM_LOCK:
|
||||||
|
fCalcView->ToggleAutoNumlock();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSG_OPTIONS_AUDIO_FEEDBACK:
|
||||||
|
fCalcView->ToggleAudioFeedback();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSG_OPTIONS_KEYPAD_MODE_COMPACT:
|
||||||
|
fCalcView->SetKeypadMode(KEYPAD_MODE_COMPACT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSG_OPTIONS_KEYPAD_MODE_BASIC:
|
||||||
|
fCalcView->SetKeypadMode(KEYPAD_MODE_BASIC);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSG_OPTIONS_KEYPAD_MODE_SCIENTIFIC:
|
||||||
|
fCalcView->SetKeypadMode(KEYPAD_MODE_SCIENTIFIC);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
BWindow::MessageReceived(msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CalcWindow::Show()
|
CalcWindow::Show()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class CalcWindow : public BWindow {
|
|||||||
CalcWindow(BRect frame, BMessage* settings);
|
CalcWindow(BRect frame, BMessage* settings);
|
||||||
virtual ~CalcWindow();
|
virtual ~CalcWindow();
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
virtual void Show();
|
virtual void Show();
|
||||||
virtual bool QuitRequested();
|
virtual bool QuitRequested();
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ resource app_name_catalog_entry "x-vnd.Haiku-DeskCalc:System name:DeskCalc";
|
|||||||
|
|
||||||
resource app_version {
|
resource app_version {
|
||||||
major = 2,
|
major = 2,
|
||||||
middle = 1,
|
middle = 2,
|
||||||
minor = 0,
|
minor = 0,
|
||||||
|
|
||||||
variety = B_APPV_ALPHA,
|
variety = B_APPV_ALPHA,
|
||||||
internal = 1,
|
internal = 1,
|
||||||
|
|
||||||
short_info = "DeskCalc",
|
short_info = "DeskCalc",
|
||||||
long_info = "DeskCalc ©2006-2009 Haiku, Inc."
|
long_info = "DeskCalc ©2006-2011 Haiku, Inc."
|
||||||
};
|
};
|
||||||
|
|
||||||
resource app_flags B_SINGLE_LAUNCH;
|
resource app_flags B_SINGLE_LAUNCH;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006 Haiku, Inc. All Rights Reserved.
|
* Copyright 2006-2011 Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -188,7 +188,7 @@ ExpressionTextView::SetValue(BString value)
|
|||||||
uint32 mode = B_FONT_ALL;
|
uint32 mode = B_FONT_ALL;
|
||||||
GetFontAndColor(&font, &mode);
|
GetFontAndColor(&font, &mode);
|
||||||
float stringWidth = font.StringWidth(value);
|
float stringWidth = font.StringWidth(value);
|
||||||
|
|
||||||
// make the string shorter if it does not fit in the view
|
// make the string shorter if it does not fit in the view
|
||||||
float viewWidth = Frame().Width();
|
float viewWidth = Frame().Width();
|
||||||
if (value.CountChars() > 3 && stringWidth > viewWidth) {
|
if (value.CountChars() > 3 && stringWidth > viewWidth) {
|
||||||
@@ -207,20 +207,20 @@ ExpressionTextView::SetValue(BString value)
|
|||||||
if (offset == firstDigit + 1) {
|
if (offset == firstDigit + 1) {
|
||||||
// if the value is 0.01 or larger then scientific notation
|
// if the value is 0.01 or larger then scientific notation
|
||||||
// won't shorten the string
|
// won't shorten the string
|
||||||
if (value[firstDigit] != '0' || value[firstDigit+2] != '0'
|
if (value[firstDigit] != '0' || value[firstDigit + 2] != '0'
|
||||||
|| value[firstDigit + 3] != '0') {
|
|| value[firstDigit + 3] != '0') {
|
||||||
exponent = 0;
|
exponent = 0;
|
||||||
} else {
|
} else {
|
||||||
// remove the period
|
// remove the period
|
||||||
value.Remove(offset, 1);
|
value.Remove(offset, 1);
|
||||||
|
|
||||||
// check for negative exponent value
|
// check for negative exponent value
|
||||||
exponent = 0;
|
exponent = 0;
|
||||||
while (value[firstDigit] == '0') {
|
while (value[firstDigit] == '0') {
|
||||||
value.Remove(firstDigit, 1);
|
value.Remove(firstDigit, 1);
|
||||||
exponent--;
|
exponent--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the period
|
// add the period
|
||||||
value.Insert('.', 1, firstDigit + 1);
|
value.Insert('.', 1, firstDigit + 1);
|
||||||
}
|
}
|
||||||
@@ -241,12 +241,12 @@ ExpressionTextView::SetValue(BString value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the exponent
|
// add the exponent
|
||||||
offset = value.CountChars() - 1;
|
offset = value.CountChars() - 1;
|
||||||
if (exponent != 0)
|
if (exponent != 0)
|
||||||
value << "E" << exponent;
|
value << "E" << exponent;
|
||||||
|
|
||||||
// reduce the number of digits until the string fits or can not be
|
// reduce the number of digits until the string fits or can not be
|
||||||
// made any shorter
|
// made any shorter
|
||||||
stringWidth = font.StringWidth(value);
|
stringWidth = font.StringWidth(value);
|
||||||
@@ -257,13 +257,13 @@ ExpressionTextView::SetValue(BString value)
|
|||||||
value.Remove(offset--, 1);
|
value.Remove(offset--, 1);
|
||||||
stringWidth = font.StringWidth(value);
|
stringWidth = font.StringWidth(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// there is no need to keep the period if no digits follow
|
// there is no need to keep the period if no digits follow
|
||||||
if (value[offset] == '.') {
|
if (value[offset] == '.') {
|
||||||
value.Remove(offset, 1);
|
value.Remove(offset, 1);
|
||||||
offset--;
|
offset--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// take care of proper rounding of the result
|
// take care of proper rounding of the result
|
||||||
int digit = (int)lastRemovedDigit - '0'; // ascii to int
|
int digit = (int)lastRemovedDigit - '0'; // ascii to int
|
||||||
if (digit >= 5) {
|
if (digit >= 5) {
|
||||||
@@ -282,14 +282,14 @@ ExpressionTextView::SetValue(BString value)
|
|||||||
value[firstDigit] = '.';
|
value[firstDigit] = '.';
|
||||||
}
|
}
|
||||||
value.Insert('1', 1, firstDigit);
|
value.Insert('1', 1, firstDigit);
|
||||||
|
|
||||||
// remove the exponent value and the last digit
|
// remove the exponent value and the last digit
|
||||||
offset = value.FindFirst('E');
|
offset = value.FindFirst('E');
|
||||||
if (offset == B_ERROR)
|
if (offset == B_ERROR)
|
||||||
offset = value.CountChars();
|
offset = value.CountChars();
|
||||||
value.Truncate(--offset);
|
value.Truncate(--offset);
|
||||||
offset--; // offset now points to the last digit
|
offset--; // offset now points to the last digit
|
||||||
|
|
||||||
// increase the exponent and add it back to the string
|
// increase the exponent and add it back to the string
|
||||||
exponent++;
|
exponent++;
|
||||||
value << 'E' << exponent;
|
value << 'E' << exponent;
|
||||||
@@ -298,11 +298,11 @@ ExpressionTextView::SetValue(BString value)
|
|||||||
value[offset] = char(digit + 48);
|
value[offset] = char(digit + 48);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove trailing zeros
|
// remove trailing zeros
|
||||||
while (value[offset] == '0')
|
while (value[offset] == '0')
|
||||||
value.Remove(offset--, 1);
|
value.Remove(offset--, 1);
|
||||||
|
|
||||||
// there is no need to keep the period if no digits follow
|
// there is no need to keep the period if no digits follow
|
||||||
if (value[offset] == '.')
|
if (value[offset] == '.')
|
||||||
value.Remove(offset, 1);
|
value.Remove(offset, 1);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2009 Haiku, Inc. All Rights Reserved.
|
* Copyright 2006-2011 Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -159,7 +159,7 @@ class Tokenizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// optional exponent part
|
// optional exponent part
|
||||||
if (*fCurrentChar == 'e' || *fCurrentChar == 'E') {
|
if (*fCurrentChar == 'E') {
|
||||||
temp << *fCurrentChar;
|
temp << *fCurrentChar;
|
||||||
fCurrentChar++;
|
fCurrentChar++;
|
||||||
|
|
||||||
@@ -206,6 +206,13 @@ class Tokenizer {
|
|||||||
fCurrentToken = Token(begin, length, _CurrentPos() - length,
|
fCurrentToken = Token(begin, length, _CurrentPos() - length,
|
||||||
TOKEN_IDENTIFIER);
|
TOKEN_IDENTIFIER);
|
||||||
|
|
||||||
|
} else if ((unsigned char)fCurrentChar[0] == 0xCF
|
||||||
|
&& (unsigned char)fCurrentChar[1] == 0x80) {
|
||||||
|
// UTF-8 small greek letter PI
|
||||||
|
fCurrentToken = Token(fCurrentChar, 2, _CurrentPos() - 1,
|
||||||
|
TOKEN_IDENTIFIER);
|
||||||
|
fCurrentChar += 2;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
int32 type = TOKEN_NONE;
|
int32 type = TOKEN_NONE;
|
||||||
|
|
||||||
@@ -568,10 +575,14 @@ ExpressionParser::_InitArguments(MAPM values[], int32 argumentCount)
|
|||||||
MAPM
|
MAPM
|
||||||
ExpressionParser::_ParseFunction(const Token& token)
|
ExpressionParser::_ParseFunction(const Token& token)
|
||||||
{
|
{
|
||||||
if (strcasecmp("e", token.string.String()) == 0)
|
if (strcmp("e", token.string.String()) == 0)
|
||||||
return _ParseFactorial(MAPM(MM_E));
|
return _ParseFactorial(MAPM(MM_E));
|
||||||
else if (strcasecmp("pi", token.string.String()) == 0)
|
else if (strcasecmp("pi", token.string.String()) == 0
|
||||||
|
|| ((unsigned char)token.string.String()[0] == 0xCF
|
||||||
|
&& (unsigned char)token.string.String()[1] == 0x80)) {
|
||||||
|
// UTF-8 small greek letter PI
|
||||||
return _ParseFactorial(MAPM(MM_PI));
|
return _ParseFactorial(MAPM(MM_PI));
|
||||||
|
}
|
||||||
|
|
||||||
// hard coded cases for different count of arguments
|
// hard coded cases for different count of arguments
|
||||||
// supports functions with 3 arguments at most
|
// supports functions with 3 arguments at most
|
||||||
|
|||||||
Reference in New Issue
Block a user