예제 #1
0
void ColorPopup::onSimpleColorClick()
{
  m_colorType.deselectItems();
  if (!g_simplePal)
    return;

  app::Color color = getColor();

  // Find bestfit palette entry
  int r = color.getRed();
  int g = color.getGreen();
  int b = color.getBlue();
  int a = color.getAlpha();

  // Search for the closest color to the RGB values
  int i = g_simplePal->findBestfit(r, g, b, a, 0);
  if (i >= 0) {
    color_t c = g_simplePal->getEntry(i);
    color = app::Color::fromRgb(doc::rgba_getr(c),
                                doc::rgba_getg(c),
                                doc::rgba_getb(c),
                                doc::rgba_geta(c));
  }

  setColorWithSignal(color, ChangeType);
}
예제 #2
0
void PixelsMovement::getDraggedImageCopy(base::UniquePtr<Image>& outputImage,
                                         base::UniquePtr<Mask>& outputMask)
{
  gfx::Rect bounds = m_currentData.transformedBounds();
  base::UniquePtr<Image> image(Image::create(m_sprite->pixelFormat(), bounds.w, bounds.h));

  drawImage(image, bounds.origin(), false);

  // Draw mask without shrinking it, so the mask size is equal to the
  // "image" render.
  base::UniquePtr<Mask> mask(new Mask);
  drawMask(mask, false);

  // Now we can shrink and crop the image.
  gfx::Rect oldMaskBounds = mask->bounds();
  mask->shrink();
  gfx::Rect newMaskBounds = mask->bounds();
  if (newMaskBounds != oldMaskBounds) {
    newMaskBounds.x -= oldMaskBounds.x;
    newMaskBounds.y -= oldMaskBounds.y;
    image.reset(crop_image(image,
                           newMaskBounds.x,
                           newMaskBounds.y,
                           newMaskBounds.w,
                           newMaskBounds.h, 0));
  }

  outputImage.reset(image.release());
  outputMask.reset(mask.release());
}
예제 #3
0
void ColorCurveCommand::onExecute(Context* context)
{
  // Default curve
  if (!the_curve) {
    // TODO load the curve?

    the_curve.reset(new ColorCurve(ColorCurve::Linear));
    the_curve->addPoint(gfx::Point(0, 0));
    the_curve->addPoint(gfx::Point(255, 255));
  }

  ColorCurveFilter filter;
  filter.setCurve(the_curve.get());

  FilterManagerImpl filterMgr(context, &filter);
  filterMgr.setTarget(TARGET_RED_CHANNEL |
                      TARGET_GREEN_CHANNEL |
                      TARGET_BLUE_CHANNEL |
                      TARGET_GRAY_CHANNEL |
                      TARGET_ALPHA_CHANNEL);

  ColorCurveWindow window(filter, filterMgr);
  if (window.doModal()) {
    // TODO save the curve?
  }
}
예제 #4
0
bool ResourcesLoader::next(base::UniquePtr<Resource>& resource)
{
  Resource* rawResource;
  if (m_queue.try_pop(rawResource)) {
    resource.reset(rawResource);
    return true;
  }
  else
    return false;
}
예제 #5
0
  SimpleColors(ColorPopup* colorPopup, TooltipManager* tooltips) {
    for (int i=0; i<g_simplePal->size(); ++i) {
      doc::color_t c = g_simplePal->getEntry(i);
      app::Color color =
        app::Color::fromRgb(doc::rgba_getr(c),
                            doc::rgba_getg(c),
                            doc::rgba_getb(c),
                            doc::rgba_geta(c));

      Item* item = new Item(colorPopup, color);
      item->InitTheme.connect(
        [item]{
          item->setSizeHint(gfx::Size(16, 16)*ui::guiscale());
          item->setStyle(skin::SkinTheme::instance()->styles.simpleColor());
        });
      item->initTheme();
      addChild(item);

      tooltips->addTooltipFor(
        item, g_simplePal->getEntryName(i), BOTTOM);
    }
  }
