represents a calculator application that performs arithmetic operations on numbers.
#include <xtd/forms/application>
#include <xtd/forms/button>
#include <xtd/forms/form>
#include <xtd/forms/label>
#include <xtd/startup>
#include <array>
namespace calculator {
class form_main :
public form {
enum class operators {
equal
};
public:
static auto main() {
}
form_main() {
maximize_box(false);
key_press += key_press_event_handler(*this, &form_main::form_main_key_press);
result.bounds({0, 0, 240, 60});
result.parent(*this);
result.text("0");
button_clear.parent(*this);
.border_radius(0)
.border_size(0));
button_clear.location({0, 60});
button_clear.text("C");
button_clear.size({60, 50});
button_clear.click += event_handler(*this, &form_main::button_clear_click);
button_plus_minus.parent(*this);
.border_radius(0)
.border_size(0));
button_plus_minus.location({61, 60});
button_plus_minus.text("+/-");
button_plus_minus.size({60, 50});
button_plus_minus.click += event_handler(*this, &form_main::button_plus_minus_click);
button_percent.parent(*this);
.border_radius(0)
.border_size(0));
button_percent.location({122, 60});
button_percent.text("%");
button_percent.size({60, 50});
button_percent.click += event_handler(*this, &form_main::button_percent_click);
button_decimal.parent(*this);
.border_radius(0)
.border_size(0));
button_decimal.location({122, 264});
button_decimal.text(".");
button_decimal.size({60, 50});
button_decimal.click += event_handler(*this, &form_main::button_number_click);
generic::list<xtd::drawing::point> button_number_locations = {{0, 264}, {0, 213}, {61, 213}, {122, 213}, {0, 162}, {61, 162}, {122, 162}, {0, 111}, {61, 111}, {122, 111}};
for (
int i = 0;
i < 10;
i++) {
button_numbers[
i].parent(*
this);
.border_radius(0)
.border_size(0));
button_numbers[
i].text(string::format(
"{}",
i));
button_numbers[
i].location(button_number_locations[
i]);
button_numbers[
i].size({60, 50});
button_numbers[
i].click += event_handler(*
this, &form_main::button_number_click);
}
button_numbers[0].width(121);
for (
int i = 0;
i < 5;
i++) {
button_operators[
i].parent(*
this);
.border_radius(0)
.border_size(0));
button_operators[
i].text(button_operator_texts[
i]);
button_operators[
i].location(button_operator_locations[
i]);
button_operators[
i].size({60, 50});
button_operators[
i].click += event_handler(*
this, &form_main::button_operator_click);
}
}
if (
e.key_char() >=
'0' &&
e.key_char() <=
'9') {
button_numbers[
e.key_char() -
'0'].perform_click();
return;
}
case 'c' : button_clear.perform_click();
e.handled(
true);
break;
case 'C' : button_clear.perform_click();
e.handled(
true);
break;
case '%' : button_percent.perform_click();
e.handled(
true);
break;
case ',' : button_decimal.perform_click();
e.handled(
true);
break;
case '.' : button_decimal.perform_click();
e.handled(
true);
break;
case '/' : button_operators[
as<int>(operators::divide)].perform_click();
e.handled(
true);
break;
case '*' : button_operators[
as<int>(operators::multiply)].perform_click();
e.handled(
true);
break;
case '-' : button_operators[
as<int>(operators::subtract)].perform_click();
e.handled(
true);
break;
case '+' : button_operators[
as<int>(operators::add)].perform_click();
e.handled(
true);
break;
case '=' : button_operators[
as<int>(operators::equal)].perform_click();
e.handled(
true);
break;
case 13 : button_operators[
as<int>(operators::equal)].perform_click();
e.handled(
true);
break;
case 127 : back_space_key_press(sender,
e);
e.handled(
true);
break;
}
}
void back_space_key_press(
object& sender,
const event_args&
e) {
if (result.text().length() > 0) result.text(
as<string>(result.text()).remove(result.text().length() - 1));
if (result.text().length() == 0 || result.text() ==
"-") button_clear_click(sender,
e);
}
void button_clear_click(
object& sender,
const event_args&
e) {
result.text("0");
first_operand.reset();
second_operand.reset();
operation = operators::none;
}
void button_percent_click(
object& sender,
const event_args&
e) {
result.text(string::format(
"{}",
parse<double>(result.text()) / 100));
}
void button_plus_minus_click(
object& sender,
const event_args&
e) {
if (result.text() !=
"0" && result.text() !=
"0.") result.text(string::format(
"{}", -
parse<double>(result.text())));
}
void button_number_click(
object& sender,
const event_args&
e) {
if ((
as<control>(sender).handle() == button_decimal.handle() &&
as<string>(result.text()).contains(
".")) || (result.text() ==
"0" &&
as<control>(sender).handle() == button_numbers[0].handle()))
return;
if ((first_operand.has_value() && first_operand ==
parse<double>(result.text())) || (result.text() ==
"0" &&
as<control>(sender).handle() != button_decimal.handle())) result.text(
"");
if (second_operand.has_value()) second_operand.reset();
result.text(result.text() +
as<control>(sender).text());
}
void button_operator_click(
object& sender,
const event_args&
e) {
if (!first_operand.has_value()) first_operand =
parse<double>(result.text());
else {
if (!second_operand.has_value()) second_operand =
parse<double>(result.text());
switch (operation) {
case operators::none: break;
case operators::divide: result.text(string::format("{}", first_operand.value() / second_operand.value())); break;
case operators::multiply: result.text(string::format("{}", first_operand.value() * second_operand.value())); break;
case operators::subtract: result.text(string::format("{}", first_operand.value() - second_operand.value())); break;
case operators::add: result.text(string::format("{}", first_operand.value() + second_operand.value())); break;
default: break;
}
}
operation = std::map<string, operators> {{
"÷", operators::divide}, {
"x", operators::multiply}, {
"-", operators::subtract}, {
"+", operators::add}, {
"=", operation}} [
as<control>(sender).text()];
if (second_operand.has_value()) first_operand.reset();
second_operand.reset();
}
}
private:
std::array<button, 10> button_numbers;
std::array<button, 5> button_operators;
std::optional<double> first_operand;
std::optional<double> second_operand;
operators operation = operators::none;
};
}
Represents a strongly typed list of objects that can be accessed by index. Provides methods to search...
Definition list.hpp:80
static const xtd::drawing::color white
Gets a system-defined color that has an ARGB value of 0xFFFFFFFF. This field is constant.
Definition color.hpp:470
static xtd::drawing::color from_argb(uint32 argb) noexcept
Creates a xtd::drawing::color class from a 32-bit ARGB value.
static font_family generic_sans_serif() noexcept
Gets a generic sans serif font_family.
Defines a particular format for text, including font face, size, and style attributes....
Definition font.hpp:45
Represents the base class for classes that contain event data, and provides a value to use for events...
Definition event_args.hpp:18
#define startup_(main_method)
Defines the entry point to be called when the application loads. Generally this is set either to the ...
Definition startup.hpp:167
size_t size
Represents a size of any object in bytes.
Definition size.hpp:23
type_t as(any_object &o)
Casts a type into another type.
Definition __as_any_object.hpp:59
value_t parse(const std::string &str)
Convert a string into a type.
Definition parse.hpp:34
@ none
No modifier key.
Definition console_modifiers.hpp:22
@ multiply
The Multiply key.
Definition console_key.hpp:168
@ add
The Add key.
Definition console_key.hpp:170
@ i
The I key.
Definition console_key.hpp:104
@ divide
The Divide key.
Definition console_key.hpp:178
@ subtract
The Subtract key.
Definition console_key.hpp:174
@ e
The E key.
Definition console_key.hpp:96
The xtd::collections namespace contains interfaces and classes that define various collections of obj...
Definition any_pair.hpp:10
Contains classes that represent ASCII and Unicode character encodings; abstract base classes for conv...
Definition basic_string_builder.hpp:16
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition abstract_object.hpp:8