xtd 0.2.0
Loading...
Searching...
No Matches
painting.cpp

demonstrates the use of xtd::forms::form controls with mouse_down, mouse_move and paint events.

Windows

macOS

Gnome

#include <xtd/drawing/pens>
#include <xtd/forms/application>
#include <xtd/forms/button>
#include <xtd/forms/form>
#include <xtd/forms/label>
#include <xtd/forms/message_box>
#include <xtd/forms/numeric_up_down>
#include <xtd/forms/open_file_dialog>
#include <xtd/forms/panel>
#include <xtd/forms/track_bar>
using namespace std;
using namespace xtd;
using namespace xtd::drawing;
using namespace xtd::forms;
namespace painting_example {
class form1 : public form {
public:
form1() {
text("Painting example");
client_size({640, 480});
panel_colors_container.parent(*this);
panel_colors_container.border_style(forms::border_style::fixed_single);
panel_colors_container.location({10, 10});
panel_colors_container.client_size({512, 32});
for (auto color : {color::dark_magenta, color::dark_cyan, color::brown, color::dark_blue, color::dark_green, color::dark_red, color::gray, color::dark_gray, color::magenta, color::cyan, color::yellow, color::blue, color::green, color::red, color::white, color::black}) {
auto panel_color = make_shared<panel>();
panel_color->parent(panel_colors_container);
panel_color->size({32, 32});
panel_color->back_color(color);
panel_color->dock(dock_style::left);
panel_color->click += event_handler {*this, &form1::choose_current_color};
panel_colors.push_back(panel_color);
}
current_color = panel_colors[panel_colors.size() - 1]->back_color();
panel_colors[panel_colors.size() - 1]->border_style(forms::border_style::fixed_single);
button_clear.parent(*this);
button_clear.text("Clear");
button_clear.location({542, 13});
button_clear.click += [&] {
picture = bitmap {picture.width(), picture.height()};
panel_painting.invalidate();
};
button_open.parent(*this);
button_open.text("Open...");
button_open.location({542, 47});
button_open.click += [&] {
if (ofd.show_dialog() == forms::dialog_result::ok) {
bitmap new_picture(ofd.file_name());
if (new_picture.width() > 128 || new_picture.height() > 128)
message_box::show(*this, "The size of the image must be less than or equal to 128 x 128 pixels.", "Painting example", message_box_buttons::ok, message_box_icon::error);
else {
picture = new_picture;
panel_painting.size({picture.width() * zoom, picture.height() * zoom});
panel_painting.invalidate();
}
}
};
label_zoom.parent(*this);
label_zoom.auto_size(false);
label_zoom.location({10, 60});
label_zoom.anchor(anchor_styles::top | anchor_styles::left);
label_zoom.text("Zoom");
track_bar_zoom.parent(*this);
track_bar_zoom.auto_size(false);
track_bar_zoom.location({60, 55});
track_bar_zoom.anchor(anchor_styles::top | anchor_styles::left);
track_bar_zoom.set_range(1, 50);
track_bar_zoom.tick_style(forms::tick_style::none);
track_bar_zoom.value(zoom);
track_bar_zoom.value_changed += [&] {
zoom = track_bar_zoom.value();
numeric_up_down_zoom.value(zoom);
panel_painting.size({picture.width() * zoom, picture.height() * zoom});
panel_painting.invalidate();
};
track_bar_zoom.size({390, 25});
numeric_up_down_zoom.parent(*this);
numeric_up_down_zoom.location({470, 55});
numeric_up_down_zoom.set_range(1, 50);
numeric_up_down_zoom.value(zoom);
numeric_up_down_zoom.value_changed += [&] {
zoom = as<int>(numeric_up_down_zoom.value());
track_bar_zoom.value(zoom);
panel_painting.size({picture.width() * zoom, picture.height() * zoom});
panel_painting.invalidate();
};
numeric_up_down_zoom.width(52);
panel_main.parent(*this);
panel_main.auto_scroll(true);
panel_main.border_style(forms::border_style::fixed_single);
panel_main.location({10, 90});
panel_main.size({620, 380});
panel_main.anchor(anchor_styles::top | anchor_styles::left | anchor_styles::bottom | anchor_styles::right);
panel_painting.parent(panel_main);
panel_painting.back_color(color::white_smoke);
panel_painting.size({picture.width() * zoom, picture.height() * zoom});
panel_painting.mouse_down += [&](object & sender, const mouse_event_args & e) {
if (e.x() / zoom >= 0 && e.x() / zoom < picture.width() && e.y() / zoom >= 0 && e.y() / zoom < picture.height()) {
picture.set_pixel(e.x() / zoom, e.y() / zoom, e.button() == mouse_buttons::left ? current_color : color::from_argb(0, 0, 0, 0));
panel_painting.invalidate(rectangle(e.x() / zoom * zoom, e.y() / zoom * zoom, zoom, zoom));
}
};
panel_painting.mouse_move += [&](object & sender, const mouse_event_args & e) {
if (e.button() == mouse_buttons::left && e.x() / zoom >= 0 && e.x() / zoom < picture.width() && e.y() / zoom >= 0 && e.y() / zoom < picture.height()) {
picture.set_pixel(e.x() / zoom, e.y() / zoom, current_color);
panel_painting.invalidate(rectangle(e.x() / zoom * zoom, e.y() / zoom * zoom, zoom, zoom));
}
};
panel_painting.paint += [&](object & sender, paint_event_args & e) {
for (auto y = 0; y < panel_painting.client_size().height(); y += zoom)
for (auto x = 0; x < panel_painting.client_size().width(); x += zoom)
if (picture.get_pixel(x / zoom, y / zoom) != color::from_argb(0, 0, 0, 0))
e.graphics().fill_rectangle(solid_brush(picture.get_pixel(x / zoom, y / zoom)), x, y, zoom, zoom);
if (zoom > 3) {
for (auto index = 0; index < panel_painting.client_size().width(); index += zoom)
e.graphics().draw_line(pens::light_blue(), index, 0, index, panel_painting.client_size().height());
for (auto index = 0; index < panel_painting.client_size().height(); index += zoom)
e.graphics().draw_line(pens::light_blue(), 0, index, panel_painting.client_size().width(), index);
}
};
}
private:
void choose_current_color(object& sender, const event_args& e) {
for (auto panel : panel_colors)
panel->border_style(panel->handle() != as<control>(sender).handle() ? forms::border_style::none : forms::border_style::fixed_single);
current_color = as<control>(sender).back_color();
}
int zoom = 20;
drawing::color current_color;
bitmap picture {32, 32};
panel panel_colors_container;
vector<shared_ptr<panel>> panel_colors;
button button_clear;
button button_open;
panel panel_main;
panel panel_painting;
label label_zoom;
track_bar track_bar_zoom;
numeric_up_down numeric_up_down_zoom;
};
}
auto main()->int {
application::run(painting_example::form1 {});
}
Encapsulates a GDI+ bitmap, which consists of the pixel data for a graphics image and its attributes....
Definition bitmap.h:26
Represents an ARGB (alpha, red, green, blue) color.
Definition color.h:49
int32 height() const noexcept
Gets the height, in pixels, of this image.
int32 width() const noexcept
Gets the width, in pixels, of this image.
const drawing::size & size() const noexcept
Gets the width and height, in pixels, of this image.
Stores a set of four integers that represent the location and size of a rectangle.
Definition rectangle.h:44
Defines a xtd::drawing::brush of a single color. Brushes are used to fill graphics shapes,...
Definition solid_brush.h:30
Represents the base class for classes that contain event data, and provides a value to use for events...
Definition event_args.h:18
Represents a Windows button control.
Definition button.h:47
xtd::forms::dialog_result show_dialog()
Runs a common dialog box with a default owner.
intptr handle() const override
Gets the window handle that the control is bound to.
virtual const xtd::ustring & file_name() const noexcept
Gets a string containing the file name selected in the file dialog box.
Represents a window or dialog box that makes up an application's user interface.
Definition form.h:52
Represents a standard Windows label.
Definition label.h:36
Provides data for the xtd::forms::control::mouse_up, xtd::forms::control::mouse_down,...
Definition mouse_event_args.h:32
Represents a standard Windows numeric up down.
Definition numeric_up_down.h:32
Displays a standard dialog box that prompts the user to open a file. This class cannot be inherited.
Definition open_file_dialog.h:28
Provides data for the xtd::forms::control::paint event.
Definition paint_event_args.h:28
Used to group collections of controls.
Definition panel.h:30
virtual forms::border_style border_style() const noexcept
Gets the border style for the control.
Represents a standard Windows track bar.
Definition track_bar.h:32
generic_event_handler<> event_handler
Represents the method that will handle an event that has no event data.
Definition event_handler.h:32
The xtd::drawing namespace provides access to GDI+ basic graphics functionality. More advanced functi...
Definition actions_system_images.h:11
The xtd::forms namespace contains classes for creating Windows-based applications that take full adva...
Definition xtd_about_box.h:12
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition xtd_about_box.h:10