Initial checkin with some style cleanups from original sources
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17681 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
a7b537b877
commit
0d960ff17f
349
src/apps/calculator/CalcEngine.cpp
Normal file
349
src/apps/calculator/CalcEngine.cpp
Normal file
@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Peter Wagner <pwagner@stanfordalumni.org>
|
||||
*/
|
||||
#include "CalcEngine.h"
|
||||
#include <string.h>
|
||||
#include <Beep.h>
|
||||
|
||||
CalcEngine::CalcEngine(int max_digits_in)
|
||||
{
|
||||
max_digits = max_digits_in;
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
void CalcEngine::Clear()
|
||||
{
|
||||
trig_inverse_active = false;
|
||||
trig_is_radians = false;
|
||||
already_have_infix = false;
|
||||
number_stack_index = 0;
|
||||
symbol_stack_index = 0;
|
||||
keyed_value = 0.0;
|
||||
text[0] = '\0';
|
||||
}
|
||||
|
||||
|
||||
CalcEngine::~CalcEngine()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
double CalcEngine::GetValue(char *str)
|
||||
{
|
||||
if (strlen(text) == 0)
|
||||
{
|
||||
if (str != NULL)
|
||||
{
|
||||
int precision = max_digits+1;
|
||||
char format[10];
|
||||
do
|
||||
{
|
||||
precision--;
|
||||
sprintf(format, "%%.%dg", precision);
|
||||
sprintf(str, format, keyed_value);
|
||||
} while (!TextWidthOK(str));
|
||||
}
|
||||
return keyed_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (str != NULL)
|
||||
strcpy(str, text);
|
||||
return atof(text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CalcEngine::TextWidthOK(const char *str)
|
||||
{
|
||||
return (int)strlen(str) < max_digits+1 ? true : false;
|
||||
}
|
||||
|
||||
|
||||
void CalcEngine::DoCommand(ulong what)
|
||||
{
|
||||
bool is_infix_symbol = false;
|
||||
int i;
|
||||
double d;
|
||||
|
||||
switch (what)
|
||||
{
|
||||
case 'clr':
|
||||
if (keyed_value == 0 && strlen(text)==0)
|
||||
{
|
||||
// Clear was just pressed before, so reset everything.
|
||||
Clear();
|
||||
}
|
||||
SetValue(0.0);
|
||||
break;
|
||||
case '¹':
|
||||
case 'p':
|
||||
case 'pi':
|
||||
SetValue(M_PI);
|
||||
break;
|
||||
case 'e':
|
||||
SetValue(M_E);
|
||||
break;
|
||||
case '-/+':
|
||||
if (strlen(text)==0) keyed_value = -keyed_value;
|
||||
else
|
||||
{
|
||||
// Must stick a minus sign in front of the text or
|
||||
// after 'e' in exponential form.
|
||||
char *p = strchr(text, 'e');
|
||||
if (p == NULL) p = text;
|
||||
else p += 1; // one char after 'e'
|
||||
|
||||
// p now points to insertion point
|
||||
if (p[0] == '-')
|
||||
p[0] = '+';
|
||||
else if (p[0] == '+')
|
||||
p[0] = '-';
|
||||
else
|
||||
{
|
||||
memmove(p+1, p, strlen(p)+1);
|
||||
p[0] = '-';
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
Append(what);
|
||||
break;
|
||||
case 'exp':
|
||||
if (strlen(text) > 0 && strchr(text,'e')==NULL)
|
||||
Append('e');
|
||||
else
|
||||
beep();
|
||||
break;
|
||||
case '.':
|
||||
if (strlen(text) == 0)
|
||||
SetValue("0.");
|
||||
else if (strchr(text,'.')==NULL && strchr(text,'e')==NULL)
|
||||
Append('.');
|
||||
else beep();
|
||||
break;
|
||||
case '(':
|
||||
PushSymbol(what);
|
||||
SetValue(0.0);
|
||||
break;
|
||||
case ')':
|
||||
PushKeyedValue();
|
||||
while (symbol_stack_index > 0
|
||||
&& symbol_stack[symbol_stack_index-1] != '(') // )
|
||||
{
|
||||
d = DoStackedCalculation();
|
||||
}
|
||||
if (symbol_stack_index > 0
|
||||
&& symbol_stack[symbol_stack_index-1] == '(') // )
|
||||
symbol_stack_index--;
|
||||
SetValue(number_stack[--number_stack_index]);
|
||||
break;
|
||||
case '+':
|
||||
case '-':
|
||||
is_infix_symbol = true;
|
||||
if (already_have_infix) symbol_stack_index--;
|
||||
else PushKeyedValue();
|
||||
d = GetValue();
|
||||
while (symbol_stack_index > 0
|
||||
&& (symbol_stack[symbol_stack_index-1] == '+'
|
||||
|| symbol_stack[symbol_stack_index-1] == '-'
|
||||
|| symbol_stack[symbol_stack_index-1] == '*'
|
||||
|| symbol_stack[symbol_stack_index-1] == '/'
|
||||
|| symbol_stack[symbol_stack_index-1] == '^'
|
||||
|| symbol_stack[symbol_stack_index-1] == '^1/y'))
|
||||
{
|
||||
d = DoStackedCalculation();
|
||||
}
|
||||
SetValue(d);
|
||||
PushSymbol(what);
|
||||
break;
|
||||
case '*':
|
||||
case '/':
|
||||
is_infix_symbol = true;
|
||||
if (already_have_infix) symbol_stack_index--;
|
||||
else PushKeyedValue();
|
||||
d = GetValue();
|
||||
while (symbol_stack_index > 0
|
||||
&& (symbol_stack[symbol_stack_index-1] == '*'
|
||||
|| symbol_stack[symbol_stack_index-1] == '/'
|
||||
|| symbol_stack[symbol_stack_index-1] == '^'
|
||||
|| symbol_stack[symbol_stack_index-1] == '^1/y'))
|
||||
{
|
||||
d = DoStackedCalculation();
|
||||
}
|
||||
SetValue(d);
|
||||
PushSymbol(what);
|
||||
break;
|
||||
case '^':
|
||||
case '^1/y':
|
||||
is_infix_symbol = true;
|
||||
if (already_have_infix) symbol_stack_index--;
|
||||
else PushKeyedValue();
|
||||
d = GetValue();
|
||||
while (symbol_stack_index > 0
|
||||
&& (symbol_stack[symbol_stack_index-1] == '^'
|
||||
|| symbol_stack[symbol_stack_index-1] == '^1/y'))
|
||||
{
|
||||
d = DoStackedCalculation();
|
||||
}
|
||||
SetValue(d);
|
||||
PushSymbol(what);
|
||||
break;
|
||||
case 'x^2':
|
||||
d = GetValue();
|
||||
SetValue(d * d);
|
||||
break;
|
||||
case 'sqrt':
|
||||
SetValue(sqrt(GetValue()));
|
||||
break;
|
||||
case '10^x':
|
||||
SetValue(pow(10.0, GetValue()));
|
||||
break;
|
||||
case 'log':
|
||||
SetValue(log10(GetValue()));
|
||||
break;
|
||||
case 'e^x':
|
||||
SetValue(exp(GetValue()));
|
||||
break;
|
||||
case 'ln x':
|
||||
SetValue(log(GetValue()));
|
||||
break;
|
||||
case '1/x':
|
||||
SetValue(1.0 / GetValue());
|
||||
break;
|
||||
case '!':
|
||||
d = GetValue();
|
||||
if (d > 1000) d = 1000;
|
||||
else if (d < -1000) d = -1000;
|
||||
|
||||
if (d >= 0)
|
||||
{
|
||||
i = (int)(d + 0.0000000001);
|
||||
d = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = (int)(-d + 0.0000000001);
|
||||
d = -1.0;
|
||||
}
|
||||
while (i > 0)
|
||||
{
|
||||
d *= i;
|
||||
i--;
|
||||
}
|
||||
SetValue(d);
|
||||
break;
|
||||
case 'sin':
|
||||
if (trig_inverse_active)
|
||||
SetValue(TrigAngleOutput(asin(GetValue())));
|
||||
else
|
||||
SetValue(sin(TrigAngleInput(GetValue())));
|
||||
break;
|
||||
case 'cos':
|
||||
if (trig_inverse_active)
|
||||
SetValue(TrigAngleOutput(acos(GetValue())));
|
||||
else
|
||||
SetValue(cos(TrigAngleInput(GetValue())));
|
||||
break;
|
||||
case 'tan':
|
||||
if (trig_inverse_active)
|
||||
SetValue(TrigAngleOutput(atan(GetValue())));
|
||||
else
|
||||
SetValue(tan(TrigAngleInput(GetValue())));
|
||||
break;
|
||||
case '=':
|
||||
case 'entr':
|
||||
if (already_have_infix) symbol_stack_index--;
|
||||
else PushKeyedValue();
|
||||
while (symbol_stack_index > 0)
|
||||
{
|
||||
d = DoStackedCalculation();
|
||||
}
|
||||
d = number_stack[--number_stack_index];
|
||||
number_stack_index = 0;
|
||||
SetValue(d);
|
||||
break;
|
||||
case 'trgA':
|
||||
trig_inverse_active = !trig_inverse_active;
|
||||
break;
|
||||
case 'trgM':
|
||||
trig_is_radians = !trig_is_radians;
|
||||
break;
|
||||
}
|
||||
|
||||
already_have_infix = is_infix_symbol;
|
||||
|
||||
if (what != 'trgA' && trig_inverse_active)
|
||||
{
|
||||
trig_inverse_active = !trig_inverse_active;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CalcEngine::PushKeyedValue()
|
||||
{
|
||||
double d = GetValue();
|
||||
number_stack[number_stack_index++] = d;
|
||||
SetValue(d);
|
||||
}
|
||||
|
||||
|
||||
void CalcEngine::PushSymbol(ulong sym)
|
||||
{
|
||||
symbol_stack[symbol_stack_index++] = sym;
|
||||
}
|
||||
|
||||
|
||||
double CalcEngine::DoStackedCalculation()
|
||||
{
|
||||
ulong sym = symbol_stack[--symbol_stack_index];
|
||||
double right_number = number_stack[--number_stack_index];
|
||||
double left_number = number_stack[--number_stack_index];
|
||||
double result;
|
||||
|
||||
switch (sym)
|
||||
{
|
||||
case '+':
|
||||
result = left_number + right_number;
|
||||
break;
|
||||
case '-':
|
||||
result = left_number - right_number;
|
||||
break;
|
||||
case '*':
|
||||
result = left_number * right_number;
|
||||
break;
|
||||
case '/':
|
||||
result = left_number / right_number;
|
||||
break;
|
||||
case '^':
|
||||
result = pow(left_number, right_number);
|
||||
break;
|
||||
case '^1/y':
|
||||
result = pow(left_number, 1.0/right_number);
|
||||
break;
|
||||
default:
|
||||
// bogus !
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
number_stack[number_stack_index++] = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
62
src/apps/calculator/CalcEngine.h
Normal file
62
src/apps/calculator/CalcEngine.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Peter Wagner <pwagner@stanfordalumni.org>
|
||||
*/
|
||||
#ifndef __CALC_ENGINE__
|
||||
#define __CALC_ENGINE__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
typedef unsigned long ulong;
|
||||
|
||||
class CalcEngine
|
||||
{
|
||||
public:
|
||||
CalcEngine(int max_digits = 12);
|
||||
virtual ~CalcEngine();
|
||||
|
||||
void DoCommand(ulong key);
|
||||
double GetValue(char *val=NULL);
|
||||
void Clear(void);
|
||||
|
||||
bool TrigInverseActive() { return trig_inverse_active; };
|
||||
bool TrigIsRadians() { return trig_is_radians; };
|
||||
|
||||
virtual bool TextWidthOK(const char *text);
|
||||
|
||||
private:
|
||||
|
||||
enum { max_stack_size = 20 };
|
||||
enum { mode_start=0, mode_input };
|
||||
|
||||
char text[64];
|
||||
double keyed_value;
|
||||
|
||||
void SetValue(double d) { keyed_value=d; text[0]='\0'; };
|
||||
void SetValue(const char *str) { keyed_value=0; strcpy(text,str);};
|
||||
void Append(char c) { char *p=text+strlen(text); *p++=c; *p='\0'; };
|
||||
|
||||
double DoStackedCalculation();
|
||||
void PushKeyedValue();
|
||||
void PushSymbol(ulong sym);
|
||||
|
||||
int max_digits;
|
||||
bool trig_inverse_active;
|
||||
bool trig_is_radians;
|
||||
bool already_have_infix;
|
||||
|
||||
int number_stack_index;
|
||||
double number_stack[max_stack_size];
|
||||
int symbol_stack_index;
|
||||
ulong symbol_stack[max_stack_size];
|
||||
|
||||
double TrigAngleInput(double d) { return trig_is_radians?d:M_PI/180*d; };
|
||||
double TrigAngleOutput(double d) { return trig_is_radians?d:180/M_PI*d; };
|
||||
};
|
||||
|
||||
#endif
|
589
src/apps/calculator/CalcView.cpp
Normal file
589
src/apps/calculator/CalcView.cpp
Normal file
@ -0,0 +1,589 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Peter Wagner <pwagner@stanfordalumni.org>
|
||||
*/
|
||||
#include <iostream.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Button.h>
|
||||
#include <StringView.h>
|
||||
#include <Beep.h>
|
||||
#include <Dragger.h>
|
||||
#include <TextView.h>
|
||||
#include <View.h>
|
||||
#include <Clipboard.h>
|
||||
|
||||
#include "CalcView.h"
|
||||
#include "FrameView.h"
|
||||
|
||||
|
||||
const int border = 8;
|
||||
const int key_border = 4;
|
||||
const int key_height = 23;
|
||||
const int key_width = 32;
|
||||
|
||||
|
||||
void CalcView::MouseDown(BPoint where)
|
||||
{
|
||||
BView::MouseDown(where);
|
||||
MakeFocus();
|
||||
ChangeHighlight();
|
||||
}
|
||||
|
||||
|
||||
void CalcView::ChangeHighlight()
|
||||
{
|
||||
int state = state_unknown;
|
||||
|
||||
BWindow *wind = Window();
|
||||
if (wind != NULL)
|
||||
state = (wind->IsActive() && IsFocus()) ? state_active : state_inactive;
|
||||
|
||||
if (state != current_highlight) {
|
||||
rgb_color on = {204,204,255};
|
||||
rgb_color off = {204*9/10, 204*9/10, 255*9/10};
|
||||
|
||||
if (state == state_inactive) {
|
||||
lcd_frame->SetViewColor(off);
|
||||
lcd->SetLowColor(off);
|
||||
lcd->SetViewColor(off);
|
||||
// lcd->SetHighColor(102,102,102);
|
||||
}
|
||||
else {
|
||||
lcd_frame->SetViewColor(on);
|
||||
lcd->SetLowColor(on);
|
||||
lcd->SetViewColor(on);
|
||||
// lcd->SetHighColor(51,51,51);
|
||||
}
|
||||
lcd_frame->Invalidate();
|
||||
lcd->Invalidate();
|
||||
|
||||
current_highlight = state;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CalcView::WindowActivated(bool state)
|
||||
{
|
||||
BView::WindowActivated(state);
|
||||
|
||||
ChangeHighlight();
|
||||
}
|
||||
|
||||
|
||||
void CalcView::MakeFocus(bool focusState)
|
||||
{
|
||||
BView::MakeFocus(focusState);
|
||||
|
||||
ChangeHighlight();
|
||||
}
|
||||
|
||||
|
||||
CalcView::CalcView(BRect rect)
|
||||
: BView(rect, "Calculator", B_FOLLOW_NONE, B_WILL_DRAW),
|
||||
calc(15)
|
||||
{
|
||||
Init();
|
||||
|
||||
BDragger *dragger;
|
||||
dragger = new BDragger(BRect(0,0,7,7), this, 0);
|
||||
AddChild(dragger);
|
||||
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
BRect r;
|
||||
r.left = border;
|
||||
r.right = r.left + key_border*8 + key_width*7;
|
||||
r.top = border-1;
|
||||
r.bottom = r.top + 40;
|
||||
r.InsetBy(-1,0);
|
||||
lcd_frame = new FrameView(r, "lcd frame", B_FOLLOW_LEFT_RIGHT|B_FOLLOW_TOP, 1);
|
||||
AddChild(lcd_frame);
|
||||
|
||||
BRect r2;
|
||||
r2 = lcd_frame->Bounds();
|
||||
r2.InsetBy(5,2);
|
||||
r2.OffsetBy(3,1);
|
||||
lcd = new BStringView(r2, "lcd", "0", B_FOLLOW_ALL_SIDES);
|
||||
lcd->SetFont(be_plain_font/*"Arial MT"*/);
|
||||
lcd->SetFontSize(30);
|
||||
lcd->SetAlignment(B_ALIGN_RIGHT);
|
||||
lcd_frame->AddChild(lcd);
|
||||
|
||||
static FrameView::ClusterInfo trig_button_info[] =
|
||||
{ {"sin", 'sin'}, {"cos", 'cos'},
|
||||
{"tan", 'tan'}, {0}, {0},
|
||||
{"inv", 'trgA'}, {"deg", 'trgM'}
|
||||
};
|
||||
FrameView *trig_frame
|
||||
= new FrameView(BPoint(8,57), "trig area", B_FOLLOW_NONE,
|
||||
7,1, 1, key_border, key_height, key_width,
|
||||
trig_button_info);
|
||||
AddChild(trig_frame);
|
||||
|
||||
static FrameView::ClusterInfo const_button_info[] =
|
||||
{ {"-/+", '-/+'}, {"exp", 'exp'},
|
||||
{"e", 'e'}, {"pi", 'pi'}, {0},
|
||||
{"(", '('}, {")", ')'}
|
||||
};
|
||||
FrameView *const_frame
|
||||
= new FrameView(BPoint(8,97), "const area", B_FOLLOW_NONE,
|
||||
7,1, 1, key_border, key_height, key_width,
|
||||
const_button_info);
|
||||
AddChild(const_frame);
|
||||
|
||||
|
||||
|
||||
static FrameView::ClusterInfo keypad_button_info[] =
|
||||
{ {"C",'clr'}, {"=",'='}, {"/",'/'}, {"*",'*'},
|
||||
{"7",'7'}, {"8",'8'}, {"9",'9'}, {"-",'-'},
|
||||
{"4",'4'}, {"5",'5'}, {"6",'6'}, {"+",'+'},
|
||||
{"1",'1'}, {"2",'2'}, {"3",'3'}, {"=",'entr'},
|
||||
{"0",'0'}, {0}, {".",'.'}, {0}
|
||||
};
|
||||
FrameView *keypad_frame
|
||||
= new FrameView(BPoint(8,137), "keypad area", B_FOLLOW_NONE,
|
||||
4,5, 1, key_border, key_height, key_width,
|
||||
keypad_button_info);
|
||||
AddChild(keypad_frame);
|
||||
keypad_frame->FindView("entr")->ResizeBy(0, key_height+key_border);
|
||||
keypad_frame->FindView("0")->ResizeBy(key_width+key_border, 0);
|
||||
|
||||
|
||||
static FrameView::ClusterInfo func_button_info[] =
|
||||
{ {"x^y", '^'}, {"x^1/y", '^1/y'},
|
||||
{"x^2", 'x^2'}, {"sqrt", 'sqrt'},
|
||||
{"10^x", '10^x'}, {"log", 'log'},
|
||||
{"e^x", 'e^x'}, {"ln x", 'ln x'},
|
||||
{"x!", '!'}, {"1/x", '1/x'}
|
||||
};
|
||||
FrameView *func_frame
|
||||
= new FrameView(BPoint(188,137), "func area", B_FOLLOW_NONE,
|
||||
2,5, 1, key_border, key_height, key_width,
|
||||
func_button_info);
|
||||
AddChild(func_frame);
|
||||
}
|
||||
|
||||
|
||||
CalcView::CalcView(BMessage *msg)
|
||||
: BView(msg),
|
||||
calc(15)
|
||||
{
|
||||
Init();
|
||||
|
||||
is_replicant = true;
|
||||
|
||||
lcd_frame = (FrameView *)FindView("lcd frame");
|
||||
lcd = (BStringView *)FindView("lcd");
|
||||
|
||||
lcd->SetText("0");
|
||||
}
|
||||
|
||||
|
||||
void CalcView::Init()
|
||||
{
|
||||
is_replicant = false;
|
||||
current_highlight = state_unknown;
|
||||
|
||||
binary_sign_view = NULL;
|
||||
binary_exponent_view = NULL;
|
||||
binary_number_view = NULL;
|
||||
}
|
||||
|
||||
|
||||
void CalcView::Draw(BRect updateRect)
|
||||
{
|
||||
BView::Draw(updateRect);
|
||||
|
||||
if (is_replicant)
|
||||
{
|
||||
const float bevel = 2;
|
||||
BRect r = Bounds();
|
||||
r.right -= (bevel - 1);
|
||||
r.bottom -= (bevel - 1);
|
||||
SetPenSize(bevel);
|
||||
StrokeRect(r);
|
||||
SetPenSize(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BView * CalcView::AddExtra()
|
||||
{
|
||||
BRect r2;
|
||||
|
||||
BRect r = Frame();
|
||||
r.top = r.bottom;
|
||||
r.bottom = r.top + ExtraHeight();
|
||||
BView *view = new BView(r, "Calculator Extra", 0, B_WILL_DRAW);
|
||||
view->SetViewColor(153,153,153);
|
||||
|
||||
r = view->Bounds();
|
||||
r.InsetBy(border, 1);
|
||||
r.left -= 1;
|
||||
r.bottom = r.top + 16;
|
||||
r.right = r.left + 8+2;
|
||||
FrameView *binary_frame = new FrameView(r, NULL, 0, 1);
|
||||
view->AddChild(binary_frame);
|
||||
r2 = binary_frame->Bounds();
|
||||
r2.InsetBy(2,2);
|
||||
r2.OffsetBy(1,1);
|
||||
binary_sign_view = new BStringView(r2, "binary sign view", "", 0);
|
||||
binary_sign_view->SetAlignment(B_ALIGN_CENTER);
|
||||
binary_sign_view->SetViewColor(binary_frame->ViewColor());
|
||||
binary_frame->AddChild(binary_sign_view);
|
||||
|
||||
r.OffsetBy(r.Width()+3, 0);
|
||||
r.right = r.left + 72;
|
||||
binary_frame = new FrameView(r, NULL, 0, 1);
|
||||
view->AddChild(binary_frame);
|
||||
r2 = binary_frame->Bounds();
|
||||
r2.InsetBy(2,2);
|
||||
r2.OffsetBy(1,1);
|
||||
binary_exponent_view = new BStringView(r2, "binary exponent view", "", 0);
|
||||
binary_exponent_view->SetAlignment(B_ALIGN_CENTER);
|
||||
binary_exponent_view->SetViewColor(binary_frame->ViewColor());
|
||||
binary_frame->AddChild(binary_exponent_view);
|
||||
|
||||
r.OffsetBy(r.Width()+3, 0);
|
||||
r.right = Bounds().Width() - border + 1;
|
||||
binary_frame = new FrameView(r, NULL, 0, 1);
|
||||
view->AddChild(binary_frame);
|
||||
r2 = binary_frame->Bounds();
|
||||
r2.InsetBy(2,2);
|
||||
r2.OffsetBy(1,1);
|
||||
binary_number_view = new BStringView(r2, "binary number view", "", 0);
|
||||
binary_number_view->SetAlignment(B_ALIGN_CENTER);
|
||||
binary_number_view->SetViewColor(binary_frame->ViewColor());
|
||||
binary_frame->AddChild(binary_number_view);
|
||||
|
||||
|
||||
r = view->Bounds();
|
||||
r.InsetBy(border, 0);
|
||||
r.top = binary_frame->Frame().bottom + 3;
|
||||
r.bottom = r.top + 16;
|
||||
r.InsetBy(-1,0);
|
||||
FrameView *about_frame = new FrameView(r, NULL, 0, 1);
|
||||
view->AddChild(about_frame);
|
||||
r2 = about_frame->Bounds();
|
||||
r2.InsetBy(2,2);
|
||||
r2.OffsetBy(0,1);
|
||||
BStringView *peter = new BStringView(r2, NULL,
|
||||
"Brought to you by Peter Wagner", 0);
|
||||
peter->SetAlignment(B_ALIGN_CENTER);
|
||||
peter->SetViewColor(about_frame->ViewColor());
|
||||
about_frame->AddChild(peter);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
status_t CalcView::Archive(BMessage *msg, bool deep) const
|
||||
{
|
||||
BView::Archive(msg, deep);
|
||||
// msg->AddString("class", "CalcView");
|
||||
msg->AddString("add_on", "application/x-vnd.Be-calculator");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
BArchivable *CalcView::Instantiate(BMessage *msg)
|
||||
{
|
||||
if (validate_instantiation(msg, "CalcView"))
|
||||
return new CalcView(msg);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CalcView::~CalcView()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void ConnectButtonMessages(BView *target, const BView *which)
|
||||
{
|
||||
BView *child = which->ChildAt(0);
|
||||
while (child != NULL)
|
||||
{
|
||||
BControl * button = (BControl *)child;
|
||||
button->SetTarget(target);
|
||||
child = child->NextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CalcView::AllAttached()
|
||||
{
|
||||
BView::AllAttached();
|
||||
|
||||
lcd->SetHighColor(51,51,51);
|
||||
MakeFocus();
|
||||
ChangeHighlight();
|
||||
}
|
||||
|
||||
|
||||
void CalcView::AttachedToWindow()
|
||||
{
|
||||
BView::AttachedToWindow();
|
||||
|
||||
// Make buttons send their messages to this view instead of the
|
||||
// [default] enclosing window.
|
||||
ConnectButtonMessages(this, FindView("trig area"));
|
||||
ConnectButtonMessages(this, FindView("const area"));
|
||||
ConnectButtonMessages(this, FindView("keypad area"));
|
||||
ConnectButtonMessages(this, FindView("func area"));
|
||||
}
|
||||
|
||||
|
||||
void CalcView::KeyDown(const char *bytes, int32 numBytes)
|
||||
{
|
||||
for (int i=0; i<numBytes; i++) {
|
||||
char key = bytes[i];
|
||||
BButton *button = NULL;
|
||||
|
||||
switch(key) {
|
||||
case '¸':
|
||||
case '¹':
|
||||
case 'p':
|
||||
case 'P':
|
||||
button = (BButton *)FindView("pi");
|
||||
break;
|
||||
case 'C':
|
||||
case 'c':
|
||||
button = (BButton *)FindView("clr");
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
button = (BButton *)FindView("exp");
|
||||
break;
|
||||
case '`':
|
||||
button = (BButton *)FindView("-/+");
|
||||
break;
|
||||
case '(':
|
||||
case ')':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '=':
|
||||
case '/':
|
||||
case '*':
|
||||
case '-':
|
||||
case '+':
|
||||
case '.':
|
||||
case '^':
|
||||
case '!':
|
||||
char name[2];
|
||||
if (isalpha(key)) key = tolower(key);
|
||||
name[0] = key;
|
||||
name[1] = '\0';
|
||||
button = (BButton *)FindView(name);
|
||||
break;
|
||||
case 10:
|
||||
button = (BButton *)FindView("entr");
|
||||
break;
|
||||
case 127:
|
||||
button = (BButton *)FindView(".");
|
||||
break;
|
||||
default:
|
||||
button = button;
|
||||
break;
|
||||
}
|
||||
|
||||
if (button != NULL) {
|
||||
button->SetValue(1);
|
||||
snooze(100000);
|
||||
button->SetValue(0);
|
||||
snooze(20000);
|
||||
BMessage msg(*button->Message());
|
||||
SendKeystroke(msg.what);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void DoubleToBinary(double *dPtr, char *str)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)dPtr;
|
||||
str[sizeof(double)*8] = '\0';
|
||||
const int bits = sizeof(double) * 8;
|
||||
|
||||
unsigned short endian_test = 1;
|
||||
|
||||
if(((unsigned char *)&endian_test)[0] != 0) {
|
||||
// little-endian
|
||||
for (int i=0; i<bits; i++)
|
||||
str[i] = (p[(sizeof(double) - i/8) - 1] & (128 >> (i&7))) ? '1' : '0';
|
||||
}
|
||||
else {
|
||||
// Big endian
|
||||
for (int i=0; i<bits; i++)
|
||||
str[i] = (p[i/8] & (128 >> (i&7))) ? '1' : '0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char * Mid(const char *str, int start, int stop, char *str_out)
|
||||
{
|
||||
char *s = str_out;
|
||||
|
||||
for (int i=start; i<stop; i++)
|
||||
*s++ = str[i];
|
||||
|
||||
*s = '\0';
|
||||
|
||||
return str_out;
|
||||
}
|
||||
|
||||
|
||||
void CalcView::SendKeystroke(ulong key)
|
||||
{
|
||||
calc.DoCommand(key);
|
||||
|
||||
BButton *trig_inverse = (BButton *)FindView("trgA");
|
||||
trig_inverse->SetValue(calc.TrigInverseActive()?1:0);
|
||||
|
||||
BButton *trig_mode = (BButton *)FindView("trgM");
|
||||
trig_mode->SetLabel(calc.TrigIsRadians()?"rad":"deg");
|
||||
|
||||
|
||||
// Update LCD display.
|
||||
char engine_str[64];
|
||||
calc.GetValue(engine_str);
|
||||
lcd->SetText(engine_str);
|
||||
|
||||
|
||||
if (binary_sign_view && binary_exponent_view && binary_number_view) {
|
||||
// Update binary representation of current display.
|
||||
double d = calc.GetValue();
|
||||
char str[300], str2[300];
|
||||
DoubleToBinary(&d, str);
|
||||
binary_sign_view->SetText(Mid(str, 0,1, str2));
|
||||
binary_exponent_view->SetText(Mid(str, 1,12, str2));
|
||||
|
||||
Mid(str, 13,sizeof(double)*8, str2);
|
||||
while(binary_number_view->StringWidth(str2) >= binary_number_view->Bounds().Width()
|
||||
&& strlen(str2) > 24) {
|
||||
str2[20] = str2[21] = str2[22] = '.';
|
||||
strcpy(str2+23, str2+24);
|
||||
}
|
||||
binary_number_view->SetText(str2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool IsSystemCommand(unsigned long what)
|
||||
{
|
||||
for (int zz=0; zz<4; zz++) {
|
||||
char c = (char)(what >> (zz*8));
|
||||
if (!isupper(c) && c!='_') return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CalcView::About()
|
||||
{
|
||||
(new BAlert("About Calculator", "Calculator (the Replicant version)\n\n Brought to you by Peter Wagner.\n Copyright 1998.","OK"))->Go();
|
||||
}
|
||||
|
||||
|
||||
void CalcView::MessageReceived(BMessage *message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case B_ABOUT_REQUESTED:
|
||||
CalcView::About();
|
||||
break;
|
||||
case B_COPY: {
|
||||
double d;
|
||||
char str[64];
|
||||
d = calc.GetValue(str);
|
||||
if (be_clipboard->Lock())
|
||||
{
|
||||
be_clipboard->Clear();
|
||||
BMessage *clipper = be_clipboard->Data();
|
||||
clipper->AddDouble("value", d);
|
||||
clipper->AddData("text/plain", 'MIME', str, strlen(str));
|
||||
be_clipboard->Commit();
|
||||
be_clipboard->Unlock();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case B_PASTE: {
|
||||
const void *data = NULL;
|
||||
ssize_t sz;
|
||||
if (be_clipboard->Lock()) {
|
||||
BMessage *clipper = be_clipboard->Data();
|
||||
status_t status = clipper->FindData("text/plain", 'MIME', &data, &sz);
|
||||
if (status == B_OK && data!=NULL)
|
||||
KeyDown((const char *)data, (int32)sz);
|
||||
/*
|
||||
// What the heck was on the clipboard !??!
|
||||
{
|
||||
char *name;
|
||||
uint32 type;
|
||||
int32 count;
|
||||
char typeS[5];
|
||||
for ( int32 i = 0;
|
||||
clipper->GetInfo(B_ANY_TYPE, i, &name, &type, &count) == B_OK;
|
||||
i++ )
|
||||
{
|
||||
for (int z=0; z<4; z++)
|
||||
{
|
||||
typeS[z] = (char)(type >> 24);
|
||||
type = type << 8;
|
||||
}
|
||||
cout << i << ": " << name << " " << typeS << "\n";
|
||||
}
|
||||
}
|
||||
*/
|
||||
be_clipboard->Unlock();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (IsSystemCommand(message->what))
|
||||
BView::MessageReceived(message);
|
||||
else {
|
||||
SendKeystroke(message->what);
|
||||
MakeFocus();
|
||||
ChangeHighlight();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
// What the heck was that message?!!
|
||||
char str[5];
|
||||
str[4] = '\0';
|
||||
ulong msg = message->what;
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
str[i] = (char)(msg>>24);
|
||||
msg = msg << 8;
|
||||
if (str[i] == '\0') str[i] = '-';
|
||||
}
|
||||
lcd->SetText(str);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool CalcView::TextWidthOK(const char *str)
|
||||
{
|
||||
return (lcd->StringWidth(str) < lcd->Bounds().Width()) ? true : false;
|
||||
}
|
75
src/apps/calculator/CalcView.h
Normal file
75
src/apps/calculator/CalcView.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Peter Wagner <pwagner@stanfordalumni.org>
|
||||
*/
|
||||
#ifndef __CALC_VIEW__
|
||||
#define __CALC_VIEW__
|
||||
|
||||
#include <View.h>
|
||||
#include <Message.h>
|
||||
#include "FrameView.h"
|
||||
#include "CalcEngine.h"
|
||||
|
||||
class _EXPORT CalcView : public BView
|
||||
{
|
||||
public:
|
||||
static void About(void);
|
||||
|
||||
|
||||
static float TheWidth() { return 272; }
|
||||
static float TheHeight() { return 284; }
|
||||
static BRect TheRect() { return TheRect(0,0); }
|
||||
static BRect TheRect(const BPoint &pt) { return TheRect(pt.x,pt.y); }
|
||||
static BRect TheRect(float x, float y) { return BRect(x,y,x+TheWidth(),y+TheHeight()); }
|
||||
static float ExtraHeight() { return 43; }
|
||||
|
||||
|
||||
CalcView(BRect frame);
|
||||
virtual ~CalcView();
|
||||
|
||||
|
||||
// replicant
|
||||
CalcView(BMessage *msg);
|
||||
virtual status_t Archive(BMessage *msg, bool deep) const;
|
||||
static BArchivable* Instantiate(BMessage *msg);
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
virtual void AllAttached();
|
||||
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void KeyDown(const char *bytes, int32 numBytes);
|
||||
virtual void MouseDown(BPoint where);
|
||||
virtual void WindowActivated(bool state);
|
||||
virtual void MakeFocus(bool focusState = true);
|
||||
|
||||
virtual void MessageReceived(BMessage *message);
|
||||
|
||||
void SendKeystroke(ulong key);
|
||||
|
||||
virtual bool TextWidthOK(const char *str);
|
||||
|
||||
BView *AddExtra();
|
||||
|
||||
private:
|
||||
void Init(void);
|
||||
|
||||
CalcEngine calc;
|
||||
bool is_replicant;
|
||||
|
||||
int current_highlight;
|
||||
enum { state_unknown=0, state_active, state_inactive };
|
||||
void ChangeHighlight();
|
||||
|
||||
|
||||
FrameView *lcd_frame;
|
||||
BStringView *lcd;
|
||||
BStringView *binary_sign_view;
|
||||
BStringView *binary_exponent_view;
|
||||
BStringView *binary_number_view;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
46
src/apps/calculator/CalcWindow.cpp
Normal file
46
src/apps/calculator/CalcWindow.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Peter Wagner <pwagner@stanfordalumni.org>
|
||||
*/
|
||||
#include "Calculator.h"
|
||||
#include "CalcWindow.h"
|
||||
#include "CalcView.h"
|
||||
#include "Prefs.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int h;
|
||||
int v;
|
||||
} Prefs;
|
||||
|
||||
|
||||
CalcWindow::CalcWindow(BPoint pt)
|
||||
: BWindow(CalcView::TheRect(pt), "Calculator", B_TITLED_WINDOW, B_NOT_RESIZABLE)
|
||||
{
|
||||
BRect r = CalcView::TheRect();
|
||||
|
||||
SetSizeLimits(r.right, r.right, r.bottom, r.bottom+CalcView::ExtraHeight());
|
||||
SetZoomLimits(r.right, r.bottom+CalcView::ExtraHeight());
|
||||
|
||||
calc_view = new CalcView(r);
|
||||
AddChild(calc_view);
|
||||
|
||||
BView *extraView = calc_view->AddExtra();
|
||||
AddChild(extraView);
|
||||
}
|
||||
|
||||
|
||||
bool CalcWindow::QuitRequested()
|
||||
{
|
||||
Prefs prefs;
|
||||
prefs.h = (int)(Frame().left);
|
||||
prefs.v = (int)(Frame().top);
|
||||
|
||||
WritePrefs("calculator.prefs", &prefs, sizeof(prefs));
|
||||
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return true;
|
||||
}
|
27
src/apps/calculator/CalcWindow.h
Normal file
27
src/apps/calculator/CalcWindow.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Peter Wagner <pwagner@stanfordalumni.org>
|
||||
*/
|
||||
#ifndef __CALC_WINDOW__
|
||||
#define __CALC_WINDOW__
|
||||
|
||||
#include <Window.h>
|
||||
#include <Beep.h>
|
||||
|
||||
#include "CalcView.h"
|
||||
|
||||
class CalcWindow : public BWindow
|
||||
{
|
||||
public:
|
||||
CalcWindow(BPoint pt);
|
||||
virtual bool QuitRequested();
|
||||
|
||||
private:
|
||||
CalcView *calc_view;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
86
src/apps/calculator/Calculator.cpp
Normal file
86
src/apps/calculator/Calculator.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Peter Wagner <pwagner@stanfordalumni.org>
|
||||
*/
|
||||
#include <iostream.h>
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Window.h>
|
||||
#include <Application.h>
|
||||
#include <Beep.h>
|
||||
#include <Screen.h>
|
||||
|
||||
#include "Calculator.h"
|
||||
#include "CalcWindow.h"
|
||||
#include "Prefs.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int h;
|
||||
int v;
|
||||
} Prefs;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// If we have command-line arguments, calculate and
|
||||
// return. Otherwise, run the graphical interface.
|
||||
if(argc > 1) {
|
||||
for (int i=1; i<argc; i++) {
|
||||
char *str = argv[i];
|
||||
CalcEngine engine;
|
||||
|
||||
while (*str != '\0')
|
||||
engine.DoCommand(*str++);
|
||||
|
||||
engine.DoCommand('='); // send an extra one, just in case
|
||||
printf("%.15g\n", engine.GetValue());
|
||||
}
|
||||
}
|
||||
else {
|
||||
CalculatorApp app;
|
||||
app.Run();
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
CalculatorApp::CalculatorApp(void)
|
||||
: BApplication("application/x-vnd.Haiku-Calculator")
|
||||
{
|
||||
Prefs prefs;
|
||||
if (ReadPrefs("calculator.prefs", &prefs, sizeof(prefs)) != true) {
|
||||
prefs.h = 20;
|
||||
prefs.v = 70;
|
||||
}
|
||||
|
||||
BScreen screen;
|
||||
BRect r = screen.Frame();
|
||||
r.left += 3;
|
||||
r.top += 23;
|
||||
r.right -= (20-5);
|
||||
r.bottom -= -3;
|
||||
|
||||
if(prefs.h < r.left)
|
||||
prefs.h = (int)r.left;
|
||||
if(prefs.h > r.right)
|
||||
prefs.h = (int)r.right;
|
||||
if(prefs.v < r.top)
|
||||
prefs.v = (int)r.top;
|
||||
if(prefs.v > r.bottom)
|
||||
prefs.v = (int)r.bottom;
|
||||
|
||||
|
||||
wind = new CalcWindow(BPoint(prefs.h, prefs.v));
|
||||
wind->Show();
|
||||
}
|
||||
|
||||
|
||||
void CalculatorApp::AboutRequested()
|
||||
{
|
||||
CalcView::About();
|
||||
}
|
||||
|
27
src/apps/calculator/Calculator.h
Normal file
27
src/apps/calculator/Calculator.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Peter Wagner <pwagner@stanfordalumni.org>
|
||||
*/
|
||||
#ifndef __CALCULATOR__
|
||||
#define __CALCULATOR__
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
class CalculatorApp : public BApplication
|
||||
{
|
||||
public:
|
||||
CalculatorApp();
|
||||
virtual void AboutRequested();
|
||||
|
||||
private:
|
||||
BWindow *wind;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
85
src/apps/calculator/Calculator.rdef
Normal file
85
src/apps/calculator/Calculator.rdef
Normal file
@ -0,0 +1,85 @@
|
||||
|
||||
resource(101, "BEOS:M:STD_ICON") #'MICN' array {
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFF0000FFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFF0019190000FFFFFF"
|
||||
$"FFFFFFFFFFFFFF0019868619190000FF"
|
||||
$"FFFFFFFFFFFF00198686868686193F00"
|
||||
$"FFFFFFFFFF00193F3F198686863F0C00"
|
||||
$"FFFFFFFF00191919193F3F863F0C000C"
|
||||
$"FFFFFF00193F3F193F3F193F0C000CFF"
|
||||
$"FFFF0019190C0C190C0C3F0C000C0CFF"
|
||||
$"FF00193F3F193F3F193F0C000C0CFFFF"
|
||||
$"00123F0C0C190C0C3F0C000C0CFFFFFF"
|
||||
$"0012123F3F3F3F3F0C000C0CFFFFFFFF"
|
||||
$"FF000012123F190C000C0CFFFFFFFFFF"
|
||||
$"FFFFFF00001212000C0CFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFF00000C0CFFFFFFFFFFFFFF"
|
||||
};
|
||||
|
||||
resource(101, "BEOS:L:STD_ICON") #'ICON' array {
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0019190000FFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0019868619190000FFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0019868686868619190000FFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFF0019868686868686868619190000FFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFF0019868686868686868686868619190000FFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFF00193F1919868686868686868686868619190000"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFF00191919193F191986868686868686868686193F00"
|
||||
$"FFFFFFFFFFFFFFFFFFFF00193F3F191919193F191986868686868686193F0C00"
|
||||
$"FFFFFFFFFFFFFFFFFF00190C19190C19191919193F191986868686193F0C0C00"
|
||||
$"FFFFFFFFFFFFFFFF001919190C0C19193F3F191919193F191986193F0C0C0C00"
|
||||
$"FFFFFFFFFFFFFF00193F3F191919190C19190C19191919193F193F0C0C0C0019"
|
||||
$"FFFFFFFFFFFF00190C19190C191919190C0C19193F3F1919193F0C0C0C001919"
|
||||
$"FFFFFFFFFF001919190C0C19193F3F191919190C19190C193F0C0C0C00191919"
|
||||
$"FFFFFFFF00193F3F191919190C19190C191919190C0C193F0C0C0C0019191919"
|
||||
$"FFFFFF00190C19190C191919190C0C19193F3F1919193F0C0C0C0019191919FF"
|
||||
$"FFFFFF003F190C0C19193F3F191919190C19190C193F0C0C0C0019191919FFFF"
|
||||
$"FFFFFF00123F3F19190C19190C191919190C0C193F0C0C0C0019191919FFFFFF"
|
||||
$"FFFFFF001212123F3F190C0C19193F3F1919193F0C0C0C0019191919FFFFFFFF"
|
||||
$"FFFFFF0012121212123F3F19190C19190C193F0C0C0C0019191919FFFFFFFFFF"
|
||||
$"FFFFFF00001212121212123F3F190C0C193F0C0C0C0019191919FFFFFFFFFFFF"
|
||||
$"FFFFFFFFFF00001212121212123F3F193F0C0C0C0019191919FFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFF00001212121212123F0C0C0C0019191919FFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFF000012121212000C0C0019191919FFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFF00001212000C0019191919FFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFF0000000019191919FFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0019191919FFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||
};
|
||||
|
||||
resource(1, "BEOS:FILE_TYPES") message;
|
||||
|
||||
resource(1, "BEOS:APP_SIG") #'MIMS' "application/x-vnd.Haiku-calculator";
|
||||
|
||||
resource(1, "BEOS:APP_VERSION") #'APPV' array {
|
||||
$"010000000000000000000000000000000000000043616C63756C61746F720000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000536369656E74696669632043"
|
||||
$"616C63756C61746F722077697468205265706C6963616E7420546563686E6F6C"
|
||||
$"6F67790000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
$"0000000000000000"
|
||||
};
|
||||
|
||||
resource(1, "BEOS:APP_FLAGS") #'APPF' $"01000000";
|
173
src/apps/calculator/FrameView.cpp
Normal file
173
src/apps/calculator/FrameView.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Peter Wagner <pwagner@stanfordalumni.org>
|
||||
*/
|
||||
#include <Button.h>
|
||||
#include "FrameView.h"
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
A FrameView is a subclass of a BView that draws a simple beveled
|
||||
rectangle just inside the view's bounds.
|
||||
|
||||
The bevel_style parameter is currently unused--the only style available
|
||||
is a 1-pixel inset bevel.
|
||||
|
||||
The contents of the view are erased to the "view color." The left and
|
||||
top edges are drawn in the view's high color and the right and bottom
|
||||
edges are drawn inthe view's low color. You may set the high, low,
|
||||
and view colors after creation to customize the FrameView's look.
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
BArchivable *FrameView::Instantiate(BMessage *archive)
|
||||
{
|
||||
if ( validate_instantiation(archive, "FrameView"))
|
||||
return new FrameView(archive);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
FrameView::FrameView(BRect frame, const char *name,
|
||||
ulong resizeMask, int in_bevel_indent)
|
||||
: BView(frame, name, resizeMask, B_WILL_DRAW|B_FRAME_EVENTS)
|
||||
{
|
||||
static const rgb_color c = {215, 215, 215, 0};
|
||||
ColoringBasis(c);
|
||||
bevel_indent = in_bevel_indent;
|
||||
}
|
||||
|
||||
|
||||
FrameView::FrameView(BMessage *data)
|
||||
: BView(data)
|
||||
{
|
||||
static const rgb_color c = {215, 215, 215, 0};
|
||||
ColoringBasis(c);
|
||||
|
||||
int32 i;
|
||||
if(data->FindInt32("bevel_indent", &i) != B_OK)
|
||||
i = 1;
|
||||
if(i < 0)
|
||||
i = 0;
|
||||
if(i > 10)
|
||||
i = 10;
|
||||
bevel_indent = i;
|
||||
}
|
||||
|
||||
|
||||
void FrameView::MouseDown(BPoint where)
|
||||
{
|
||||
// Pass unused mouse clicks up the view hierarchy.
|
||||
BView *view = Parent();
|
||||
if(view != NULL)
|
||||
view->MouseDown(where);
|
||||
}
|
||||
|
||||
|
||||
FrameView::FrameView(const BPoint &where, const char *name, uint32 resizeMask,
|
||||
int items_wide, int items_high,
|
||||
int bevel, int key_border, int key_height, int key_width,
|
||||
const ClusterInfo button_info[])
|
||||
: BView(BRect(where.x-bevel, where.y-bevel,
|
||||
where.x+bevel+key_border+items_wide*(key_border+key_width)-1,
|
||||
where.y+bevel+key_border+items_high*(key_border+key_height)-1),
|
||||
name, resizeMask, B_WILL_DRAW|B_FRAME_EVENTS)
|
||||
{
|
||||
static const rgb_color c = {215, 215, 215, 0};
|
||||
ColoringBasis(c);
|
||||
bevel_indent = bevel;
|
||||
|
||||
for (int y=0; y<items_high; y++) {
|
||||
for (int x=0; x<items_wide; x++) {
|
||||
const ClusterInfo *info = &(button_info[x + y*items_wide]);
|
||||
char name[5];
|
||||
char *p=name;
|
||||
for (int i=0; i<4; i++)
|
||||
if (((info->message >> (24-8*i)) & 0x00FF) != 0)
|
||||
*p++ = (char)(info->message >> (24-8*i));
|
||||
*p = '\0';
|
||||
if (info->message != 0) {
|
||||
BRect r;
|
||||
r.left = bevel_indent + key_border + x*(key_border+key_width);
|
||||
r.right = r.left + key_width;
|
||||
r.top = bevel_indent + key_border + y*(key_border+key_height);
|
||||
r.bottom = r.top + key_height;
|
||||
BMessage *msg = new BMessage(info->message);
|
||||
BButton *button = new BButton(r, name, info->label, msg);
|
||||
AddChild(button);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t FrameView::Archive(BMessage *msg, bool deep) const
|
||||
{
|
||||
BView::Archive(msg, deep);
|
||||
msg->AddString("class", "FrameView");
|
||||
msg->AddInt32("bevel_indent", (int32)bevel_indent);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
#define min(x,y) ((x<y)?x:y)
|
||||
#define max(x,y) ((x>y)?x:y)
|
||||
|
||||
void FrameView::ColoringBasis(rgb_color basis_color)
|
||||
{
|
||||
rgb_color view_color = basis_color;
|
||||
view_color.red = min(view_color.red+15, 255);
|
||||
view_color.green = min(view_color.green+15, 255);
|
||||
view_color.blue = min(view_color.blue+15, 255);
|
||||
SetViewColor(view_color);
|
||||
|
||||
rgb_color hi_color = basis_color;
|
||||
hi_color.red = max(hi_color.red-45, 0);
|
||||
hi_color.green = max(hi_color.green-45, 0);
|
||||
hi_color.blue = max(hi_color.blue-45, 0);
|
||||
SetHighColor(hi_color);
|
||||
|
||||
rgb_color low_color = basis_color;
|
||||
low_color.red = min(low_color.red+45, 255);
|
||||
low_color.green = min(low_color.green+45, 255);
|
||||
low_color.blue = min(low_color.blue+45, 255);
|
||||
SetLowColor(low_color);
|
||||
}
|
||||
|
||||
|
||||
void FrameView::AttachedToWindow()
|
||||
{
|
||||
BView *view = Parent();
|
||||
if (view != NULL)
|
||||
ColoringBasis(view->ViewColor());
|
||||
}
|
||||
|
||||
|
||||
void FrameView::Draw(BRect)
|
||||
{
|
||||
BRect r = Bounds();
|
||||
|
||||
// r.InsetBy(bevel_indent/2, bevel_indent/2);
|
||||
// SetPenSize(bevel_indent);
|
||||
|
||||
for (int i=0; i<bevel_indent; i++) {
|
||||
StrokeLine(r.RightTop(), r.RightBottom(), B_SOLID_LOW);
|
||||
StrokeLine(r.RightBottom(), r.LeftBottom(), B_SOLID_LOW);
|
||||
StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
|
||||
StrokeLine(r.LeftBottom(), r.LeftTop(), B_SOLID_HIGH);
|
||||
r.InsetBy(1,1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FrameView::FrameResized(float new_width, float new_height)
|
||||
{
|
||||
BRect r = Bounds();
|
||||
r.InsetBy(bevel_indent,bevel_indent);
|
||||
rgb_color old_color = HighColor();
|
||||
SetHighColor(ViewColor());
|
||||
FillRect(r);
|
||||
SetHighColor(old_color);
|
||||
Draw(Bounds());
|
||||
}
|
45
src/apps/calculator/FrameView.h
Normal file
45
src/apps/calculator/FrameView.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Peter Wagner <pwagner@stanfordalumni.org>
|
||||
*/
|
||||
#ifndef __FRAME_VIEW__
|
||||
#define __FRAME_VIEW__
|
||||
|
||||
#include <View.h>
|
||||
|
||||
class _EXPORT FrameView : public BView
|
||||
{
|
||||
public:
|
||||
FrameView(BRect frame, const char *name,
|
||||
uint32 resizeMask, int bevel_indent=1);
|
||||
FrameView(BMessage *data);
|
||||
virtual status_t Archive(BMessage *msg, bool deep) const;
|
||||
static BArchivable * Instantiate(BMessage *archive);
|
||||
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void FrameResized(float new_width, float new_height);
|
||||
virtual void AttachedToWindow();
|
||||
void MouseDown(BPoint where);
|
||||
|
||||
void ColoringBasis(rgb_color view_color);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *label;
|
||||
uint32 message;
|
||||
} ClusterInfo;
|
||||
|
||||
FrameView(const BPoint &where, const char *name,
|
||||
uint32 resizeMask, int items_wide,
|
||||
int items_high, int bevel, int key_border,
|
||||
int key_height, int key_width,
|
||||
const ClusterInfo button_info[]);
|
||||
private:
|
||||
int bevel_indent;
|
||||
};
|
||||
|
||||
#endif
|
14
src/apps/calculator/Jamfile
Normal file
14
src/apps/calculator/Jamfile
Normal file
@ -0,0 +1,14 @@
|
||||
SubDir HAIKU_TOP src apps calculator ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
Application Calculator :
|
||||
CalcEngine.cpp
|
||||
Calculator.cpp
|
||||
CalcView.cpp
|
||||
CalcWindow.cpp
|
||||
FrameView.cpp
|
||||
Prefs.cpp
|
||||
: be
|
||||
: Calculator.rdef
|
||||
;
|
50
src/apps/calculator/Prefs.cpp
Normal file
50
src/apps/calculator/Prefs.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Peter Wagner <pwagner@stanfordalumni.org>
|
||||
*/
|
||||
#include <StorageKit.h>
|
||||
#include <string.h>
|
||||
#include <iostream.h>
|
||||
#include "Prefs.h"
|
||||
|
||||
bool ReadPrefs(const char *prefsname, void *prefs, size_t sz)
|
||||
{
|
||||
BPath path;
|
||||
find_directory(B_USER_SETTINGS_DIRECTORY, &path, true);
|
||||
|
||||
BDirectory dir;
|
||||
dir.SetTo(path.Path());
|
||||
|
||||
BEntry entry;
|
||||
if (dir.FindEntry(prefsname, &entry) == B_OK) {
|
||||
BFile file(&entry, O_RDONLY);
|
||||
if (file.InitCheck() == B_OK) {
|
||||
if ((size_t)file.Read(prefs, sz) == sz)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
memset(prefs, 0, sz);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool WritePrefs(const char *prefsname, void *prefs, size_t sz)
|
||||
{
|
||||
BPath path;
|
||||
find_directory(B_USER_SETTINGS_DIRECTORY, &path, true);
|
||||
|
||||
BDirectory dir;
|
||||
dir.SetTo(path.Path());
|
||||
|
||||
BFile file;
|
||||
if (dir.CreateFile(prefsname, &file, false) == B_OK) {
|
||||
if ((size_t)file.Write(prefs, sz) == sz)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
14
src/apps/calculator/Prefs.h
Normal file
14
src/apps/calculator/Prefs.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Peter Wagner <pwagner@stanfordalumni.org>
|
||||
*/
|
||||
#ifndef __PREFS__
|
||||
#define __PREFS__
|
||||
|
||||
bool ReadPrefs(const char *prefsname, void *prefs, size_t sz);
|
||||
bool WritePrefs(const char *prefsname, void *prefs, size_t sz);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user