1/*
2 * Copyright 2006-2012 Haiku, Inc. All Rights Reserved.
3 * Copyright 1997, 1998 R3 Software Ltd. All Rights Reserved.
4 * Distributed under the terms of the MIT License.
5 *
6 * Authors:
7 *		Stephan A��mus, superstippi@gmx.de
8 *		John Scipione, jscipione@gmail.com
9 *		Timothy Wayper, timmy@wunderbear.com
10 */
11
12
13#include "CalcWindow.h"
14
15#include <stdlib.h>
16#include <stdio.h>
17#include <assert.h>
18
19#include <Application.h>
20#include <Catalog.h>
21#include <Dragger.h>
22#include <Screen.h>
23
24#include "CalcApplication.h"
25#include "CalcOptions.h"
26#include "CalcView.h"
27
28
29#undef B_TRANSLATION_CONTEXT
30#define B_TRANSLATION_CONTEXT "Window"
31
32
33CalcWindow::CalcWindow(BRect frame, BMessage* settings)
34	:
35	BWindow(frame, kAppName, B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS
36		| B_NOT_ANCHORED_ON_ACTIVATE)
37{
38	// create calculator view with calculator description and
39	// desktop background color
40	BScreen screen(this);
41	rgb_color baseColor = screen.DesktopColor();
42
43	// Size Limits are defined in CalcView.h
44	SetSizeLimits(kMinimumWidthBasic, kMaximumWidthBasic,
45		kMinimumHeightBasic, kMaximumHeightBasic);
46
47	frame.OffsetTo(B_ORIGIN);
48	fCalcView = new CalcView(Frame(), baseColor, settings);
49
50	// create replicant dragger
51	BRect replicantFrame(frame);
52	replicantFrame.top = replicantFrame.bottom - 7.0f;
53	replicantFrame.left = replicantFrame.right - 7.0f;
54	BDragger* dragger = new BDragger(replicantFrame, fCalcView,
55		B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
56
57	// attach views
58	AddChild(fCalcView);
59	fCalcView->AddChild(dragger);
60
61	BRect rect;
62	if (settings->FindRect("window frame", &rect) == B_OK)
63		SetFrame(rect);
64	else
65		SetFrame(frame, true);
66
67	// Add shortcut keys to menu options
68	AddShortcut('0', B_COMMAND_KEY,
69		new BMessage(MSG_OPTIONS_KEYPAD_MODE_COMPACT));
70	AddShortcut('1', B_COMMAND_KEY,
71		new BMessage(MSG_OPTIONS_KEYPAD_MODE_BASIC));
72	AddShortcut('2', B_COMMAND_KEY,
73		new BMessage(MSG_OPTIONS_KEYPAD_MODE_SCIENTIFIC));
74}
75
76
77CalcWindow::~CalcWindow()
78{
79}
80
81
82void
83CalcWindow::MessageReceived(BMessage* message)
84{
85	switch (message->what) {
86		case MSG_OPTIONS_AUTO_NUM_LOCK:
87			fCalcView->ToggleAutoNumlock();
88			break;
89
90		case MSG_OPTIONS_AUDIO_FEEDBACK:
91			fCalcView->ToggleAudioFeedback();
92			break;
93
94		case MSG_OPTIONS_ANGLE_MODE_RADIAN:
95			fCalcView->SetDegreeMode(false);
96			return;
97
98		case MSG_OPTIONS_ANGLE_MODE_DEGREE:
99			fCalcView->SetDegreeMode(true);
100			return;
101
102		case MSG_OPTIONS_KEYPAD_MODE_COMPACT:
103			fCalcView->SetKeypadMode(KEYPAD_MODE_COMPACT);
104			break;
105
106		case MSG_OPTIONS_KEYPAD_MODE_BASIC:
107			fCalcView->SetKeypadMode(KEYPAD_MODE_BASIC);
108			break;
109
110		case MSG_OPTIONS_KEYPAD_MODE_SCIENTIFIC:
111			fCalcView->SetKeypadMode(KEYPAD_MODE_SCIENTIFIC);
112			break;
113
114		default:
115			BWindow::MessageReceived(message);
116			break;
117	}
118}
119
120
121void
122CalcWindow::Show()
123{
124	// NOTE: done here because the CalcView
125	// turns on numlock if the options say so...
126	// so we want to call MakeFocus() after
127	// the options have been read for sure...
128	fCalcView->MakeFocus();
129	BWindow::Show();
130}
131
132
133bool
134CalcWindow::QuitRequested()
135{
136	be_app->PostMessage(B_QUIT_REQUESTED);
137	Hide();
138
139	// NOTE: don't quit, since the app needs us
140	// for saving settings yet...
141	return false;
142}
143
144
145status_t
146CalcWindow::SaveSettings(BMessage* archive) const
147{
148	status_t ret = archive->AddRect("window frame", Frame());
149	if (ret < B_OK)
150		return ret;
151
152	return fCalcView->SaveSettings(archive);
153}
154
155
156void
157CalcWindow::SetFrame(BRect frame, bool forceCenter)
158{
159	// make sure window frame is on screen (center, if not)
160	BScreen screen(this);
161	BRect screenFrame = screen.Frame();
162	if (forceCenter || !screenFrame.Contains(frame)) {
163		float left = (screenFrame.Width() - frame.Width()) / 2.0;
164		float top = (screenFrame.Height() - frame.Height()) / 2.0;
165		left += screenFrame.left;
166		top += screenFrame.top;
167		frame.OffsetTo(left, top);
168	}
169
170	MoveTo(frame.left, frame.top);
171	ResizeTo(frame.Width(), frame.Height());
172}
173