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