Something went wrong. Try again.
art software for the rest of us
drawing paint image sdl art
Something went wrong. Try again.
C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235#include "LayersPanel.h"#include <cstdio>#include "../ImGui.h"#include "MaterialIcons.h"#include "../ManagementContext/LayerManagmentContext.h"#include "../LayerNodes/PaintLayerNode.h"#include "../Commands/LayerEdit.h"#include "../ManagementContext/StyleManagmentContext.h"#include "../App.h"void LayersPanel::OnActivate(){ state = OPEN;}void LayersPanel::OnDeactivate(){ state = CLOSED;}void LayersPanel::renderLayers(){ ImGui::PushItemWidth(-FLT_MIN);
StyleManagmentContext::Push(BRUSHLIST); ImGui::BeginTable("##LayerTable", 3); // canvas buttons, layers, layer buttons ImGui::TableSetupColumn("##CanvasColumn", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("##LayerColumn", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##LayerButtonColumn", ImGuiTableColumnFlags_WidthFixed); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::PushFont(DearImGuiApp::MaterialIcons, 24.0f); // TODO: use/create own icons StyleManagmentContext::Push(LAYERMANAGER);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); if (ImGui::Button(ICON_MS_ADD)) { LayerManagementContext::AddLayer(); } // add layer ImGui::Button(ICON_MS_CREATE_NEW_FOLDER); // add folder ImGui::Button(ICON_MS_LIBRARY_ADD); // duplicate layer ImGui::Button(ICON_MS_VERTICAL_ALIGN_CENTER); // add layer from canvas ImGui::Button(ICON_MS_IMAGE); // import image ImGui::Button(ICON_MS_SWAP_HORIZ); // flip canvas horizontal ImGui::Button(ICON_MS_SWAP_VERT); // flip canvas vertical ImGui::PopStyleColor(); StyleManagmentContext::Pop(); ImGui::PopFont(); ImGui::TableSetColumnIndex(1); if (ImGui::BeginListBox("##LayerListBox", ImVec2(-FLT_MIN, -FLT_MIN - 68))) { renderLayerNodes();
// background auto currentBackgroundMode = LayerManagementContext::Background;
auto cursor = ImGui::GetCursorScreenPos(); ImGui::SetCursorScreenPos(ImVec2(cursor.x + 3.0f, cursor.y)); ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); if (currentBackgroundMode == BackgroundMode::COLOR) { StyleManagmentContext::Push(SELECTED); } if (ImGui::ColorEdit4("", LayerManagementContext::BackgroundColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_NoSidePreview)) {//ImGui::ColorButton("##LayerBackground", *(ImVec4*)&LayerManagementContext::BackgroundColor)) { LayerManagementContext::SetBackground(BackgroundMode::COLOR, LayerManagementContext::BackgroundColor); } if (currentBackgroundMode == BackgroundMode::COLOR) { StyleManagmentContext::Pop(); } ImGui::SameLine(); if (ImGui::RadioButton("Transparency", currentBackgroundMode == BackgroundMode::TRANSPARENT)) { LayerManagementContext::SetBackground(BackgroundMode::TRANSPARENT, LayerManagementContext::BackgroundColor); } ImGui::SameLine(); if (ImGui::RadioButton("Dark", currentBackgroundMode == BackgroundMode::TRANSPARENT_DARK)) { LayerManagementContext::SetBackground(BackgroundMode::TRANSPARENT_DARK, LayerManagementContext::BackgroundColor); } ImGui::PopStyleVar(); ImGui::EndListBox(); } ImGui::TableSetColumnIndex(2); ImGui::PushFont(DearImGuiApp::MaterialIcons, 24.0f); // TODO: use/create own icons StyleManagmentContext::Push(LAYERMANAGER);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); ImGui::Button(ICON_MS_BACKSPACE); // clear layer ImGui::Button(ICON_MS_INVERT_COLORS); // invert layer ImGui::Button(ICON_MS_TEXT_SELECT_MOVE_DOWN); // merge layer down if (ImGui::Button(ICON_MS_DELETE)) { LayerManagementContext::RemoveLayer(LayerManagementContext::SelectedLayer); } // delete layer ImGui::PushID("LayerButtonSwapHoriz"); ImGui::Button(ICON_MS_SWAP_HORIZ); // flip layer horizontal ImGui::PopID(); ImGui::PushID("LayerButtonSwapVert"); ImGui::Button(ICON_MS_SWAP_VERT); // flip layer vertical ImGui::PopID(); ImGui::Button(ICON_MS_DRAG_PAN); // move layer ImGui::Button(ICON_MS_MORE_HORIZ); // more
ImGui::PopStyleColor(); StyleManagmentContext::Pop(); ImGui::PopFont(); ImGui::EndTable(); StyleManagmentContext::Pop();}
void LayersPanel::renderLayerNodes(){ /*int uncounted = 1; //+ LayerManagementContext::Layers.size(); // TODO: future visualize customization for (LayerNode* layer : LayerManagementContext::Layers) { if (!layer->Name.compare("")) { // std::string::compare returning null when true is stupid uncounted++; } }*/
for (auto it = LayerManagementContext::Layers.rbegin(); it != LayerManagementContext::Layers.rend(); it++) { // reverse itterator auto layer = *it;
auto cursor = ImGui::GetCursorScreenPos(); ImGui::SetCursorScreenPos(ImVec2(cursor.x, cursor.y - 2.0f)); bool thisOne = layer == LayerManagementContext::SelectedLayer; ImGui::SetNextItemAllowOverlap(); if (ImGui::Selectable(("##LayerSelect@" + std::to_string((size_t)layer)).c_str(), thisOne, 0, ImVec2(ImGui::GetContentRegionAvail().x - 4.0f, 48.0f))) { LayerManagementContext::SelectLayer(layer); } if (ImGui::IsItemActive() && !ImGui::IsItemHovered()) { auto next = it + (ImGui::GetMouseDragDelta(0).y < 0.f ? -1 : 1); if (next >= LayerManagementContext::Layers.rbegin() && next < LayerManagementContext::Layers.rend()) { LayerManagementContext::SwapLayers(layer, *next); ImGui::ResetMouseDragDelta(); } }
auto paintLayer = dynamic_cast<PaintLayerNode*>(layer); if (paintLayer) { int h = paintLayer->Target->GetHeight(); int w = paintLayer->Target->GetWidth(); float ratio = (float)h / (float)w; float largest = std::max((float)h, (float)w); float finalw = largest == w ? 42.0f : 42.0f * ratio; float finalh = largest == w ? 42.0f * ratio : 42.0f; ImGui::SetCursorScreenPos(ImVec2(cursor.x + 2.0f, cursor.y + 2.0f + (42.0f - finalh) / 2.0f)); ImGui::Image(paintLayer->Target->Get(), ImVec2(finalw, finalh), ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), ImVec4(1.0f, 1.0f, 1.0f, 1.0f), ImVec4(0.0f, 0.0f, 0.0f, 0.5f)); } ImGui::SetCursorScreenPos(ImVec2(cursor.x + 48.0f, cursor.y)); //ImGui::Text((layer->Name.compare("") ? layer->Name : (--uncounted, "Layer " + std::to_string(uncounted))).c_str()); StyleManagmentContext::Push(NOBORDER); DearImGuiApp::InputText(("##LayerNameInput@" + std::to_string((size_t)layer)).c_str(), layer->Name, ImGuiInputTextFlags_EnterReturnsTrue); StyleManagmentContext::Pop(); //ImGui::Text((--uncounted, (layer->Name.compare("") ? layer->Name + ": " + std::to_string(uncounted) : std::to_string(uncounted))).c_str()); cursor = ImGui::GetCursorScreenPos(); ImGui::SetCursorScreenPos(ImVec2(cursor.x + 48.0f, cursor.y)); ImGui::Text((std::to_string((int)(layer->Opacity * 100.0)) + "%% " + BlendmodeNames[layer->BlendMode]).c_str(), nullptr); cursor = ImGui::GetCursorScreenPos(); ImGui::SetCursorScreenPos(ImVec2(cursor.x, cursor.y));
ImGui::Separator(); }}
void LayersPanel::renderLayerTools(){ double* opacity = &LayerManagementContext::SelectedLayer->Opacity; static double previousOpacity; double min = 0.0; double max = 1.0; static bool alphaLock = false; static bool clipping = false; char stringBuffers[1][20]; std::sprintf(stringBuffers[0], "Opacity: %.1f%%%%", (float)(*opacity * 100.0)); //ImGui::SliderFloat("##OpacitySlider", (float*)&opacity, 0.0f, 1.0f, stringBuffers[0]); double oldOpacity = *opacity; ImGui::SliderScalar("##OpacitySlider", ImGuiDataType_Double, opacity, &min, &max, stringBuffers[0]); if (ImGui::IsItemActivated()) { // if this control flow graph was a family tree it would be a circle previousOpacity = oldOpacity; } if (ImGui::IsItemDeactivatedAfterEdit() && previousOpacity != *opacity) { auto action = std::make_unique<LayerEdit>("Change Opacity of Layer", LayerManagementContext::SelectedLayer->ID); action->SetOpacity(*opacity); action->SetOldOpacity(previousOpacity); App::History->Execute(std::move(action)); } ImGui::PopItemWidth(); ImGui::PushFont(DearImGuiApp::MaterialIcons, 24.0f); ImGui::Checkbox(ICON_MS_LOCK, &alphaLock); ImGui::SameLine(); // alpha lock ImGui::Checkbox(ICON_MS_VERTICAL_ALIGN_BOTTOM, &clipping); ImGui::SameLine(); // clipping ImGui::PopFont(); ImGui::SetNextItemWidth(-FLT_MIN); StyleManagmentContext::Push(POPUP); if (ImGui::BeginCombo("##LayerComboBox", BlendmodeNames[LayerManagementContext::SelectedLayer->BlendMode], ImGuiComboFlags_HeightLargest)) { if (ImGui::BeginChild("##LayerComboBoxChild", ImVec2(0.0f, 0.0f), ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_Borders)) { for (int i = 0; i != Blendmode::INVALID; i++) { if (i == 2) { ImGui::Separator(); ImGui::TextColored(ImVec4(0.0f, 0.0f, 0.0f, 0.5f), "Placeholders"); } if (ImGui::Selectable(BlendmodeNames[i], LayerManagementContext::SelectedLayer->BlendMode == (Blendmode)i)) { auto action = std::make_unique<LayerEdit>("Blendmode", LayerManagementContext::SelectedLayer->ID); action->SetBlendmode((Blendmode)i); App::History->Execute(std::move(action)); } } ImGui::EndChild(); } ImGui::EndCombo(); } StyleManagmentContext::Pop();}
void LayersPanel::OnRender(){ if (!state) { return; }
const ImGuiViewport* viewport = ImGui::GetMainViewport(); ImVec2 work_pos = viewport->WorkPos; ImVec2 work_size = viewport->WorkSize; ImVec2 window_pos;
window_pos.x = work_pos.x + (work_size.x / 2) + 144; window_pos.y = work_pos.y + work_size.y - 64; if (state != DETACHED) { ImGui::SetNextWindowPos(window_pos, 0, ImVec2(0.5f, 1.0f)); ImGui::SetNextWindowSize(ImVec2(336, 440), 0); }
ImGui::SetNextWindowSizeConstraints(ImVec2(336, 440), ImVec2(FLT_MAX, FLT_MAX)); if (!beginCustomWindow("Layers")) { return; } renderLayers(); renderLayerTools();
endCustomWindow();
}