xref: /haiku/src/apps/deskcalc/CalcWindow.cpp (revision 427edfcf0ddc74fc461c9355484d33fd4b027b70)
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 
33 CalcWindow::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 
77 CalcWindow::~CalcWindow()
78 {
79 }
80 
81 
82 void
83 CalcWindow::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 
121 void
122 CalcWindow::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 
133 bool
134 CalcWindow::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 
145 status_t
146 CalcWindow::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 
156 void
157 CalcWindow::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