Приложение А. Некоторые выдержки из кода программы




Интерфейс инструмента:

#pragma once

 

struct point {

int x;

int y;

};

 

enum EditorTool {

TOOL_PENCIL, TOOL_BRUSH, TOOL_LINE, TOOL_ERASER, TOOL_FILL, TOOL_PIPETTE

};

 

ref class Tool abstract {

protected:

static System::Drawing::Color color = System::Drawing::Color::Black;

static System::Drawing::Pen ^colored_pen = gcnew System::Drawing::Pen(color);

static System::Drawing::Pen ^colored_thick_pen = gcnew System::Drawing::Pen(color, (float)30);

static System::Drawing::Brush ^colored_brush = gcnew System::Drawing::SolidBrush(color);

static unsigned thickness = 30;

public:

Tool() { }

virtual ~Tool() { }

 

static System::Drawing::Color GetColor() {

return color;

}

 

static void SetColor(System::Drawing::Color _color) {

color = _color;

colored_pen->Color = color;

colored_thick_pen->Color = color;

colored_brush = gcnew System::Drawing::SolidBrush(color);

ColorChanged(nullptr, nullptr);

}

 

static System::Drawing::Pen ^GetPen() {

return colored_pen;

}

 

static System::Drawing::Brush ^GetBrush() {

return colored_brush;

}

 

static unsigned GetThickness() {

return thickness;

}

 

static void SetThickness(unsigned _thickness) {

thickness = _thickness;

colored_thick_pen->Width = (float)thickness;

ThicknessChanged(nullptr, nullptr);

}

 

static event System::EventHandler ^ColorChanged;

static event System::EventHandler ^ThicknessChanged;

 

virtual EditorTool Identifier() = 0;

 

// true если рисунок изменён этим инструментом

// false если нет (например, пипетка или выделение не изменяют рисунок)

virtual bool IsMutating() = 0;

 

// true если изменение инструмента постоянно (напр., карандаш рисует все движения)

// false если нет (например, линия рисуется только после отпускания, а до этого предпросмотр)

// ВНИМАНИЕ: ставить в false ТОЛЬКО если инструмент ТРЕБУЕТ предпросмотра!

virtual bool IsMovementPermanent() = 0;

 

// true если использует ширину

// false если ширина неприменима к инструменту

virtual bool IsThickable() = 0;

 

// срабатывает при нажатии мыши

virtual void BeginDraw(System::Drawing::Bitmap ^bmp, System::Drawing::Point ^location) = 0;

// срабатывает при ведении мыши

virtual void ContinueDraw(System::Drawing::Graphics ^g, System::Drawing::Point ^location) = 0;

// срабатывает при отпускании мыши

virtual void EndDraw(System::Drawing::Graphics ^g, System::Drawing::Point ^location) = 0;

};

 

Основные действия, доступные из меню

void New() {

if (!ConfirmForLosingChanges()) return;

isFileEdited = false;

isDrawingNow = false;

needInvalidation = true; // обновление в самом начале, чтобы показать пустой рисунок

assignedFileName = String::Empty;

real_image = gcnew Bitmap(400, 300, System::Drawing::Imaging::PixelFormat::Format32bppArgb);

g = Graphics::FromImage(real_image);

// если нет непостоянных изменений, g_tmp == g

g_tmp = g;

// заливаем новую картинку белым цветом

g->FillRectangle(gcnew SolidBrush(System::Drawing::Color::White), 0, 0, real_image->Width, real_image->Height);

 

// обновляем экран

pictureBox1->Size = real_image->Size;

needInvalidation = true;

pictureBox1->Invalidate();

}

 

void Open() {

if (!ConfirmForLosingChanges()) return;

System::Windows::Forms::DialogResult ^dr = openFileDialog1->ShowDialog();

if(*dr == System::Windows::Forms::DialogResult::OK) {

New();

real_image = gcnew Bitmap(openFileDialog1->FileName);

g = Graphics::FromImage(real_image);

g_tmp = g;

 

assignedFileName = openFileDialog1->FileName;

 

// обновляем экран

pictureBox1->Size = real_image->Size;

needInvalidation = true;

pictureBox1->Invalidate();

}

}

 

