// ----------------------------------------------------------------------------- // Updates display attributes for [item] // ----------------------------------------------------------------------------- void UndoListView::updateItemAttr(long item, long column, long index) const { if (!manager_) return; item_attr_->SetTextColour(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOXTEXT)); if (item == manager_->currentIndex()) item_attr_->SetTextColour(WXCOL(ColRGBA(0, 170, 0))); else if (item > manager_->currentIndex()) item_attr_->SetTextColour(WXCOL(ColRGBA(150, 150, 150))); }
// ----------------------------------------------------------------------------- // Sets the colour and tint amount to use // ----------------------------------------------------------------------------- void GfxTintDialog::setValues(const string& col, int val) { wxColour wxcol(col); cb_colour_->setColour(ColRGBA(COLWX(wxcol))); slider_amount_->SetValue(val); label_amount_->SetLabel(S_FMT("%d%% ", slider_amount_->GetValue())); gfx_preview_->getImage()->tint(colour(), amount(), &palette_); gfx_preview_->updateImageTexture(); gfx_preview_->Refresh(); }
wxColour Drawing::darkColour(const wxColour& colour, float percent) { if (percent == 0) { return colour; } // Convert to HSL ColHSL hsl = ColRGBA(COLWX(colour)).asHSL(); // Decrease luminance hsl.l -= (float)((percent * 5.0) / 100.0); if (hsl.l < 0) hsl.l = 0; ColRGBA rgb = hsl.asRGB(); return wxColour(rgb.r, rgb.g, rgb.b); }
// ----------------------------------------------------------------------------- // Draws the image // (reloads the image as a texture each time, will change this later...) // ----------------------------------------------------------------------------- void GfxCanvas::drawImage() { // Check image is valid if (!image_.isValid()) return; // Save current matrix glPushMatrix(); // Zoom double yscale = (gfx_arc ? scale_ * 1.2 : scale_); glScaled(scale_, yscale, 1.0); // Pan if (view_type_ == View::Centered) glTranslated(-(image_.width() * 0.5), -(image_.height() * 0.5), 0); // Pan to center image else if (view_type_ == View::Sprite) glTranslated(-image_.offset().x, -image_.offset().y, 0); // Pan by offsets else if (view_type_ == View::HUD) { glTranslated(-160, -100, 0); // Pan to hud 'top left' glTranslated(-image_.offset().x, -image_.offset().y, 0); // Pan by offsets } // Enable textures glEnable(GL_TEXTURE_2D); // Update texture if needed if (update_texture_) { // If the image change isn't caused by drawing, resize drawing mask if (!drawing_) { delete[] drawing_mask_; drawing_mask_ = new bool[image_.width() * image_.height()]; memset(drawing_mask_, false, image_.width() * image_.height()); } OpenGL::Texture::clear(tex_image_); tex_image_ = OpenGL::Texture::createFromImage(image_, &palette_); update_texture_ = false; } // Determine (texture)coordinates double x = (double)image_.width(); double y = (double)image_.height(); // If tiled view if (view_type_ == View::Tiled) { // Draw tiled image OpenGL::setColour(255, 255, 255, 255, OpenGL::Blend::Normal); Drawing::drawTextureTiled(tex_image_, GetSize().x / scale_, GetSize().y / scale_); } else if (drag_origin_.x < 0) // If not dragging { // Draw the image OpenGL::setColour(255, 255, 255, 255, OpenGL::Blend::Normal); Drawing::drawTexture(tex_image_); // Draw hilight otherwise if (image_hilight_ && gfx_hilight_mouseover && editing_mode_ == EditMode::None) { OpenGL::setColour(255, 255, 255, 80, OpenGL::Blend::Additive); Drawing::drawTexture(tex_image_); // Reset colour OpenGL::setColour(255, 255, 255, 255, OpenGL::Blend::Normal); } } else // Dragging { // Draw the original OpenGL::setColour(ColRGBA(0, 0, 0, 180), OpenGL::Blend::Normal); Drawing::drawTexture(tex_image_); // Draw the dragged image int off_x = (drag_pos_.x - drag_origin_.x) / scale_; int off_y = (drag_pos_.y - drag_origin_.y) / scale_; glTranslated(off_x, off_y, 0); OpenGL::setColour(255, 255, 255, 255, OpenGL::Blend::Normal); Drawing::drawTexture(tex_image_); } // Draw brush shadow when in editing mode if (editing_mode_ != EditMode::None && cursor_pos_ != Vec2i{ -1, -1 }) { OpenGL::setColour(255, 255, 255, 160, OpenGL::Blend::Normal); Drawing::drawTexture(tex_brush_); OpenGL::setColour(255, 255, 255, 255, OpenGL::Blend::Normal); } // Disable textures glDisable(GL_TEXTURE_2D); // Draw outline if (gfx_show_border) { OpenGL::setColour(0, 0, 0, 64); glBegin(GL_LINE_LOOP); glVertex2d(0, 0); glVertex2d(0, y); glVertex2d(x, y); glVertex2d(x, 0); glEnd(); } // Restore previous matrix glPopMatrix(); }
// ----------------------------------------------------------------------------- // Using [dc], draw the calltip contents at [xoff,yoff]. // Returns the dimensions of the drawn calltip text // ----------------------------------------------------------------------------- wxSize SCallTip::drawCallTip(wxDC& dc, int xoff, int yoff) { wxSize ct_size; auto bold = font_.Bold(); // Setup faded text colour ColRGBA faded; if (txed_calltips_dim_optional) faded = ColRGBA( (uint8_t)round((col_fg_.r + col_bg_.r) * 0.5), (uint8_t)round((col_fg_.g + col_bg_.g) * 0.5), (uint8_t)round((col_fg_.b + col_bg_.b) * 0.5)); else faded = col_fg_; // Clear dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush(wxBrush(WXCOL(col_bg_))); dc.DrawRectangle(0, 0, 1000, 1000); // Wx Colours (to avoid creating them multiple times) wxcol_fg = WXCOL(col_fg_); wxcol_fg_hl = WXCOL(col_fg_hl); wxcol_type = WXCOL(col_type_); auto wxcol_faded = WXCOL(faded); if (function_) { dc.SetFont(font_); dc.SetTextForeground(wxcol_fg); wxRect rect; int left = xoff; int max_right = 0; int bottom = yoff; // Context switching calltip if (switch_contexts_) { // up-filled \xE2\x96\xB2 // up-empty \xE2\x96\xB3 // down-filled \xE2\x96\xBC // down-empty \xE2\x96\xBD // Up arrow dc.SetTextForeground((btn_mouse_over_ == 2) ? wxcol_fg_hl : wxcol_fg); dc.DrawLabel( wxString::FromUTF8("\xE2\x96\xB2"), wxNullBitmap, wxRect(xoff, yoff, 100, 100), 0, -1, &rect_btn_up_); // Arg set int width = dc.GetTextExtent("X/X").x; dc.SetTextForeground(wxcol_fg); dc.DrawLabel( wxString::Format("%lu/%lu", context_current_ + 1, function_->contexts().size()), wxNullBitmap, wxRect(rect_btn_up_.GetRight() + UI::scalePx(4), yoff, width, 900), wxALIGN_CENTER_HORIZONTAL); // Down arrow dc.SetTextForeground((btn_mouse_over_ == 1) ? wxcol_fg_hl : wxcol_fg); dc.DrawLabel( wxString::FromUTF8("\xE2\x96\xBC"), wxNullBitmap, wxRect(rect_btn_up_.GetRight() + width + UI::scalePx(8), yoff, 900, 900), 0, -1, &rect_btn_down_); left = rect_btn_down_.GetRight() + UI::scalePx(8); rect_btn_up_.Offset(WxUtils::scaledPoint(12, 8)); rect_btn_down_.Offset(WxUtils::scaledPoint(12, 8)); // Draw function (current context) rect = drawFunctionContext(dc, context_, left, yoff, wxcol_faded, bold); max_right = rect.GetRight(); bottom = rect.GetBottom(); } // Normal calltip - show (potentially) multiple contexts else { // Determine separator colour wxColour col_sep; if (col_bg_.greyscale().r < 128) col_sep = WXCOL(col_bg_.amp(30, 30, 30, 0)); else col_sep = WXCOL(col_bg_.amp(-30, -30, -30, 0)); bool first = true; auto num = std::min<unsigned long>(function_->contexts().size(), 12u); for (auto a = 0u; a < num; a++) { auto& context = function_->contexts()[a]; if (!first) { dc.SetPen(wxPen(col_sep)); dc.DrawLine(xoff, bottom + 5, 2000, bottom + 5); } rect = drawFunctionContext( dc, context, xoff, bottom + (first ? 0 : UI::scalePx(11)), wxcol_faded, bold); bottom = (int)round(rect.GetBottom() + UI::scaleFactor()); max_right = std::max(max_right, rect.GetRight()); first = false; } // Show '... # more' if there are too many contexts if (function_->contexts().size() > num) { dc.SetTextForeground(wxcol_faded); drawText( dc, wxString::Format("... %lu more", function_->contexts().size() - num), xoff, bottom + UI::scalePx(11), &rect); bottom = (int)round(rect.GetBottom() + UI::scaleFactor()); } if (num > 1) bottom--; } if (!rect.IsEmpty() && !context_.description.empty()) { auto rect_desc = drawFunctionDescription(dc, context_.description, left, rect.GetBottom()); max_right = std::max(max_right, rect_desc.GetRight()); bottom = rect_desc.GetBottom(); } // Size buffer bitmap to fit ct_size.SetWidth((int)round(max_right + UI::scaleFactor())); ct_size.SetHeight((int)round(bottom + UI::scaleFactor())); } else { // No function, empty buffer ct_size.SetWidth(16); ct_size.SetHeight(16); } return ct_size; }
// ----------------------------------------------------------------------------- // Sets up the dialog UI layout // ----------------------------------------------------------------------------- void GfxConvDialog::setupLayout() { int px_inner = UI::pad(); int px_outer = UI::padLarge(); int px_pad = UI::px(UI::Size::PadMinimum); int px_preview_size = UI::scalePx(192); auto msizer = new wxBoxSizer(wxVERTICAL); SetSizer(msizer); auto m_vbox = new wxBoxSizer(wxVERTICAL); msizer->Add(m_vbox, 1, wxEXPAND | wxALL, px_outer); // Add current format label label_current_format_ = new wxStaticText(this, -1, "Current Format:"); m_vbox->Add(label_current_format_, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM, px_inner); // Add 'Convert To' combo box auto hbox = new wxBoxSizer(wxHORIZONTAL); m_vbox->Add(hbox, 0, wxEXPAND | wxBOTTOM, px_outer); hbox->Add(new wxStaticText(this, -1, "Convert to:"), 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, px_pad); combo_target_format_ = new wxChoice(this, -1); hbox->Add(combo_target_format_, 1, wxEXPAND); // Add Gfx previews auto frame = new wxStaticBox(this, -1, "Colour Options"); auto framesizer = new wxStaticBoxSizer(frame, wxHORIZONTAL); m_vbox->Add(framesizer, 1, wxEXPAND | wxBOTTOM, px_outer); auto gbsizer = new wxGridBagSizer(px_inner, px_inner); framesizer->Add(gbsizer, 1, wxEXPAND | wxALL, px_inner); // Current gbsizer->Add(new wxStaticText(this, -1, "Current Graphic"), { 0, 0 }, { 1, 1 }); gfx_current_ = new GfxCanvas(this, -1); gfx_current_->SetInitialSize(wxSize(px_preview_size, px_preview_size)); gfx_current_->setViewType(GfxCanvas::View::Centered); gbsizer->Add(gfx_current_, { 1, 0 }, { 1, 1 }, wxEXPAND); pal_chooser_current_ = new PaletteChooser(this, -1); pal_chooser_current_->selectPalette(current_palette_name_); gbsizer->Add(pal_chooser_current_, { 2, 0 }, { 1, 1 }, wxEXPAND); // Converted gbsizer->Add(new wxStaticText(this, -1, "Converted Graphic"), { 0, 1 }, { 1, 2 }); gfx_target_ = new GfxCanvas(this, -1); gfx_target_->SetInitialSize(wxSize(px_preview_size, px_preview_size)); gfx_target_->setViewType(GfxCanvas::View::Centered); gbsizer->Add(gfx_target_, { 1, 1 }, { 1, 2 }, wxEXPAND); pal_chooser_target_ = new PaletteChooser(this, -1); pal_chooser_target_->selectPalette(target_palette_name_); gbsizer->Add(pal_chooser_target_, { 2, 1 }, { 1, 1 }, wxEXPAND); btn_colorimetry_settings_ = new wxBitmapButton(this, -1, Icons::getIcon(Icons::General, "settings"), wxDefaultPosition, wxDefaultSize); btn_colorimetry_settings_->SetToolTip("Adjust Colorimetry Settings..."); gbsizer->Add(btn_colorimetry_settings_, { 2, 2 }, { 1, 1 }, wxALIGN_CENTER); gbsizer->AddGrowableCol(0, 1); gbsizer->AddGrowableCol(1, 1); gbsizer->AddGrowableRow(1, 1); // Add transparency options frame = new wxStaticBox(this, -1, "Transparency Options"); framesizer = new wxStaticBoxSizer(frame, wxVERTICAL); m_vbox->Add(framesizer, 0, wxEXPAND | wxBOTTOM, px_outer); gbsizer = new wxGridBagSizer(px_inner, px_inner); framesizer->Add(gbsizer, 1, wxEXPAND | wxALL, px_inner); // 'Enable transparency' checkbox cb_enable_transparency_ = new wxCheckBox(this, -1, "Enable Transparency"); cb_enable_transparency_->SetValue(true); cb_enable_transparency_->SetToolTip("Uncheck this to remove any existing transparency from the graphic"); gbsizer->Add(cb_enable_transparency_, { 0, 0 }, { 1, 2 }); // Keep existing transparency rb_transparency_existing_ = new wxRadioButton(this, 100, "Existing w/Threshold:", wxDefaultPosition, wxDefaultSize, wxRB_GROUP); rb_transparency_existing_->SetValue(true); gbsizer->Add(rb_transparency_existing_, { 1, 0 }, { 1, 1 }, wxALIGN_CENTER_VERTICAL); // Alpha threshold slider_alpha_threshold_ = new wxSlider( this, -1, 0, 0, 255, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL | wxSL_LABELS | wxSL_BOTTOM); slider_alpha_threshold_->SetToolTip( "Specifies the 'cutoff' transparency level, anything above this will be fully opaque, " "anything equal or below will be completely transparent"); gbsizer->Add(slider_alpha_threshold_, { 1, 1 }, { 1, 1 }, wxEXPAND); // Transparent colour rb_transparency_colour_ = new wxRadioButton(this, 101, "Transparent Colour:", wxDefaultPosition, wxDefaultSize, 0); rb_transparency_colour_->SetValue(false); gbsizer->Add(rb_transparency_colour_, { 2, 0 }, { 1, 1 }, wxALIGN_CENTER_VERTICAL); colbox_transparent_ = new ColourBox(this, -1, false); colbox_transparent_->setColour(ColRGBA(0, 255, 255, 255)); gbsizer->Add(colbox_transparent_, { 2, 1 }, { 1, 1 }); // From brightness rb_transparency_brightness_ = new wxRadioButton(this, 102, "Transparency from Brightness"); rb_transparency_brightness_->SetValue(false); gbsizer->Add(rb_transparency_brightness_, { 3, 0 }, { 1, 2 }); gbsizer->AddGrowableCol(1, 1); // Buttons hbox = new wxBoxSizer(wxHORIZONTAL); m_vbox->Add(hbox, 0, wxEXPAND); btn_convert_ = new wxButton(this, -1, "Convert"); btn_convert_all_ = new wxButton(this, -1, "Convert All"); btn_skip_ = new wxButton(this, -1, "Skip"); btn_skip_all_ = new wxButton(this, -1, "Skip All"); hbox->AddStretchSpacer(1); hbox->Add(btn_convert_, 0, wxEXPAND | wxRIGHT, px_inner); hbox->Add(btn_convert_all_, 0, wxEXPAND | wxRIGHT, px_inner); hbox->Add(btn_skip_, 0, wxEXPAND | wxRIGHT, px_inner); hbox->Add(btn_skip_all_, 0, wxEXPAND); // Bind events Bind(wxEVT_SIZE, &GfxConvDialog::onResize, this); btn_convert_->Bind(wxEVT_BUTTON, &GfxConvDialog::onBtnConvert, this); btn_convert_all_->Bind(wxEVT_BUTTON, &GfxConvDialog::onBtnConvertAll, this); btn_skip_->Bind(wxEVT_BUTTON, &GfxConvDialog::onBtnSkip, this); btn_skip_all_->Bind(wxEVT_BUTTON, &GfxConvDialog::onBtnSkipAll, this); combo_target_format_->Bind(wxEVT_CHOICE, &GfxConvDialog::onTargetFormatChanged, this); pal_chooser_current_->Bind(wxEVT_CHOICE, &GfxConvDialog::onCurrentPaletteChanged, this); pal_chooser_target_->Bind(wxEVT_CHOICE, &GfxConvDialog::onTargetPaletteChanged, this); slider_alpha_threshold_->Bind(wxEVT_SLIDER, &GfxConvDialog::onAlphaThresholdChanged, this); cb_enable_transparency_->Bind(wxEVT_CHECKBOX, &GfxConvDialog::onEnableTransparencyChanged, this); rb_transparency_colour_->Bind(wxEVT_RADIOBUTTON, &GfxConvDialog::onTransTypeChanged, this); rb_transparency_existing_->Bind(wxEVT_RADIOBUTTON, &GfxConvDialog::onTransTypeChanged, this); rb_transparency_brightness_->Bind(wxEVT_RADIOBUTTON, &GfxConvDialog::onTransTypeChanged, this); Bind(wxEVT_COLOURBOX_CHANGED, &GfxConvDialog::onTransColourChanged, this, colbox_transparent_->GetId()); gfx_current_->Bind(wxEVT_LEFT_DOWN, &GfxConvDialog::onPreviewCurrentMouseDown, this); btn_colorimetry_settings_->Bind(wxEVT_BUTTON, &GfxConvDialog::onBtnColorimetrySettings, this); // Autosize to fit contents (and set this as the minimum size) SetMinClientSize(msizer->GetMinSize()); }