예제 #6
0
void ColorPopup::setColor(const app::Color& color,
                          const SetColorOptions options)
{
  m_color = color;

  if (m_simpleColors) {
    int r = color.getRed();
    int g = color.getGreen();
    int b = color.getBlue();
    int a = color.getAlpha();
    int i = g_simplePal->findExactMatch(r, g, b, a, -1);
    if (i >= 0)
      m_simpleColors->selectColor(i);
    else
      m_simpleColors->deselect();
  }

  if (color.getType() == app::Color::IndexType) {
    if (m_colorPalette) {
      m_colorPalette->deselect();
      m_colorPalette->selectColor(color.getIndex());
    }
  }

  m_sliders.setColor(m_color);
  if (!m_disableHexUpdate)
    m_hexColorEntry.setColor(m_color);

  if (options == ChangeType)
    selectColorType(m_color.getType());

  // Set the new color
  Shade shade = m_oldAndNew.getShade();
  shade.resize(2);
  shade[1] = (color.getType() == app::Color::IndexType ? color.toRgb(): color);
  if (!m_insideChange)
    shade[0] = shade[1];
  m_oldAndNew.setShade(shade);
}
예제 #7
0
namespace app {

using namespace ui;
using namespace doc;

enum {
  INDEX_MODE,
  RGB_MODE,
  HSV_MODE,
  HSL_MODE,
  GRAY_MODE,
  MASK_MODE,
  COLOR_MODES
};

static base::UniquePtr<doc::Palette> g_simplePal(nullptr);

class ColorPopup::SimpleColors : public HBox {
public:

  class Item : public Button {
  public:
    Item(ColorPopup* colorPopup, const app::Color& color)
      : Button("")
      , m_colorPopup(colorPopup)
      , m_color(color) {
    }

  private:
    void onClick(Event& ev) override {
      m_colorPopup->setColorWithSignal(m_color, ChangeType);
    }

    void onPaint(PaintEvent& ev) override {
      Graphics* g = ev.graphics();
      skin::SkinTheme* theme = skin::SkinTheme::instance();
      gfx::Rect rc = clientBounds();

      Button::onPaint(ev);

      rc.shrink(theme->calcBorder(this, style()));
      draw_color(g, rc, m_color, doc::ColorMode::RGB);
    }

    ColorPopup* m_colorPopup;
    app::Color m_color;
  };

  SimpleColors(ColorPopup* colorPopup, TooltipManager* tooltips) {
    for (int i=0; i<g_simplePal->size(); ++i) {
      doc::color_t c = g_simplePal->getEntry(i);
      app::Color color =
        app::Color::fromRgb(doc::rgba_getr(c),
                            doc::rgba_getg(c),
                            doc::rgba_getb(c),
                            doc::rgba_geta(c));

      Item* item = new Item(colorPopup, color);
      item->InitTheme.connect(
        [item]{
          item->setSizeHint(gfx::Size(16, 16)*ui::guiscale());
          item->setStyle(skin::SkinTheme::instance()->styles.simpleColor());
        });
      item->initTheme();
      addChild(item);

      tooltips->addTooltipFor(
        item, g_simplePal->getEntryName(i), BOTTOM);
    }
  }

  void selectColor(int index) {
    for (int i=0; i<g_simplePal->size(); ++i) {
      children()[i]->setSelected(i == index);
    }
  }

  void deselect() {
    for (int i=0; i<g_simplePal->size(); ++i) {
      children()[i]->setSelected(false);
    }
  }
};

ColorPopup::CustomButtonSet::CustomButtonSet()
  : ButtonSet(COLOR_MODES)
{
}

int ColorPopup::CustomButtonSet::countSelectedItems()
{
  int count = 0;
  for (int i=0; i<COLOR_MODES; ++i)
    if (getItem(i)->isSelected())
      ++count;
  return count;
}

void ColorPopup::CustomButtonSet::onSelectItem(Item* item, bool focusItem, ui::Message* msg)
{
  int count = countSelectedItems();
  int itemIndex = getItemIndex(item);

  if (itemIndex == INDEX_MODE ||
      itemIndex == MASK_MODE ||
      !msg ||
      // Any key modifier will act as multiple selection
      (!msg->shiftPressed() &&
       !msg->altPressed() &&
       !msg->ctrlPressed() &&
       !msg->cmdPressed())) {
    if (item &&
        item->isSelected() &&
        count == 1)
      return;

    for (int i=0; i<COLOR_MODES; ++i)
      if (getItem(i)->isSelected())
        getItem(i)->setSelected(false);
  }
  else {
    if (getItem(INDEX_MODE)->isSelected()) getItem(INDEX_MODE)->setSelected(false);
    if (getItem(MASK_MODE)->isSelected()) getItem(MASK_MODE)->setSelected(false);
  }

  if (item) {
    // Item already selected
    if (count == 1 && item == findSelectedItem())
      return;

    item->setSelected(!item->isSelected());
    if (focusItem)
      item->requestFocus();
  }
}

ColorPopup::ColorPopup(const ColorButtonOptions& options)
  : PopupWindowPin(" ", // Non-empty to create title-bar and close button
                   ClickBehavior::CloseOnClickInOtherWindow,
                   options.canPinSelector)
  , m_vbox(VERTICAL)
  , m_topBox(HORIZONTAL)
  , m_color(app::Color::fromMask())
  , m_closeButton(nullptr)
  , m_colorPaletteContainer(options.showIndexTab ?
                            new ui::View: nullptr)
  , m_colorPalette(options.showIndexTab ?
                   new PaletteView(false, PaletteView::SelectOneColor, this, 7*guiscale()):
                   nullptr)
  , m_simpleColors(nullptr)
  , m_oldAndNew(Shade(2), ColorShades::ClickEntries)
  , m_maskLabel("Transparent Color Selected")
  , m_canPin(options.canPinSelector)
  , m_insideChange(false)
  , m_disableHexUpdate(false)
{
  if (options.showSimpleColors) {
    if (!g_simplePal) {
      ResourceFinder rf;
      rf.includeDataDir("palettes/tags.gpl");
      if (rf.findFirst())
        g_simplePal.reset(load_palette(rf.filename().c_str()));
    }

    if (g_simplePal)
      m_simpleColors = new SimpleColors(this, &m_tooltips);
  }

  ButtonSet::Item* item = m_colorType.addItem("Index");
  item->setFocusStop(false);
  if (!options.showIndexTab)
    item->setVisible(false);

  m_colorType.addItem("RGB")->setFocusStop(false);
  m_colorType.addItem("HSV")->setFocusStop(false);
  m_colorType.addItem("HSL")->setFocusStop(false);
  m_colorType.addItem("Gray")->setFocusStop(false);
  m_colorType.addItem("Mask")->setFocusStop(false);

  m_topBox.setBorder(gfx::Border(0));
  m_topBox.setChildSpacing(0);

  if (m_colorPalette) {
    m_colorPaletteContainer->attachToView(m_colorPalette);
    m_colorPaletteContainer->setExpansive(true);
  }
  m_sliders.setExpansive(true);

  m_topBox.addChild(&m_colorType);
  m_topBox.addChild(new Separator("", VERTICAL));
  m_topBox.addChild(&m_hexColorEntry);
  m_topBox.addChild(&m_oldAndNew);

  // TODO fix this hack for close button in popup window
  // Move close button (decorative widget) inside the m_topBox
  {
    WidgetsList decorators;
    for (auto child : children()) {
      if (child->type() == kWindowCloseButtonWidget) {
        m_closeButton = child;
        removeChild(child);
        break;
      }
    }
    if (m_closeButton) {
      m_topBox.addChild(new BoxFiller);
      VBox* vbox = new VBox;
      vbox->addChild(m_closeButton);
      m_topBox.addChild(vbox);
    }
  }
  setText("");                  // To remove title

  m_vbox.addChild(&m_tooltips);
  if (m_simpleColors)
    m_vbox.addChild(m_simpleColors);
  m_vbox.addChild(&m_topBox);
  if (m_colorPaletteContainer)
    m_vbox.addChild(m_colorPaletteContainer);
  m_vbox.addChild(&m_sliders);
  m_vbox.addChild(&m_maskLabel);
  addChild(&m_vbox);

  m_colorType.ItemChange.connect(base::Bind<void>(&ColorPopup::onColorTypeClick, this));

  m_sliders.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
  m_hexColorEntry.ColorChange.connect(&ColorPopup::onColorHexEntryChange, this);
  m_oldAndNew.Click.connect(&ColorPopup::onSelectOldColor, this);

  // Set RGB just for the sizeHint(), and then deselect the color type
  // (the first setColor() call will setup it correctly.)
  selectColorType(app::Color::RgbType);
  m_colorType.deselectItems();

  m_onPaletteChangeConn =
    App::instance()->PaletteChange.connect(&ColorPopup::onPaletteChange, this);

  InitTheme.connect(
    [this]{
      setSizeHint(gfx::Size(300*guiscale(), sizeHint().h));
    });
  initTheme();
}

ColorPopup::~ColorPopup()
{
}

void ColorPopup::setColor(const app::Color& color,
                          const SetColorOptions options)
{
  m_color = color;

  if (m_simpleColors) {
    int r = color.getRed();
    int g = color.getGreen();
    int b = color.getBlue();
    int a = color.getAlpha();
    int i = g_simplePal->findExactMatch(r, g, b, a, -1);
    if (i >= 0)
      m_simpleColors->selectColor(i);
    else
      m_simpleColors->deselect();
  }

  if (color.getType() == app::Color::IndexType) {
    if (m_colorPalette) {
      m_colorPalette->deselect();
      m_colorPalette->selectColor(color.getIndex());
    }
  }

  m_sliders.setColor(m_color);
  if (!m_disableHexUpdate)
    m_hexColorEntry.setColor(m_color);

  if (options == ChangeType)
    selectColorType(m_color.getType());

  // Set the new color
  Shade shade = m_oldAndNew.getShade();
  shade.resize(2);
  shade[1] = (color.getType() == app::Color::IndexType ? color.toRgb(): color);
  if (!m_insideChange)
    shade[0] = shade[1];
  m_oldAndNew.setShade(shade);
}

app::Color ColorPopup::getColor() const
{
  return m_color;
}

bool ColorPopup::onProcessMessage(ui::Message* msg)
{
  switch (msg->type()) {
    case kSetCursorMessage: {
      if (m_canPin) {
        gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
        if (hitTest(mousePos) == HitTestCaption) {
          set_mouse_cursor(kMoveCursor);
          return true;
        }
      }
      break;
    }
  }
  return PopupWindowPin::onProcessMessage(msg);
}

void ColorPopup::onWindowResize()
{
  PopupWindowPin::onWindowResize();

  if (m_closeButton) {
    gfx::Rect rc = m_closeButton->bounds();
    if (rc.x2() > bounds().x2()) {
      rc.x = bounds().x2() - rc.w;
      m_closeButton->setBounds(rc);
    }
  }
}

void ColorPopup::onMakeFloating()
{
  PopupWindowPin::onMakeFloating();

  if (m_canPin) {
    setSizeable(true);
    setMoveable(true);
  }
}

void ColorPopup::onMakeFixed()
{
  PopupWindowPin::onMakeFixed();

  if (m_canPin) {
    setSizeable(false);
    setMoveable(true);
  }
}

void ColorPopup::onPaletteViewIndexChange(int index, ui::MouseButtons buttons)
{
  base::ScopedValue<bool> restore(m_insideChange, true,
                                  m_insideChange);

  setColorWithSignal(app::Color::fromIndex(index), ChangeType);
}

void ColorPopup::onColorSlidersChange(ColorSlidersChangeEvent& ev)
{
  base::ScopedValue<bool> restore(m_insideChange, true,
                                  m_insideChange);

  setColorWithSignal(ev.color(), DontChangeType);
  findBestfitIndex(ev.color());
}

void ColorPopup::onColorHexEntryChange(const app::Color& color)
{
  base::ScopedValue<bool> restore(m_insideChange, true,
                                  m_insideChange);

  // Disable updating the hex entry so we don't override what the user
  // is writting in the text field.
  m_disableHexUpdate = true;

  setColorWithSignal(color, ChangeType);
  findBestfitIndex(color);

  // If we are in edit mode, the "m_disableHexUpdate" will be changed
  // to false in onPaletteChange() after the color bar timer is
  // triggered. In this way we don't modify the hex field when the
  // user is editing it and the palette "edit mode" is enabled.
  if (!inEditMode())
    m_disableHexUpdate = false;
}

void ColorPopup::onSelectOldColor()
{
  Shade shade = m_oldAndNew.getShade();
  int hot = m_oldAndNew.getHotEntry();
  if (hot >= 0 &&
      hot < int(shade.size())) {
    setColorWithSignal(shade[hot], DontChangeType);
  }
}

void ColorPopup::onSimpleColorClick()
{
  m_colorType.deselectItems();
  if (!g_simplePal)
    return;

  app::Color color = getColor();

  // Find bestfit palette entry
  int r = color.getRed();
  int g = color.getGreen();
  int b = color.getBlue();
  int a = color.getAlpha();

  // Search for the closest color to the RGB values
  int i = g_simplePal->findBestfit(r, g, b, a, 0);
  if (i >= 0) {
    color_t c = g_simplePal->getEntry(i);
    color = app::Color::fromRgb(doc::rgba_getr(c),
                                doc::rgba_getg(c),
                                doc::rgba_getb(c),
                                doc::rgba_geta(c));
  }

  setColorWithSignal(color, ChangeType);
}

void ColorPopup::onColorTypeClick()
{
  base::ScopedValue<bool> restore(m_insideChange, true,
                                  m_insideChange);

  if (m_simpleColors)
    m_simpleColors->deselect();

  app::Color newColor = getColor();

  switch (m_colorType.selectedItem()) {
    case INDEX_MODE:
      newColor = app::Color::fromIndex(newColor.getIndex());
      break;
    case RGB_MODE:
      newColor = app::Color::fromRgb(newColor.getRed(),
                                     newColor.getGreen(),
                                     newColor.getBlue(),
                                     newColor.getAlpha());
      break;
    case HSV_MODE:
      newColor = app::Color::fromHsv(newColor.getHsvHue(),
                                     newColor.getHsvSaturation(),
                                     newColor.getHsvValue(),
                                     newColor.getAlpha());
      break;
    case HSL_MODE:
      newColor = app::Color::fromHsl(newColor.getHslHue(),
                                     newColor.getHslSaturation(),
                                     newColor.getHslLightness(),
                                     newColor.getAlpha());
      break;
    case GRAY_MODE:
      newColor = app::Color::fromGray(newColor.getGray(),
                                      newColor.getAlpha());
      break;
    case MASK_MODE:
      newColor = app::Color::fromMask();
      break;
  }

  setColorWithSignal(newColor, ChangeType);
}

void ColorPopup::onPaletteChange()
{
  base::ScopedValue<bool> restore(m_insideChange, inEditMode(),
                                  m_insideChange);

  setColor(getColor(), DontChangeType);
  invalidate();

  if (inEditMode())
    m_disableHexUpdate = false;
}

void ColorPopup::findBestfitIndex(const app::Color& color)
{
  if (!m_colorPalette)
    return;

  // Find bestfit palette entry
  int r = color.getRed();
  int g = color.getGreen();
  int b = color.getBlue();
  int a = color.getAlpha();

  // Search for the closest color to the RGB values
  int i = get_current_palette()->findBestfit(r, g, b, a, 0);
  if (i >= 0) {
    m_colorPalette->deselect();
    m_colorPalette->selectColor(i);
  }
}

void ColorPopup::setColorWithSignal(const app::Color& color,
                                    const SetColorOptions options)
{
  Shade shade = m_oldAndNew.getShade();

  setColor(color, options);

  shade.resize(2);
  shade[1] = color;
  m_oldAndNew.setShade(shade);

  // Fire ColorChange signal
  ColorChange(color);
}

void ColorPopup::selectColorType(app::Color::Type type)
{
  if (m_colorPaletteContainer)
    m_colorPaletteContainer->setVisible(type == app::Color::IndexType);

  m_maskLabel.setVisible(type == app::Color::MaskType);

  // Count selected items.
  if (m_colorType.countSelectedItems() < 2) {
    switch (type) {
      case app::Color::IndexType:
        if (m_colorPalette)
          m_colorType.setSelectedItem(INDEX_MODE);
        else
          m_colorType.setSelectedItem(RGB_MODE);
        break;
      case app::Color::RgbType:   m_colorType.setSelectedItem(RGB_MODE); break;
      case app::Color::HsvType:   m_colorType.setSelectedItem(HSV_MODE); break;
      case app::Color::HslType:   m_colorType.setSelectedItem(HSL_MODE); break;
      case app::Color::GrayType:  m_colorType.setSelectedItem(GRAY_MODE); break;
      case app::Color::MaskType:  m_colorType.setSelectedItem(MASK_MODE); break;
    }
  }

  std::vector<app::Color::Type> types;
  if (m_colorType.getItem(RGB_MODE)->isSelected())
    types.push_back(app::Color::RgbType);
  if (m_colorType.getItem(HSV_MODE)->isSelected())
    types.push_back(app::Color::HsvType);
  if (m_colorType.getItem(HSL_MODE)->isSelected())
    types.push_back(app::Color::HslType);
  if (m_colorType.getItem(GRAY_MODE)->isSelected())
    types.push_back(app::Color::GrayType);
  m_sliders.setColorTypes(types);

  // Remove focus from hidden RGB/HSV/HSL text entries
  auto widget = manager()->getFocus();
  if (widget && !widget->isVisible()) {
    auto window = widget->window();
    if (window && window == this)
      widget->releaseFocus();
  }

  m_vbox.layout();
  m_vbox.invalidate();
}

bool ColorPopup::inEditMode()
{
  return
    // TODO use other flag instead of m_canPin, here we want to ask if
    // this ColorPopup is related to the main ColorBar (instead of
    // other ColorButtons like the one in "Replace Color", etc.)
    (m_canPin) &&
    (ColorBar::instance()->inEditMode());
}

} // namespace app
예제 #8
0
ColorPopup::ColorPopup(const ColorButtonOptions& options)
  : PopupWindowPin(" ", // Non-empty to create title-bar and close button
                   ClickBehavior::CloseOnClickInOtherWindow,
                   options.canPinSelector)
  , m_vbox(VERTICAL)
  , m_topBox(HORIZONTAL)
  , m_color(app::Color::fromMask())
  , m_closeButton(nullptr)
  , m_colorPaletteContainer(options.showIndexTab ?
                            new ui::View: nullptr)
  , m_colorPalette(options.showIndexTab ?
                   new PaletteView(false, PaletteView::SelectOneColor, this, 7*guiscale()):
                   nullptr)
  , m_simpleColors(nullptr)
  , m_oldAndNew(Shade(2), ColorShades::ClickEntries)
  , m_maskLabel("Transparent Color Selected")
  , m_canPin(options.canPinSelector)
  , m_insideChange(false)
  , m_disableHexUpdate(false)
{
  if (options.showSimpleColors) {
    if (!g_simplePal) {
      ResourceFinder rf;
      rf.includeDataDir("palettes/tags.gpl");
      if (rf.findFirst())
        g_simplePal.reset(load_palette(rf.filename().c_str()));
    }

    if (g_simplePal)
      m_simpleColors = new SimpleColors(this, &m_tooltips);
  }

  ButtonSet::Item* item = m_colorType.addItem("Index");
  item->setFocusStop(false);
  if (!options.showIndexTab)
    item->setVisible(false);

  m_colorType.addItem("RGB")->setFocusStop(false);
  m_colorType.addItem("HSV")->setFocusStop(false);
  m_colorType.addItem("HSL")->setFocusStop(false);
  m_colorType.addItem("Gray")->setFocusStop(false);
  m_colorType.addItem("Mask")->setFocusStop(false);

  m_topBox.setBorder(gfx::Border(0));
  m_topBox.setChildSpacing(0);

  if (m_colorPalette) {
    m_colorPaletteContainer->attachToView(m_colorPalette);
    m_colorPaletteContainer->setExpansive(true);
  }
  m_sliders.setExpansive(true);

  m_topBox.addChild(&m_colorType);
  m_topBox.addChild(new Separator("", VERTICAL));
  m_topBox.addChild(&m_hexColorEntry);
  m_topBox.addChild(&m_oldAndNew);

  // TODO fix this hack for close button in popup window
  // Move close button (decorative widget) inside the m_topBox
  {
    WidgetsList decorators;
    for (auto child : children()) {
      if (child->type() == kWindowCloseButtonWidget) {
        m_closeButton = child;
        removeChild(child);
        break;
      }
    }
    if (m_closeButton) {
      m_topBox.addChild(new BoxFiller);
      VBox* vbox = new VBox;
      vbox->addChild(m_closeButton);
      m_topBox.addChild(vbox);
    }
  }
  setText("");                  // To remove title

  m_vbox.addChild(&m_tooltips);
  if (m_simpleColors)
    m_vbox.addChild(m_simpleColors);
  m_vbox.addChild(&m_topBox);
  if (m_colorPaletteContainer)
    m_vbox.addChild(m_colorPaletteContainer);
  m_vbox.addChild(&m_sliders);
  m_vbox.addChild(&m_maskLabel);
  addChild(&m_vbox);

  m_colorType.ItemChange.connect(base::Bind<void>(&ColorPopup::onColorTypeClick, this));

  m_sliders.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
  m_hexColorEntry.ColorChange.connect(&ColorPopup::onColorHexEntryChange, this);
  m_oldAndNew.Click.connect(&ColorPopup::onSelectOldColor, this);

  // Set RGB just for the sizeHint(), and then deselect the color type
  // (the first setColor() call will setup it correctly.)
  selectColorType(app::Color::RgbType);
  m_colorType.deselectItems();

  m_onPaletteChangeConn =
    App::instance()->PaletteChange.connect(&ColorPopup::onPaletteChange, this);

  InitTheme.connect(
    [this]{
      setSizeHint(gfx::Size(300*guiscale(), sizeHint().h));
    });
  initTheme();
}
예제 #9
0
 void deselect() {
   for (int i=0; i<g_simplePal->size(); ++i) {
     children()[i]->setSelected(false);
   }
 }
예제 #10
0
 void selectColor(int index) {
   for (int i=0; i<g_simplePal->size(); ++i) {
     children()[i]->setSelected(i == index);
   }
 }
예제 #11
0
  ToolLoopBase(Editor* editor,
               tools::Tool* tool,
               tools::Ink* ink,
               Document* document,
               tools::ToolLoop::Button button,
               const app::Color& fgColor,
               const app::Color& bgColor)
    : m_editor(editor)
    , m_tool(tool)
    , m_brush(App::instance()->contextBar()->activeBrush(m_tool))
    , m_document(document)
    , m_sprite(editor->sprite())
    , m_layer(editor->layer())
    , m_frame(editor->frame())
    , m_rgbMap(nullptr)
    , m_docPref(Preferences::instance().document(m_document))
    , m_toolPref(Preferences::instance().tool(m_tool))
    , m_opacity(m_toolPref.opacity())
    , m_tolerance(m_toolPref.tolerance())
    , m_contiguous(m_toolPref.contiguous())
    , m_button(button)
    , m_ink(ink->clone())
    , m_controller(m_tool->getController(m_button))
    , m_pointShape(m_tool->getPointShape(m_button))
    , m_intertwine(m_tool->getIntertwine(m_button))
    , m_tracePolicy(m_tool->getTracePolicy(m_button))
    , m_symmetry(nullptr)
    , m_fgColor(color_utils::color_for_target_mask(fgColor, ColorTarget(m_layer)))
    , m_bgColor(color_utils::color_for_target_mask(bgColor, ColorTarget(m_layer)))
    , m_primaryColor(button == tools::ToolLoop::Left ? m_fgColor: m_bgColor)
    , m_secondaryColor(button == tools::ToolLoop::Left ? m_bgColor: m_fgColor)
  {
    tools::FreehandAlgorithm algorithm = m_toolPref.freehandAlgorithm();

    if (m_tracePolicy == tools::TracePolicy::Accumulate ||
        m_tracePolicy == tools::TracePolicy::AccumulateUpdateLast) {
      tools::ToolBox* toolbox = App::instance()->toolBox();

      switch (algorithm) {
        case tools::FreehandAlgorithm::DEFAULT:
          m_intertwine = toolbox->getIntertwinerById(tools::WellKnownIntertwiners::AsLines);
          m_tracePolicy = tools::TracePolicy::Accumulate;
          break;
        case tools::FreehandAlgorithm::PIXEL_PERFECT:
          m_intertwine = toolbox->getIntertwinerById(tools::WellKnownIntertwiners::AsPixelPerfect);
          m_tracePolicy = tools::TracePolicy::AccumulateUpdateLast;
          break;
        case tools::FreehandAlgorithm::DOTS:
          m_intertwine = toolbox->getIntertwinerById(tools::WellKnownIntertwiners::None);
          m_tracePolicy = tools::TracePolicy::Accumulate;
          break;
      }
    }

    // Symmetry mode
    if (Preferences::instance().symmetryMode.enabled()) {
      switch (m_docPref.symmetry.mode()) {

        case app::gen::SymmetryMode::NONE:
          ASSERT(m_symmetry == nullptr);
          break;

        case app::gen::SymmetryMode::HORIZONTAL:
          m_symmetry.reset(new app::tools::HorizontalSymmetry(m_docPref.symmetry.xAxis()));
          break;

        case app::gen::SymmetryMode::VERTICAL:
          m_symmetry.reset(new app::tools::VerticalSymmetry(m_docPref.symmetry.yAxis()));
          break;
      }
    }

    // Ignore opacity for these inks
    if (!tools::inkHasOpacity(m_toolPref.ink()) &&
        m_brush->type() != kImageBrushType &&
        !m_ink->isEffect()) {
      m_opacity = 255;
    }

    if (m_toolPref.ink() == tools::InkType::SHADING) {
      m_shadingRemap.reset(
        App::instance()->contextBar()->createShadeRemap(
          button == tools::ToolLoop::Left));
    }
  }
예제 #12
0
tools::Symmetry* getSymmetry() override { return m_symmetry.get(); }
예제 #13
0
namespace app {

using namespace filters;

static base::UniquePtr<ColorCurve> the_curve;

class ColorCurveWindow : public FilterWindow {
public:
  ColorCurveWindow(ColorCurveFilter& filter, FilterManagerImpl& filterMgr)
    : FilterWindow("Color Curve", "ColorCurve", &filterMgr,
                   WithChannelsSelector,
                   WithoutTiledCheckBox)
    , m_filter(filter)
    , m_editor(filter.getCurve(), gfx::Rect(0, 0, 256, 256))
  {
    m_view.attachToView(&m_editor);
    m_view.setExpansive(true);
    m_view.setMinSize(gfx::Size(128, 64));

    getContainer()->addChild(&m_view);

    m_editor.CurveEditorChange.connect(&ColorCurveWindow::onCurveChange, this);
  }

protected:

  void onCurveChange()
  {
    // The color curve in the filter is the same refereced by the
    // editor. But anyway, we have to re-set the same curve in the
    // filter to regenerate the map used internally by the filter
    // (which is calculated inside setCurve() method).
    m_filter.setCurve(m_editor.getCurve());

    restartPreview();
  }

private:
  ColorCurveFilter& m_filter;
  ui::View m_view;
  ColorCurveEditor m_editor;
};

class ColorCurveCommand : public Command {
public:
  ColorCurveCommand();
  Command* clone() const override { return new ColorCurveCommand(*this); }

protected:
  bool onEnabled(Context* context) override;
  void onExecute(Context* context) override;
};

ColorCurveCommand::ColorCurveCommand()
  : Command("ColorCurve",
            "Color Curve",
            CmdRecordableFlag)
{
}

bool ColorCurveCommand::onEnabled(Context* context)
{
  return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
                             ContextFlags::HasActiveSprite);
}

void ColorCurveCommand::onExecute(Context* context)
{
  // Default curve
  if (!the_curve) {
    // TODO load the curve?

    the_curve.reset(new ColorCurve(ColorCurve::Linear));
    the_curve->addPoint(gfx::Point(0, 0));
    the_curve->addPoint(gfx::Point(255, 255));
  }

  ColorCurveFilter filter;
  filter.setCurve(the_curve.get());

  FilterManagerImpl filterMgr(context, &filter);
  filterMgr.setTarget(TARGET_RED_CHANNEL |
                      TARGET_GREEN_CHANNEL |
                      TARGET_BLUE_CHANNEL |
                      TARGET_GRAY_CHANNEL |
                      TARGET_ALPHA_CHANNEL);

  ColorCurveWindow window(filter, filterMgr);
  if (window.doModal()) {
    // TODO save the curve?
  }
}

Command* CommandFactory::createColorCurveCommand()
{
  return new ColorCurveCommand;
}

} // namespace app