// возвращает true если сохранение было совершено

// false - если нет, например, пользователь нажал "Отмена"

bool Save() {

if (assignedFileName->Equals(System::String::Empty)) {

return SaveAs();

}

real_image->Save(assignedFileName);

// помечаем файл как оригинальный (его только что сохранили, с тех пор изменений не было)

isFileEdited = false;

return true;

}

 

bool SaveAs() {

// спрашиваем имя файла

System::Windows::Forms::DialogResult ^dr = saveFileDialog1->ShowDialog();

if (*dr!= System::Windows::Forms::DialogResult::OK) return false;

assignedFileName = saveFileDialog1->FileName;

// вызываем функцию обычного сохранения, которая либо вернёт true, либо кинет исключение

Save();

return true;

}

 

void About() {

MessageBox::Show("Разработал: Тихонов В.\nГруппа: АТ-63\nНовосибирск, 2017", "О программе");

}

 

void Exit() {

if (!ConfirmForLosingChanges()) return;

Application::Exit();

}

 

// вспомогательные действия

// спрашиваем, готов ли пользователь продолжить с несохранённой картинкой.

// если false, отменяем вызвавшее действие

// если true - продолжаем (при этом пользователь всё сохранил, если захотел)

bool ConfirmForLosingChanges() {

if (isFileEdited) {

System::Windows::Forms::DialogResult ^dr =

MessageBox::Show(

"Файл изменён, сохранить изменения?"

, "Предупреждение"

, MessageBoxButtons::YesNoCancel

);

switch (*dr) {

case System::Windows::Forms::DialogResult::Yes:

// если пользователь нажал "да" а потом "отмена" - не завершать программу

if (!Save()) return false;

 

break;

 

case System::Windows::Forms::DialogResult::No:

// если пользователь ответил "нет" - больше не надоедать

isFileEdited = false;

break;

 

case System::Windows::Forms::DialogResult::Cancel:

// не завершать программу

return false;

break;

}

}

return true;

}


 

События рисования

private: System::Void pictureBox1_MouseDown(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) {

// только на левую кнопку

if (e->Button!= System::Windows::Forms::MouseButtons::Left) return;

 

System::Windows::Forms::Cursor ^prevCursor = this->Cursor;

this->Cursor = Cursors::WaitCursor;

// начало действия инструмента

isDrawingNow = true;

isFileEdited |= activeToolRef->IsMutating();

 

// обновляем предпросмотр картинки в случае если его будем показывать сейчас

// см. функцию события OnPaint

if (activeToolRef->IsMutating() &&!activeToolRef->IsMovementPermanent()) {

real_image_tmp = gcnew Bitmap(real_image);

}

 

activeToolRef->BeginDraw(real_image, e->Location);

 

needInvalidation = true;

pictureBox1->Invalidate();

 

this->Cursor = prevCursor;

}

 

private: System::Void pictureBox1_MouseMove(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) {

// только на левую кнопку

if (!isDrawingNow) return;

 

// начало действия инструмента

if (!activeToolRef->IsMovementPermanent()) {

real_image_tmp = gcnew Bitmap(real_image);

g_tmp = Graphics::FromImage(real_image_tmp);

}

else {

g_tmp = g;

}

activeToolRef->ContinueDraw(g_tmp, e->Location);

 

needInvalidation = true;

pictureBox1->Invalidate();

}

 

private: System::Void pictureBox1_MouseUp(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) {

// только на левую кнопку

if (!isDrawingNow) return;

 

// начало действия инструмента

activeToolRef->EndDraw(g, e->Location);

 

needInvalidation = true;

pictureBox1->Invalidate();

isDrawingNow = false;

}

 

private: System::Void pictureBox1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) {

if (!needInvalidation) return;

// иначе показываем предпросмотр

if(activeToolRef->IsMutating() &&!activeToolRef->IsMovementPermanent()) {

pictureBox1->Image = real_image_tmp;

}

// если движения отражаются в конечном рисунке, показываем реальную картинку

else {

pictureBox1->Image = real_image;

}

needInvalidation = false;

}



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-04-04 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: