Add gtk135
This commit is contained in:
parent
f85d430a5f
commit
f9fa84b639
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools"
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
set(CMAKE_CXX_STANDARD 17)
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
project(gtk129_drawing2 VERSION 1.0.0)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../GCR_CMake/macros)
|
||||
include(GlibCompileResourcesSupport)
|
||||
|
||||
include(CTest)
|
||||
enable_testing()
|
||||
|
||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
||||
|
||||
include(CPack)
|
||||
include_directories(.)
|
||||
include_directories(..)
|
||||
|
||||
#Find PkgConfig to use gtkmm3
|
||||
find_package (PkgConfig REQUIRED)
|
||||
pkg_check_modules (GTKMM3 REQUIRED gtkmm-3.0)
|
||||
include_directories (${GTKMM3_INCLUDE_DIRS})
|
||||
link_directories (${GTKMM3_LIBRARY_DIRS})
|
||||
|
||||
#Find Gettext
|
||||
find_package (Gettext REQUIRED)
|
||||
set(PO_DIR ${CMAKE_BINARY_DIR}/po/zh_CN/LC_MESSAGES)
|
||||
|
||||
#Source files
|
||||
set(SOURCE_FILE src/main.cc src/drawing.cc)
|
||||
|
||||
#Compile Resource
|
||||
|
||||
set(RESOURCE_LIST
|
||||
icons/scalable/status/circle.svg
|
||||
icons/scalable/status/freehand.svg
|
||||
icons/scalable/status/line.svg
|
||||
icons/scalable/status/rectangle.svg)
|
||||
|
||||
compile_gresources(RESOURCE_FILE
|
||||
XML_OUT
|
||||
TYPE EMBED_C
|
||||
RESOURCES ${RESOURCE_LIST}
|
||||
PREFIX "/org/gtk/daleclack"
|
||||
SOURCE_DIR ${PROJECT_SOURCE_DIR}/res)
|
||||
|
||||
# Add a custom target to the makefile. Now make builds our resource file.
|
||||
# It depends on the output RESOURCE_FILE.
|
||||
|
||||
add_custom_target(resource ALL DEPENDS ${RESOURCE_FILE})
|
||||
|
||||
#For win32 platform,use rc resource and .ico icon
|
||||
if(WIN32)
|
||||
SET(CMAKE_RC_COMPILER windres)
|
||||
set(app_WINRC ../icon.rc)
|
||||
set_property(SOURCE ../icon.rc APPEND PROPERTY
|
||||
OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/../icon.ico
|
||||
)
|
||||
add_executable(${PROJECT_NAME} WIN32 ${app_WINRC} ${SOURCE_FILE} ${RESOURCE_FILE})
|
||||
add_custom_command( TARGET ${PROJECT_NAME}
|
||||
COMMAND echo * > ${CMAKE_BINARY_DIR}/.gitignore
|
||||
COMMAND echo **/* > ${CMAKE_BINARY_DIR}/.hgignore)
|
||||
else()
|
||||
add_executable(${PROJECT_NAME} ${SOURCE_FILE} ${RESOURCE_FILE})
|
||||
add_custom_command( TARGET ${PROJECT_NAME}
|
||||
COMMAND echo \"*\" > ${CMAKE_BINARY_DIR}/.gitignore
|
||||
COMMAND echo \"**/*\" > ${CMAKE_BINARY_DIR}/.hgignore)
|
||||
endif(WIN32)
|
||||
|
||||
#Add command to generate .gitignore and .mo files
|
||||
# add_custom_command( TARGET ${PROJECT_NAME}
|
||||
# COMMAND mkdir -p ${PO_DIR}
|
||||
# COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} ${CMAKE_SOURCE_DIR}/po/zh_CN.po -o ${PO_DIR}/${PROJECT_NAME}.mo)
|
||||
|
||||
SET (CMAKE_EXTRA_CXX_FLAGS ${GTKMM3_CFLAGS_OTHER})
|
||||
target_link_libraries (${PROJECT_NAME} ${GTKMM3_LIBRARIES} -lpthread)
|
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#363636;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M8 2A6 6 0 0 0 2 8 6 6 0 0 0 8 14 6 6 0 0 0 14 8 6 6 0 0 0 8 2M8 3A5 5 0 0 1 13 8 5 5 0 0 1 8 13 5 5 0 0 1 3 8 5 5 0 0 1 8 3"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 460 B |
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#363636;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 9.15625 2 L 2 9.125 L 2 12 C 3.075 12.019 4.84375 12 4.84375 12 L 12 4.84375 L 9.15625 2 z M 8.4375 4.15625 L 9.84375 5.5625 L 6.9980469 8.4375 L 5.5605469 6.9980469 L 8.4375 4.15625 z M 4.84375 7.71875 L 6.28125 9.125 L 5.5625 9.84375 L 4.15625 8.4375 L 4.84375 7.71875 z M 12.123047 9 C 11.927047 9.001 11.392547 9.0455 10.560547 9.5625 C 10.300547 9.7245 10.107547 9.9089531 9.8105469 10.126953 C 9.6525469 10.242953 9.0850469 10.620953 8.8730469 10.751953 C 8.2540469 11.134953 8.0320469 11.231953 7.4980469 11.501953 C 6.9810469 11.762953 6.4395469 12.000453 6.0605469 12.189453 C 4.4685469 12.984453 1.9960937 13.001953 1.9960938 13.001953 L 1.9960938 14.001953 C 1.9960938 14.001953 4.4935469 14.033953 6.3105469 13.126953 C 6.5515469 13.006953 6.9790469 12.808953 7.3730469 12.626953 C 7.3730469 12.626953 8.4920469 12.034203 8.4980469 12.033203 C 8.6940469 11.924203 8.8592969 11.841203 9.1542969 11.658203 C 9.3822969 11.517203 9.9292969 11.166953 10.154297 11.001953 C 10.484297 10.758953 10.697047 10.579703 10.873047 10.470703 C 11.258047 10.168703 11.693047 9.9889531 12.123047 10.001953 C 12.089047 10.001953 12.253297 10.011703 12.404297 10.095703 C 12.555297 10.179703 12.714797 10.329703 12.841797 10.470703 C 13.086797 10.802703 13.198047 11.055953 13.248047 11.501953 C 13.212047 12.808953 11.968047 13.006953 10.998047 13.001953 L 10.998047 14.001953 C 12.977047 14.090953 13.998047 13.167703 13.998047 11.470703 C 13.994047 11.182703 13.947797 10.945953 13.841797 10.626953 C 13.735797 10.307953 13.575797 9.9514531 13.341797 9.6894531 C 12.980797 9.2664531 12.799047 9.0809531 12.123047 9.0019531 L 12.123047 9 z "
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#363636;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 11 2 L 11 4.3125 L 4.3125 11.001953 L 2.0019531 11.001953 L 2.0019531 14.001953 L 5.0019531 14.001953 L 5.0019531 11.6875 L 11.6875 5 L 14 5 L 14 2 L 11 2 z M 12 3 L 13 3 L 13 4 L 12 4 L 12 3 z M 3 12 L 4 12 L 4 13 L 3 13 L 3 12 z "
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 569 B |
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#363636;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="m2 2v12h12v-12zm1 1h10v10h-10z"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 366 B |
|
@ -0,0 +1,365 @@
|
|||
#include "drawing.hh"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "../../json_nlohmann/json.hpp"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
Drawing::Drawing()
|
||||
: fill_check("Enable Fill Color"),
|
||||
main_label("Select a color"),
|
||||
size_label("Pen Size"),
|
||||
left_box(Gtk::ORIENTATION_VERTICAL, 5),
|
||||
main_box(Gtk::ORIENTATION_HORIZONTAL, 5),
|
||||
btn_box(Gtk::ORIENTATION_VERTICAL, 5),
|
||||
btn_clear("Clear Board"),
|
||||
btn_save("Save to png"),
|
||||
btn_exit("Exit")
|
||||
{
|
||||
// load config from json file
|
||||
int width = 640, height = 480;
|
||||
std::ifstream file1("config.json");
|
||||
if (file1.is_open())
|
||||
{
|
||||
json data = json::parse(file1);
|
||||
width = data["width"];
|
||||
height = data["height"];
|
||||
}
|
||||
|
||||
// Initalize window
|
||||
set_icon_name("org.gtk.daleclack");
|
||||
set_title("Drawing");
|
||||
set_default_size(width, height);
|
||||
|
||||
// Set the buttons grouped and set normal draw mode
|
||||
auto group = btn_free.get_group();
|
||||
btn_free.set_mode(false);
|
||||
btn_circle.set_group(group);
|
||||
btn_circle.set_mode(false);
|
||||
btn_line.set_group(group);
|
||||
btn_line.set_mode(false);
|
||||
btn_rectangle.set_group(group);
|
||||
btn_rectangle.set_mode(false);
|
||||
|
||||
// Add images to the button
|
||||
btn_free.set_image_from_icon_name("freehand");
|
||||
btn_free.set_always_show_image();
|
||||
btn_free.signal_clicked().connect(sigc::mem_fun(*this, &Drawing::btnfree_clicked));
|
||||
btn_circle.set_image_from_icon_name("circle");
|
||||
btn_circle.set_always_show_image();
|
||||
btn_circle.signal_clicked().connect(sigc::mem_fun(*this, &Drawing::btncircle_clicked));
|
||||
btn_line.set_image_from_icon_name("line");
|
||||
btn_line.set_always_show_image();
|
||||
btn_line.signal_clicked().connect(sigc::mem_fun(*this, &Drawing::btnline_clicked));
|
||||
btn_rectangle.set_image_from_icon_name("rectangle");
|
||||
btn_rectangle.set_always_show_image();
|
||||
btn_rectangle.signal_clicked().connect(sigc::mem_fun(*this, &Drawing::btnrectangle_clicked));
|
||||
|
||||
// Left Panel
|
||||
left_box.pack_start(btn_free, Gtk::PACK_SHRINK);
|
||||
left_box.pack_start(btn_circle, Gtk::PACK_SHRINK);
|
||||
left_box.pack_start(btn_line, Gtk::PACK_SHRINK);
|
||||
left_box.pack_start(btn_rectangle, Gtk::PACK_SHRINK);
|
||||
left_box.set_valign(Gtk::ALIGN_START);
|
||||
|
||||
// Color set panel
|
||||
size_adj = Gtk::Adjustment::create(3.0, 1.0, 20.0);
|
||||
scale.set_adjustment(size_adj);
|
||||
scale.set_value_pos(Gtk::POS_BOTTOM);
|
||||
btn_box.pack_start(fill_check, Gtk::PACK_SHRINK);
|
||||
btn_box.pack_start(fill_btn, Gtk::PACK_SHRINK);
|
||||
btn_box.pack_start(main_label, Gtk::PACK_SHRINK);
|
||||
btn_box.pack_start(color_btn, Gtk::PACK_SHRINK);
|
||||
btn_box.pack_start(size_label, Gtk::PACK_SHRINK);
|
||||
btn_box.pack_start(scale, Gtk::PACK_SHRINK);
|
||||
btn_box.pack_start(btn_save, Gtk::PACK_SHRINK);
|
||||
btn_box.pack_start(btn_clear, Gtk::PACK_SHRINK);
|
||||
btn_box.pack_start(btn_exit, Gtk::PACK_SHRINK);
|
||||
btn_box.set_halign(Gtk::ALIGN_CENTER);
|
||||
btn_box.set_valign(Gtk::ALIGN_CENTER);
|
||||
|
||||
// Add Gesture
|
||||
btn_clear.signal_clicked().connect(sigc::mem_fun(*this, &Drawing::btnclear_clicked));
|
||||
btn_save.signal_clicked().connect(sigc::mem_fun(*this, &Drawing::btnsave_clicked));
|
||||
btn_exit.signal_clicked().connect(sigc::mem_fun(*this, &Drawing::hide));
|
||||
|
||||
drag = Gtk::GestureDrag::create(draw_area);
|
||||
drag->set_button(GDK_BUTTON_PRIMARY);
|
||||
drag->signal_drag_begin().connect(sigc::mem_fun(*this, &Drawing::drag_begin));
|
||||
drag->signal_drag_update().connect(sigc::mem_fun(*this, &Drawing::drag_progress));
|
||||
drag->signal_drag_end().connect(sigc::mem_fun(*this, &Drawing::drag_end));
|
||||
|
||||
press = Gtk::GestureMultiPress::create(draw_area);
|
||||
press->set_button();
|
||||
press->signal_pressed().connect(sigc::mem_fun(*this, &Drawing::button_press));
|
||||
|
||||
// Create a Surface
|
||||
surface = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, 600, 480);
|
||||
|
||||
// Set Default Color
|
||||
m_color.set_blue(0);
|
||||
m_color.set_green(0);
|
||||
m_color.set_red(0);
|
||||
m_color.set_alpha(1);
|
||||
color_btn.set_rgba(m_color);
|
||||
color_btn.signal_color_set().connect(sigc::mem_fun(*this, &Drawing::color_set));
|
||||
fill_color = m_color;
|
||||
fill_btn.set_rgba(fill_color);
|
||||
fill_btn.signal_color_set().connect(sigc::mem_fun(*this, &Drawing::color_set));
|
||||
|
||||
// Initalial draw
|
||||
auto cr = Cairo::Context::create(surface);
|
||||
cr->set_source_rgb(1, 1, 1);
|
||||
cr->paint();
|
||||
cr.clear();
|
||||
draw_area.queue_draw();
|
||||
|
||||
// Set Draw mode to default
|
||||
drawing_mode = DrawMode::Default;
|
||||
|
||||
// Initalize main widget
|
||||
draw_area.set_size_request(width - 40, height);
|
||||
draw_area.signal_draw().connect(sigc::mem_fun(*this, &Drawing::draw_event));
|
||||
main_box.pack_start(left_box, Gtk::PACK_SHRINK);
|
||||
main_box.pack_start(draw_area);
|
||||
main_box.pack_start(btn_box, Gtk::PACK_SHRINK);
|
||||
main_box.set_border_width(10);
|
||||
add(main_box);
|
||||
show_all_children();
|
||||
}
|
||||
|
||||
void Drawing::btnsave_clicked()
|
||||
{
|
||||
// Create a dialog
|
||||
dialog = Gtk::FileChooserNative::create("Save to png file", *this,
|
||||
Gtk::FILE_CHOOSER_ACTION_SAVE, "OK", "Cancel");
|
||||
|
||||
// Link Signal
|
||||
dialog->signal_response().connect(sigc::mem_fun(*this, &Drawing::dialog_response));
|
||||
|
||||
// Create Filters
|
||||
|
||||
auto filter_png = Gtk::FileFilter::create();
|
||||
filter_png->set_name("Png files");
|
||||
filter_png->add_pattern("*.png");
|
||||
dialog->add_filter(filter_png);
|
||||
|
||||
auto filter_any = Gtk::FileFilter::create();
|
||||
filter_any->set_name("Any Files");
|
||||
filter_any->add_pattern("*");
|
||||
dialog->add_filter(filter_any);
|
||||
|
||||
dialog->show();
|
||||
}
|
||||
|
||||
void Drawing::dialog_response(int response_id)
|
||||
{
|
||||
// Save cairo surface to png file
|
||||
if (response_id == Gtk::RESPONSE_ACCEPT)
|
||||
{
|
||||
// Get file name
|
||||
std::string filename;
|
||||
auto file = dialog->get_file();
|
||||
filename = file->get_path();
|
||||
|
||||
// Auto complete the extension of the image file
|
||||
size_t length = filename.length();
|
||||
std::string extension = filename.substr(length - 3, length - 1);
|
||||
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
|
||||
if (extension != "png")
|
||||
{
|
||||
filename += ".png";
|
||||
}
|
||||
|
||||
// Write surface data to the file
|
||||
surface->write_to_png(filename);
|
||||
}
|
||||
dialog.reset();
|
||||
}
|
||||
|
||||
void Drawing::btnfree_clicked()
|
||||
{
|
||||
// Mode1: Free Drawing
|
||||
drawing_mode = DrawMode::Default;
|
||||
}
|
||||
|
||||
void Drawing::btnline_clicked()
|
||||
{
|
||||
// Mode2: Draw line, click for start point and end point
|
||||
drawing_mode = DrawMode::Line;
|
||||
}
|
||||
|
||||
void Drawing::btncircle_clicked()
|
||||
{
|
||||
// Mode3: Draw circle, click for radius
|
||||
drawing_mode = DrawMode::Circle;
|
||||
}
|
||||
|
||||
void Drawing::btnrectangle_clicked()
|
||||
{
|
||||
// Mode4: Draw a rectangle
|
||||
drawing_mode = DrawMode::Rectangle;
|
||||
}
|
||||
|
||||
void Drawing::btnclear_clicked()
|
||||
{
|
||||
if (surface)
|
||||
{
|
||||
// Clear the content in draw area
|
||||
auto cr = Cairo::Context::create(surface);
|
||||
cr->set_source_rgb(1, 1, 1);
|
||||
cr->paint();
|
||||
cr.clear();
|
||||
draw_area.queue_draw();
|
||||
}
|
||||
}
|
||||
|
||||
// Signal Handlers
|
||||
bool Drawing::draw_event(const Cairo::RefPtr<Cairo::Context> &context)
|
||||
{
|
||||
// Show context
|
||||
context->set_source(surface, 0, 0);
|
||||
context->paint();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Drawing::draw_brush(double x, double y, DrawProcess process)
|
||||
{
|
||||
brush_size = scale.get_value();
|
||||
auto cr = Cairo::Context::create(surface);
|
||||
|
||||
// Create Draw Brush with specificed size
|
||||
cr->set_line_width(brush_size * 2);
|
||||
|
||||
switch (drawing_mode)
|
||||
{
|
||||
case DrawMode::Default:
|
||||
// Use Line for main drawing
|
||||
if (process == DrawProcess::Begin)
|
||||
{
|
||||
rel_x = x;
|
||||
rel_y = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
cr->move_to(rel_x - 0.1, rel_y - 0.1);
|
||||
cr->line_to(x, y);
|
||||
rel_x = x;
|
||||
rel_y = y;
|
||||
}
|
||||
|
||||
// Set Color
|
||||
cr->set_source_rgba(m_color.get_red(), m_color.get_green(),
|
||||
m_color.get_blue(), m_color.get_alpha());
|
||||
|
||||
// Fill Color and Delete the brush
|
||||
cr->stroke();
|
||||
cr.clear();
|
||||
break;
|
||||
case DrawMode::Line:
|
||||
cr->move_to(rel_x, rel_y);
|
||||
cr->line_to(x, y);
|
||||
|
||||
// Set Color
|
||||
cr->set_source_rgba(m_color.get_red(), m_color.get_green(),
|
||||
m_color.get_blue(), m_color.get_alpha());
|
||||
|
||||
// Fill Color and Delete the brush
|
||||
cr->stroke();
|
||||
cr.clear();
|
||||
break;
|
||||
case DrawMode::Circle:
|
||||
// Fill Color and Delete the brush
|
||||
if (fill_check.get_active())
|
||||
{
|
||||
cr->arc(rel_x, rel_y, sqrt((x - rel_x) * (x - rel_x) + (y - rel_y) * (y - rel_y)), 0.0, 2 * G_PI);
|
||||
// Fill Color
|
||||
draw_fill_color(cr);
|
||||
}
|
||||
|
||||
cr->arc(rel_x, rel_y, sqrt((x - rel_x) * (x - rel_x) + (y - rel_y) * (y - rel_y)), 0.0, 2 * G_PI);
|
||||
|
||||
cr->set_source_rgba(m_color.get_red(), m_color.get_green(),
|
||||
m_color.get_blue(), m_color.get_alpha());
|
||||
cr->stroke();
|
||||
cr.clear();
|
||||
break;
|
||||
case DrawMode::Rectangle:
|
||||
// Fill Color and Delete the brush
|
||||
if (fill_check.get_active())
|
||||
{
|
||||
// Fill Color
|
||||
cr->rectangle(rel_x, rel_y, abs(x - rel_x), abs(y - rel_y));
|
||||
draw_fill_color(cr);
|
||||
}
|
||||
cr->rectangle(rel_x, rel_y, abs(x - rel_x), abs(y - rel_y));
|
||||
|
||||
cr->set_source_rgba(m_color.get_red(), m_color.get_green(),
|
||||
m_color.get_blue(), m_color.get_alpha());
|
||||
cr->stroke();
|
||||
cr.clear();
|
||||
break;
|
||||
}
|
||||
draw_area.queue_draw();
|
||||
}
|
||||
|
||||
void Drawing::draw_fill_color(const Cairo::RefPtr<Cairo::Context> &cr)
|
||||
{
|
||||
cr->set_source_rgba(fill_color.get_red(), fill_color.get_green(),
|
||||
fill_color.get_blue(), fill_color.get_alpha());
|
||||
cr->fill();
|
||||
}
|
||||
|
||||
void Drawing::button_press(int n_press, double x, double y)
|
||||
{
|
||||
auto button = press->get_current_button();
|
||||
// std::cout<<button<<std::endl;
|
||||
switch (button)
|
||||
{
|
||||
case 1:
|
||||
if (drawing_mode != DrawMode::Default)
|
||||
{
|
||||
if (begin)
|
||||
{
|
||||
begin = !begin;
|
||||
rel_x = x;
|
||||
rel_y = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
begin = !begin;
|
||||
draw_brush(x, y, DrawProcess::End);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
btnclear_clicked();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Drawing::drag_begin(double x, double y)
|
||||
{
|
||||
start_x = x;
|
||||
start_y = y;
|
||||
draw_brush(x, y, DrawProcess::Begin);
|
||||
}
|
||||
|
||||
void Drawing::drag_progress(double x, double y)
|
||||
{
|
||||
// Progress and end
|
||||
draw_brush(x + start_x, y + start_y, DrawProcess::Update);
|
||||
}
|
||||
|
||||
void Drawing::drag_end(double x, double y)
|
||||
{
|
||||
// Progress and end
|
||||
draw_brush(x + start_x, y + start_y, DrawProcess::End);
|
||||
}
|
||||
|
||||
void Drawing::color_set()
|
||||
{
|
||||
m_color = color_btn.get_rgba();
|
||||
fill_color = fill_btn.get_rgba();
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
#pragma once
|
||||
|
||||
#include <gtkmm.h>
|
||||
|
||||
// 4 Draw modes: default(free draw), circle, line, rectangle
|
||||
enum class DrawMode{
|
||||
Default,
|
||||
Circle,
|
||||
Line,
|
||||
Rectangle
|
||||
};
|
||||
|
||||
// Flage for process of drawing
|
||||
enum class DrawProcess{
|
||||
Begin, // The beginning of draw
|
||||
Update, // The Process(Position update)
|
||||
End // The end of draw
|
||||
};
|
||||
|
||||
class Drawing : public Gtk::Window
|
||||
{
|
||||
// Drawing Mode
|
||||
DrawMode drawing_mode;
|
||||
|
||||
// Child Widgets
|
||||
Gtk::DrawingArea draw_area;
|
||||
Gtk::ColorButton color_btn, fill_btn;
|
||||
Gtk::CheckButton fill_check;
|
||||
Gtk::Label main_label, size_label;
|
||||
Gtk::Box left_box, main_box, btn_box;
|
||||
Gtk::Button btn_clear, btn_save, btn_exit;
|
||||
Gtk::RadioButton btn_free, btn_line, btn_circle, btn_rectangle;
|
||||
Gtk::Scale scale;
|
||||
|
||||
// Color Setting
|
||||
Gdk::RGBA m_color, fill_color;
|
||||
Cairo::RefPtr<Cairo::ImageSurface> surface;
|
||||
|
||||
// Image Save Dialog
|
||||
Glib::RefPtr<Gtk::FileChooserNative> dialog;
|
||||
void dialog_response(int response_id);
|
||||
|
||||
// Draw Brush Settings
|
||||
double brush_size;
|
||||
double rel_x, rel_y;
|
||||
bool begin = true;
|
||||
|
||||
// Gesture to draw
|
||||
Glib::RefPtr<Gtk::GestureDrag> drag;
|
||||
Glib::RefPtr<Gtk::GestureMultiPress> press;
|
||||
Glib::RefPtr<Gtk::Adjustment> size_adj;
|
||||
double start_x, start_y;
|
||||
|
||||
// Signal Handlers
|
||||
|
||||
// Part 1: Drawing signal handlers
|
||||
bool draw_event(const Cairo::RefPtr<Cairo::Context> &context);
|
||||
|
||||
void draw_brush(double x, double y, DrawProcess process = DrawProcess::Update);
|
||||
|
||||
void draw_fill_color(const Cairo::RefPtr<Cairo::Context> &cr);
|
||||
|
||||
// Part 2: Signal handler for gestures
|
||||
void button_press(int n_press, double x, double y);
|
||||
|
||||
void drag_begin(double x, double y);
|
||||
|
||||
void drag_progress(double x, double y);
|
||||
|
||||
void drag_end(double x, double y);
|
||||
|
||||
// Part 3: Signal Hanlders for normal buttons on the UI
|
||||
void color_set();
|
||||
|
||||
void btnfree_clicked();
|
||||
|
||||
void btnline_clicked();
|
||||
|
||||
void btncircle_clicked();
|
||||
|
||||
void btnrectangle_clicked();
|
||||
|
||||
void btnclear_clicked();
|
||||
|
||||
void btnsave_clicked();
|
||||
|
||||
public:
|
||||
Drawing();
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
#include "drawing.hh"
|
||||
|
||||
int main(int argc,char **argv){
|
||||
auto app=Gtk::Application::create(argc,argv,"org.gtk.daleclack");
|
||||
Drawing window;
|
||||
return app->run(window);
|
||||
}
|
Loading…
Reference in New Issue