New color-bar with scrollable palette-view.

+ Removed palette-view from Palette Editor.
+ Fixed problems pasting RGB values in #hex format and HSV sliders.
This commit is contained in:
David Capello 2011-02-23 19:29:57 -03:00
parent 22a45a9acb
commit b0ff50ec0e
9 changed files with 289 additions and 654 deletions

View File

@ -1,12 +1,9 @@
<!-- ASE - Allegro Sprite Editor -->
<!-- Copyright (C) 2001-2011 by David Capello -->
<jinete>
<window text="Palette" name="palette_editor">
<window text="Palette Editor (F4)" name="palette_editor">
<box vertical="true">
<box horizontal="true" expansive="true">
<box vertical="true">
<view name="palette_editor" /> <!-- custom-widget -->
</box>
<box vertical="true" expansive="true">
<box horizontal="true" childspacing="0" noborders="true">
<radio group="1" text="RGB" name="select_rgb" looklike="button" selected="true" />

View File

@ -156,9 +156,7 @@ static Slider *H_slider, *S_slider, *V_slider;
static Widget *R_entry, *G_entry, *B_entry;
static Widget *H_entry, *S_entry, *V_entry;
static Widget *hex_entry;
static PaletteView* palette_editor;
static Widget* more_options = NULL;
static bool disable_colorbar_signals = false;
static bool window_msg_proc(JWidget widget, JMessage msg);
static bool window_close_hook(JWidget widget, void *data);
@ -180,7 +178,6 @@ static void update_slider_bgcolor(Slider* slider, const Color& color);
static void update_slider_bgcolors();
static void update_current_sprite_palette(const char* operationName);
static void update_colorbar();
static bool palette_editor_change_hook(JWidget widget, void *data);
static bool select_rgb_hook(JWidget widget, void *data);
static bool select_hsv_hook(JWidget widget, void *data);
static bool expand_button_select_hook(JWidget widget, void *data);
@ -222,7 +219,6 @@ void PaletteEditorCommand::onLoadParams(Params* params)
void PaletteEditorCommand::onExecute(Context* context)
{
View* palette_editor_view;
Widget* select_rgb;
Widget* select_hsv;
Button* expand_button;
@ -288,20 +284,10 @@ void PaletteEditorCommand::onExecute(Context* context)
"save", &button_save,
"ramp", &button_ramp,
"sort", &button_sort,
"quantize", &button_quantize,
"palette_editor", &palette_editor_view, NULL);
"quantize", &button_quantize, NULL);
// Custom widgets
if (first_time) {
palette_editor = new PaletteView(true);
palette_editor->setBoxSize(4*jguiscale());
palette_editor_view->attachToView(palette_editor);
palette_editor_view->makeVisibleAllScrollableArea();
// Set palette editor columns
palette_editor->setColumns(16);
// Setup slider bg painters
R_slider->setProperty(PropertyPtr(new SkinSliderProperty(new ColorSliderBgPainter(ColorSliderBgPainter::Red))));
G_slider->setProperty(PropertyPtr(new SkinSliderProperty(new ColorSliderBgPainter(ColorSliderBgPainter::Green))));
@ -332,7 +318,6 @@ void PaletteEditorCommand::onExecute(Context* context)
HOOK(S_entry, JI_SIGNAL_ENTRY_CHANGE, entryHSV_change_hook, 0);
HOOK(V_entry, JI_SIGNAL_ENTRY_CHANGE, entryHSV_change_hook, 0);
HOOK(hex_entry, JI_SIGNAL_ENTRY_CHANGE, hex_entry_change_hook, 0);
HOOK(palette_editor, SIGNAL_PALETTE_EDITOR_CHANGE, palette_editor_change_hook, 0);
HOOK(select_rgb, JI_SIGNAL_RADIO_CHANGE, select_rgb_hook, 0);
HOOK(select_hsv, JI_SIGNAL_RADIO_CHANGE, select_hsv_hook, 0);
HOOK(expand_button, JI_SIGNAL_BUTTON_SELECT, expand_button_select_hook, 0);
@ -456,6 +441,7 @@ static void save_command(JWidget widget)
static void ramp_command(JWidget widget)
{
PaletteView* palette_editor = app_get_colorbar()->getPaletteView();
int range_type = palette_editor->getRangeType();
int i1 = palette_editor->get1stColor();
int i2 = palette_editor->get2ndColor();
@ -504,6 +490,8 @@ static bool sort_by_criteria(Palette* palette, int from, int to, JList selected_
static void sort_command(JWidget widget)
{
PaletteView* palette_editor = app_get_colorbar()->getPaletteView();
if (Alert::show("ASE Beta<<Sort command is not available in this beta version.||&OK")) // TODO remove this
return;
@ -915,7 +903,6 @@ static bool hex_entry_change_hook(JWidget widget, void *data)
Palette* palette = get_current_palette();
std::string text = hex_entry->getText();
int r, g, b;
bool array[256];
int c;
// Fill with zeros at the end of the text
@ -931,6 +918,8 @@ static bool hex_entry_change_hook(JWidget widget, void *data)
Hsv hsv(Rgb(r, g, b));
bool array[256];
PaletteView* palette_editor = app_get_colorbar()->getPaletteView();
palette_editor->getSelectedEntries(array);
for (c=0; c<256; c++) {
if (array[c]) {
@ -939,8 +928,8 @@ static bool hex_entry_change_hook(JWidget widget, void *data)
}
H_slider->setValue(hsv.hueInt());
V_slider->setValue(hsv.saturationInt());
S_slider->setValue(hsv.valueInt());
S_slider->setValue(hsv.saturationInt());
V_slider->setValue(hsv.valueInt());
update_entries_from_sliders();
update_slider_bgcolors();
@ -1031,6 +1020,7 @@ static void update_current_sprite_palette(const char* operationName)
}
}
PaletteView* palette_editor = app_get_colorbar()->getPaletteView();
palette_editor->invalidate();
if (!jmanager_timer_is_running(redraw_timer_id))
@ -1053,30 +1043,6 @@ static void update_sliders_from_color(const Color& color)
V_slider->setValue(color.getValue());
}
static bool palette_editor_change_hook(JWidget widget, void *data)
{
Color color = Color::fromIndex(palette_editor->get2ndColor());
// colorviewer_set_color(colorviewer, color);
{
disable_colorbar_signals = true;
if (jmouse_b(0) & 2)
app_get_colorbar()->setBgColor(color);
else
app_get_colorbar()->setFgColor(color);
disable_colorbar_signals = false;
}
update_sliders_from_color(color); // Update sliders
update_entries_from_sliders(); // Update entries
update_hex_entry(); // Update hex field
update_slider_bgcolors();
return false;
}
static bool select_rgb_hook(JWidget widget, void *data)
{
R_label->setVisible(true);
@ -1184,7 +1150,9 @@ static bool expand_button_select_hook(JWidget widget, void *data)
static void modify_rgb_of_selected_entries(const Rgb& dst_rgb, bool set_r, bool set_g, bool set_b)
{
bool array[256];
PaletteView* palette_editor = app_get_colorbar()->getPaletteView();
palette_editor->getSelectedEntries(array);
ase_uint32 src_color;
int r, g, b;
@ -1207,9 +1175,10 @@ static void modify_rgb_of_selected_entries(const Rgb& dst_rgb, bool set_r, bool
static void modify_hsv_of_selected_entries(const Hsv& dst_hsv, bool set_h, bool set_s, bool set_v)
{
bool array[256];
PaletteView* palette_editor = app_get_colorbar()->getPaletteView();
palette_editor->getSelectedEntries(array);
ase_uint32 src_color;
ase_uint32 src_color;
Palette* palette = get_current_palette();
for (int c=0; c<256; c++) {
if (array[c]) {
@ -1239,16 +1208,10 @@ static void modify_hsv_of_selected_entries(const Hsv& dst_hsv, bool set_h, bool
static void on_color_changed(const Color& color)
{
if (disable_colorbar_signals)
return;
if (color.isValid() && color.getType() == Color::IndexType) {
int index = color.getIndex();
palette_editor->selectColor(index);
update_sliders_from_color(color); // Update sliders
update_entries_from_sliders(); // Update entries
update_hex_entry(); // Update hex field
update_hex_entry(); // Update hex field
update_slider_bgcolors();
jwidget_flush_redraw(window);

View File

@ -27,6 +27,7 @@
#include "raster/sprite.h"
#include "settings/ui_settings_impl.h"
#include "ui_context.h"
#include "widgets/color_bar.h"
#include "widgets/tabs.h"
UIContext* UIContext::m_instance = NULL;
@ -78,6 +79,9 @@ void UIContext::onSetCurrentSprite(Sprite* sprite)
// Select the sprite in the tabs.
app_get_tabsbar()->selectTab(sprite);
// Change the image-type of color bar.
app_get_colorbar()->setImgType(app_get_current_image_type());
// Change the main frame title.
base::string defaultTitle = PACKAGE " v" VERSION;
base::string title;

View File

@ -21,554 +21,192 @@
#include <allegro.h>
#include <cstring>
#include "app.h"
#include "app/color.h"
#include "base/bind.h"
#include "commands/commands.h"
#include "commands/params.h"
#include "console.h"
#include "core/cfg.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "gui/gui.h"
#include "modules/editors.h"
#include "modules/gfx.h"
#include "gui/list.h"
#include "gui/message.h"
#include "modules/gui.h"
#include "modules/palettes.h"
#include "raster/image.h"
#include "raster/palette.h"
#include "raster/sprite.h"
#include "raster/undo.h"
#include "skin/skin_theme.h"
#include "sprite_wrappers.h"
#include "ui_context.h"
#include "widgets/color_bar.h"
#include "widgets/color_selector.h"
#include "widgets/statebar.h"
#define COLORBAR_MAX_COLORS 256
#define ENTRYSIZE_MIN 12
#define ENTRYSIZE_MAX 64
//////////////////////////////////////////////////////////////////////
// ColorBar::ScrollableView class
// Pixels
#define FGBUTTON_SIZE (16*jguiscale())
#define BGBUTTON_SIZE (18*jguiscale())
using namespace gfx;
int colorbar_type()
ColorBar::ScrollableView::ScrollableView()
{
static int type = 0;
if (!type)
type = ji_register_widget_type();
return type;
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
int l = theme->get_part(PART_EDITOR_SELECTED_W)->w;
int t = theme->get_part(PART_EDITOR_SELECTED_N)->h;
int r = theme->get_part(PART_EDITOR_SELECTED_E)->w;
int b = theme->get_part(PART_EDITOR_SELECTED_S)->h;
jwidget_set_border(this, l, t, r, b);
}
bool ColorBar::ScrollableView::onProcessMessage(JMessage msg)
{
switch (msg->type) {
case JM_DRAW:
{
Viewport* viewport = getViewport();
Widget* child = reinterpret_cast<Widget*>(jlist_first_data(viewport->children));
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
theme->draw_bounds_nw(ji_screen,
rc->x1, rc->y1,
rc->x2-1, rc->y2-1,
hasFocus() ? PART_EDITOR_SELECTED_NW:
PART_EDITOR_NORMAL_NW, false);
}
return true;
}
return View::onProcessMessage(msg);
}
//////////////////////////////////////////////////////////////////////
// ColorBar class
ColorBar::ColorBar(int align)
: Widget(colorbar_type())
, m_fgcolor(Color::fromIndex(15))
, m_bgcolor(Color::fromIndex(0))
: Box(align)
, m_paletteButton("EDIT PAL")
, m_paletteView(false)
, m_fgColor(Color::fromIndex(15), IMAGE_INDEXED)
, m_bgColor(Color::fromIndex(0), IMAGE_INDEXED)
{
m_entrySize = 16;
m_firstIndex = 0;
m_columns = 2;
m_colorsPerColumn = 12;
m_hot = HOTCOLOR_NONE;
m_hot_editing = HOTCOLOR_NONE;
m_hot_drag = HOTCOLOR_NONE;
m_hot_drop = HOTCOLOR_NONE;
setBorder(gfx::Border(1*jguiscale()));
child_spacing = 1*jguiscale();
jwidget_focusrest(this, true);
this->setAlign(align);
m_paletteView.setBoxSize(6*jguiscale());
m_paletteView.setColumns(4);
m_fgColor.setPreferredSize(0, m_fgColor.getPreferredSize().h);
m_bgColor.setPreferredSize(0, m_bgColor.getPreferredSize().h);
this->border_width.l = 2;
this->border_width.t = 2;
this->border_width.r = 2;
this->border_width.b = 2;
m_scrollableView.attachToView(&m_paletteView);
int w = (m_scrollableView.getBorder().getSize().w +
m_scrollableView.getViewport()->getBorder().getSize().w +
m_paletteView.getPreferredSize().w +
getTheme()->scrollbar_size);
jwidget_set_min_size(&m_scrollableView, w, 0);
jwidget_expansive(&m_scrollableView, true);
jwidget_add_child(this, &m_paletteButton);
jwidget_add_child(this, &m_scrollableView);
jwidget_add_child(this, &m_fgColor);
jwidget_add_child(this, &m_bgColor);
this->border_width.l = 2*jguiscale();
this->border_width.t = 2*jguiscale();
this->border_width.r = 2*jguiscale();
this->border_width.b = 2*jguiscale();
this->child_spacing = 2*jguiscale();
m_paletteView.IndexChange.connect(&ColorBar::onPaletteIndexChange, this);
m_fgColor.Change.connect(&ColorBar::onFgColorButtonChange, this);
m_bgColor.Change.connect(&ColorBar::onBgColorButtonChange, this);
// Get selected colors
m_fgcolor = get_config_color("ColorBar", "FG", m_fgcolor);
m_bgcolor = get_config_color("ColorBar", "BG", m_bgcolor);
setFgColor(get_config_color("ColorBar", "FG", getFgColor()));
setBgColor(get_config_color("ColorBar", "BG", getBgColor()));
// Get color-bar configuration
m_columns = get_config_int("ColorBar", "Columns", m_columns);
m_columns = MID(1, m_columns, 4);
// Change color-bar background color (not ColorBar::setBgColor)
Widget::setBgColor(((SkinTheme*)getTheme())->get_tab_selected_face_color());
m_paletteView.setBgColor(((SkinTheme*)getTheme())->get_tab_selected_face_color());
m_entrySize = get_config_int("ColorBar", "EntrySize", m_entrySize);
m_entrySize = MID(ENTRYSIZE_MIN, m_entrySize, ENTRYSIZE_MAX);
// Change labels foreground color
setup_mini_look(&m_paletteButton);
m_paletteButton.Click.connect(Bind<void>(&ColorBar::onPaletteButtonClick, this));
setDoubleBuffered(true);
}
ColorBar::~ColorBar()
{
set_config_color("ColorBar", "FG", m_fgcolor);
set_config_color("ColorBar", "BG", m_bgcolor);
set_config_int("ColorBar", "Columns", m_columns);
set_config_int("ColorBar", "EntrySize", m_entrySize);
set_config_color("ColorBar", "FG", getFgColor());
set_config_color("ColorBar", "BG", getBgColor());
}
void ColorBar::setImgType(int imgtype)
{
m_fgColor.setImgType(imgtype);
m_bgColor.setImgType(imgtype);
}
Color ColorBar::getFgColor()
{
return m_fgColor.getColor();
}
Color ColorBar::getBgColor()
{
return m_bgColor.getColor();
}
void ColorBar::setFgColor(const Color& color)
{
m_fgcolor = color;
invalidate();
updateStatusBar(m_fgcolor, 100);
FgColorChange(m_fgcolor);
m_fgColor.setColor(color);
FgColorChange(color);
}
void ColorBar::setBgColor(const Color& color)
{
m_bgcolor = color;
invalidate();
updateStatusBar(m_bgcolor, 100);
BgColorChange(m_bgcolor);
m_bgColor.setColor(color);
BgColorChange(color);
}
Color ColorBar::getColorByPosition(int x, int y)
PaletteView* ColorBar::getPaletteView()
{
for (int i=0; i<getEntriesCount(); ++i) {
if (getEntryBounds(i).contains(Point(x, y)))
return getEntryColor(i);
}
// In foreground color
if (getFgBounds().contains(Point(x, y)))
return m_fgcolor;
// In background color
if (getBgBounds().contains(Point(x, y)))
return m_bgcolor;
return Color::fromMask();
return &m_paletteView;
}
bool ColorBar::onProcessMessage(JMessage msg)
// Switches the palette-editor
void ColorBar::onPaletteButtonClick()
{
switch (msg->type) {
Command* cmd_show_palette_editor = CommandsModule::instance()->getCommandByName(CommandId::PaletteEditor);
Params params;
params.set("switch", "true");
case JM_REQSIZE:
if (get_config_bool("ColorBar", "CanGrow", false))
msg->reqsize.w = 20*jguiscale() * m_columns;
else
msg->reqsize.w = 20*jguiscale() * MIN(2, m_columns);
msg->reqsize.h = 20*jguiscale();
return true;
case JM_DRAW: {
// Update the number of colors per column
{
m_colorsPerColumn = getColumnBounds(1).h / (m_entrySize*jguiscale());
m_colorsPerColumn = MAX(1, m_colorsPerColumn);
if (m_colorsPerColumn*m_columns > 256) {
m_colorsPerColumn = 256 / m_columns;
if (m_colorsPerColumn*m_columns > 256)
m_colorsPerColumn--;
}
ASSERT(m_colorsPerColumn*m_columns <= 256);
}
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
BITMAP *doublebuffer = create_bitmap(jrect_w(&msg->draw.rect),
jrect_h(&msg->draw.rect));
int imgtype = app_get_current_image_type();
// int bg = theme->get_panel_face_color();
int bg = theme->get_tab_selected_face_color();
clear_to_color(doublebuffer, bg);
for (int i=0; i<getEntriesCount(); ++i) {
Rect entryBounds = getEntryBounds(i);
// The button is not even visible
if (!entryBounds.intersects(Rect(msg->draw.rect.x1,
msg->draw.rect.y1,
jrect_w(&msg->draw.rect),
jrect_h(&msg->draw.rect))))
continue;
entryBounds.offset(-msg->draw.rect.x1,
-msg->draw.rect.y1);
int col = (i / m_colorsPerColumn);
int row = (i % m_colorsPerColumn);
Color color = Color::fromIndex(m_firstIndex + i);
draw_color_button(doublebuffer, entryBounds,
row == 0 && col == 0, // nw
row == 0, // n
row == 0 && col == m_columns-1, // ne
col == m_columns-1, // e
row == m_colorsPerColumn-1 && col == m_columns-1, // se
row == m_colorsPerColumn-1, // s
row == m_colorsPerColumn-1 && col == 0, // sw
col == 0, // w
imgtype,
color,
(i == m_hot ||
i == m_hot_editing),
(m_hot_drag == i &&
m_hot_drag != m_hot_drop));
if (m_bgcolor == color) {
theme->draw_bounds_nw(doublebuffer,
entryBounds.x, entryBounds.y,
entryBounds.x+entryBounds.w-1,
entryBounds.y+entryBounds.h-1 - (row == m_colorsPerColumn-1 ? jguiscale(): 0),
PART_COLORBAR_BORDER_BG_NW, -1);
}
if (m_fgcolor == color) {
theme->draw_bounds_nw(doublebuffer,
entryBounds.x, entryBounds.y,
entryBounds.x+entryBounds.w-1,
entryBounds.y+entryBounds.h-1 - (row == m_colorsPerColumn-1 ? jguiscale(): 0),
PART_COLORBAR_BORDER_FG_NW, -1);
}
}
// Draw foreground color
Rect fgBounds = getFgBounds().offset(-msg->draw.rect.x1,
-msg->draw.rect.y1);
draw_color_button(doublebuffer, fgBounds,
true, true, true, true,
false, false, false, true,
imgtype, m_fgcolor,
(m_hot == HOTCOLOR_FGCOLOR ||
m_hot_editing == HOTCOLOR_FGCOLOR),
(m_hot_drag == HOTCOLOR_FGCOLOR &&
m_hot_drag != m_hot_drop));
// Draw background color
Rect bgBounds = getBgBounds().offset(-msg->draw.rect.x1,
-msg->draw.rect.y1);
draw_color_button(doublebuffer, bgBounds,
false, false, false, true,
true, true, true, true,
imgtype, m_bgcolor,
(m_hot == HOTCOLOR_BGCOLOR ||
m_hot_editing == HOTCOLOR_BGCOLOR),
(m_hot_drag == HOTCOLOR_BGCOLOR &&
m_hot_drag != m_hot_drop));
blit(doublebuffer, ji_screen, 0, 0,
msg->draw.rect.x1,
msg->draw.rect.y1,
doublebuffer->w,
doublebuffer->h);
destroy_bitmap(doublebuffer);
return true;
}
case JM_BUTTONPRESSED:
captureMouse();
m_hot_drag = m_hot;
m_hot_drop = m_hot;
case JM_MOUSEENTER:
case JM_MOTION: {
int old_hot = m_hot;
int hot_v1 = 0;
int hot_v2 = 0;
m_hot = HOTCOLOR_NONE;
for (int i=0; i<getEntriesCount(); ++i) {
Rect entryBounds = getEntryBounds(i);
if (entryBounds.contains(Point(msg->mouse.x, msg->mouse.y))) {
if (m_hot != i) {
m_hot = static_cast<hotcolor_t>(i);
hot_v1 = entryBounds.y;
hot_v2 = entryBounds.y+entryBounds.h-1;
break;
}
}
}
Rect fgBounds = getFgBounds();
if (fgBounds.contains(Point(msg->mouse.x, msg->mouse.y))) {
m_hot = HOTCOLOR_FGCOLOR;
hot_v1 = fgBounds.y;
hot_v2 = fgBounds.y+fgBounds.h-1;
}
Rect bgBounds = getBgBounds();
if (bgBounds.contains(Point(msg->mouse.x, msg->mouse.y))) {
m_hot = HOTCOLOR_BGCOLOR;
hot_v1 = bgBounds.y;
hot_v2 = bgBounds.y+bgBounds.h-1;
}
// Drop target
if (m_hot_drag != HOTCOLOR_NONE)
m_hot_drop = m_hot;
// Redraw 'hot' color
if (m_hot != old_hot) {
invalidate();
// Open the new hot-color to be edited
if ((m_hot != HOTCOLOR_NONE) &&
(m_hot_drag == m_hot_drop)) {
Color color = getHotColor(m_hot);
updateStatusBar(color, 0);
}
}
return true;
}
case JM_MOUSELEAVE:
if (m_hot != HOTCOLOR_NONE) {
m_hot = HOTCOLOR_NONE;
invalidate();
}
app_get_statusbar()->clearText();
break;
case JM_WHEEL:
{
int delta = jmouse_z(1) - jmouse_z(0);
// Without Ctrl or Alt
if (!(msg->any.shifts & (KB_ALT_FLAG |
KB_CTRL_FLAG))) {
if (msg->any.shifts & KB_SHIFT_FLAG)
delta *= m_colorsPerColumn;
if (((int)m_firstIndex)+delta < 0)
m_firstIndex = 0;
else if (((int)m_firstIndex)+delta > 256-getEntriesCount())
m_firstIndex = 256-getEntriesCount();
else
m_firstIndex += delta;
}
// With Ctrl only
if ((msg->any.shifts & (KB_ALT_FLAG |
KB_CTRL_FLAG |
KB_SHIFT_FLAG)) == KB_CTRL_FLAG) {
int newColorsPerColumn = m_colorsPerColumn;
while (m_entrySize >= ENTRYSIZE_MIN &&
m_entrySize <= ENTRYSIZE_MAX &&
newColorsPerColumn == m_colorsPerColumn) {
// Increment or decrement m_entrySize until m_colorsPerColumnn changes
m_entrySize += delta;
newColorsPerColumn = getColumnBounds(1).h / (m_entrySize*jguiscale());
}
// Limit "m_entrySize" value
m_entrySize = MID(ENTRYSIZE_MIN, m_entrySize, ENTRYSIZE_MAX);
}
// With Alt only
if ((msg->any.shifts & (KB_ALT_FLAG |
KB_CTRL_FLAG |
KB_SHIFT_FLAG)) == KB_ALT_FLAG) {
int old_columns = m_columns;
if (m_columns+delta < 1)
m_columns = 1;
else if (m_columns+delta > 4)
m_columns = 4;
else
m_columns += delta;
if (get_config_bool("ColorBar", "CanGrow", false) ||
(old_columns == 1 || m_columns == 1)) {
app_get_top_window()->remap_window();
app_get_top_window()->invalidate();
}
}
// Redraw the whole widget
invalidate();
// Update the status bar
updateStatusBar(getColorByPosition(jmouse_x(0), jmouse_y(0)), 0);
}
break;
case JM_BUTTONRELEASED:
if (hasCapture()) {
/* drag and drop a color */
if (m_hot_drag != m_hot_drop) {
if (m_hot_drop != HOTCOLOR_NONE) {
Color color = getHotColor(m_hot_drag);
setHotColor(m_hot_drop, color);
}
invalidate();
}
/* pick the color */
else if (m_hot != HOTCOLOR_NONE) {
Color color = getHotColor(m_hot);
// Check if the color is invalid (e.g. index out of range)
if (color.isValid()) {
switch (m_hot) {
case HOTCOLOR_FGCOLOR:
case HOTCOLOR_BGCOLOR: {
Command* paledit_cmd = CommandsModule::instance()->getCommandByName(CommandId::PaletteEditor);
Params params;
params.set("target", (m_hot == HOTCOLOR_FGCOLOR ? "foreground": "background"));
params.set("open", "true");
UIContext::instance()->executeCommand(paledit_cmd, &params);
break;
}
default: {
Color color = getHotColor(m_hot);
if (msg->mouse.left) {
this->setFgColor(color);
}
if (msg->mouse.right) {
this->setBgColor(color);
}
break;
}
}
}
}
m_hot_drag = HOTCOLOR_NONE;
m_hot_drop = HOTCOLOR_NONE;
releaseMouse();
}
break;
case JM_SETCURSOR:
if (m_hot_drag != HOTCOLOR_NONE &&
m_hot_drag != m_hot_drop) {
jmouse_set_cursor(JI_CURSOR_MOVE);
return true;
}
else if (m_hot >= 0) {
jmouse_set_cursor(JI_CURSOR_EYEDROPPER);
return true;
}
break;
}
return Widget::onProcessMessage(msg);
UIContext::instance()->executeCommand(cmd_show_palette_editor, &params);
}
Color ColorBar::getHotColor(hotcolor_t hot)
void ColorBar::onPaletteIndexChange(int index)
{
switch (hot) {
case HOTCOLOR_NONE: return Color::fromMask();
case HOTCOLOR_FGCOLOR: return m_fgcolor;
case HOTCOLOR_BGCOLOR: return m_bgcolor;
default:
ASSERT(hot >= 0 && hot < getEntriesCount());
return getEntryColor(hot);
}
}
void ColorBar::setHotColor(hotcolor_t hot, const Color& color)
{
switch (hot) {
case HOTCOLOR_NONE:
ASSERT(false);
break;
case HOTCOLOR_FGCOLOR:
setFgColor(color);
break;
case HOTCOLOR_BGCOLOR:
setBgColor(color);
break;
default:
ASSERT(hot >= 0 && hot < getEntriesCount());
#if 0
m_color[hot] = color;
if (hot == 0 || hot == m_ncolor-1) {
color_t c1 = m_color[0];
color_t c2 = m_color[m_ncolor-1];
int r1 = c1.getRed();
int g1 = c1.getGreen();
int b1 = c1.getBlue();
int r2 = c2.getRed();
int g2 = c2.getGreen();
int b2 = c2.getBlue();
int c, r, g, b;
for (c=1; c<m_ncolor-1; ++c) {
r = r1 + (r2-r1) * c / m_ncolor;
g = g1 + (g2-g1) * c / m_ncolor;
b = b1 + (b2-b1) * c / m_ncolor;
m_color[c] = Color::fromRgb(r, g, b);
}
}
#endif
break;
}
}
Rect ColorBar::getColumnBounds(int column) const
{
Rect rc = getBounds().shrink(jguiscale());
Rect fgRc = getFgBounds();
rc.w /= m_columns;
rc.x += (rc.w * column);
rc.h = (fgRc.y - rc.y);
return rc;
}
Rect ColorBar::getEntryBounds(int index) const
{
int row = (index % m_colorsPerColumn);
int col = (index / m_colorsPerColumn);
Rect rc = getColumnBounds(col);
rc.h -= 2*jguiscale();
rc.y += row * rc.h / m_colorsPerColumn;
rc.h = ((row+1) * rc.h / m_colorsPerColumn) - (row * rc.h / m_colorsPerColumn);
if (row == m_colorsPerColumn-1)
rc.h += 2*jguiscale();
return rc;
}
Rect ColorBar::getFgBounds() const
{
Rect rc = getBounds().shrink(jguiscale());
return Rect(rc.x, rc.y+rc.h-BGBUTTON_SIZE-FGBUTTON_SIZE,
rc.w, FGBUTTON_SIZE);
}
Rect ColorBar::getBgBounds() const
{
Rect rc = getBounds().shrink(jguiscale());
return Rect(rc.x, rc.y+rc.h-BGBUTTON_SIZE,
rc.w, BGBUTTON_SIZE);
}
void ColorBar::updateStatusBar(const Color& color, int msecs)
{
if (color.isValid()) {
app_get_statusbar()
->showColor(msecs, "", color, 255);
}
else {
app_get_statusbar()
->clearText();
Color color = Color::fromIndex(index);
if (jmouse_b(0) & 2) // TODO create a PaletteChangeEvent and take left/right mouse button from there
setBgColor(color);
else
setFgColor(color);
}
void ColorBar::onFgColorButtonChange(const Color& color)
{
FgColorChange(color);
onColorButtonChange(color);
}
void ColorBar::onBgColorButtonChange(const Color& color)
{
BgColorChange(color);
onColorButtonChange(color);
}
void ColorBar::onColorButtonChange(const Color& color)
{
if (color.getType() == Color::IndexType) {
int index = color.getIndex();
// Change palette editor color only if it is not the selected entry
if (m_paletteView.get2ndColor() != index)
m_paletteView.selectColor(index);
}
}

View File

@ -21,66 +21,55 @@
#include "app/color.h"
#include "base/signal.h"
#include "gui/widget.h"
#include "gui/box.h"
#include "gui/button.h"
#include "gui/view.h"
#include "widgets/color_button.h"
#include "widgets/palette_view.h"
class ColorBar : public Widget
class PaletteView;
class ColorButton;
class ColorBar : public Box
{
typedef enum {
HOTCOLOR_NONE = -3,
HOTCOLOR_FGCOLOR = -2,
HOTCOLOR_BGCOLOR = -1,
} hotcolor_t;
public:
ColorBar(int align);
~ColorBar();
Color getFgColor() const { return m_fgcolor; }
Color getBgColor() const { return m_bgcolor; }
void setImgType(int imgtype);
Color getFgColor();
Color getBgColor();
void setFgColor(const Color& color);
void setBgColor(const Color& color);
Color getColorByPosition(int x, int y);
PaletteView* getPaletteView();
// Signals
Signal1<void, const Color&> FgColorChange;
Signal1<void, const Color&> BgColorChange;
protected:
bool onProcessMessage(JMessage msg);
void onPaletteButtonClick();
void onPaletteIndexChange(int index);
void onFgColorButtonChange(const Color& color);
void onBgColorButtonChange(const Color& color);
void onColorButtonChange(const Color& color);
private:
int getEntriesCount() const {
return m_columns*m_colorsPerColumn;
}
Color getEntryColor(int i) const {
return Color::fromIndex(i+m_firstIndex);
}
Color getHotColor(hotcolor_t hot);
void setHotColor(hotcolor_t hot, const Color& color);
gfx::Rect getColumnBounds(int column) const;
gfx::Rect getEntryBounds(int index) const;
gfx::Rect getFgBounds() const;
gfx::Rect getBgBounds() const;
void updateStatusBar(const Color& color, int msecs);
int m_firstIndex;
int m_columns;
int m_colorsPerColumn;
int m_entrySize;
Color m_fgcolor;
Color m_bgcolor;
hotcolor_t m_hot;
hotcolor_t m_hot_editing;
// Drag & drop colors
hotcolor_t m_hot_drag;
hotcolor_t m_hot_drop;
class ScrollableView : public View
{
public:
ScrollableView();
protected:
bool onProcessMessage(JMessage msg);
};
Button m_paletteButton;
ScrollableView m_scrollableView;
PaletteView m_paletteView;
ColorButton m_fgColor;
ColorButton m_bgColor;
};
int colorbar_type();
#endif

View File

@ -20,6 +20,7 @@
#include <allegro.h>
#include "app.h"
#include "app/color.h"
#include "app/color_utils.h"
#include "gui/gui.h"
@ -31,6 +32,7 @@
#include "widgets/color_button.h"
#include "widgets/color_selector.h"
#include "widgets/editor.h"
#include "widgets/statebar.h"
static bool tooltip_window_msg_proc(JWidget widget, JMessage msg);
@ -62,6 +64,12 @@ int ColorButton::getImgType() const
return m_imgtype;
}
void ColorButton::setImgType(int imgtype)
{
m_imgtype = imgtype;
invalidate();
}
Color ColorButton::getColor() const
{
return m_color;
@ -81,6 +89,14 @@ bool ColorButton::onProcessMessage(JMessage msg)
{
switch (msg->type) {
case JM_MOUSEENTER:
app_get_statusbar()->showColor(0, "", m_color, 255);
break;
case JM_MOUSELEAVE:
app_get_statusbar()->clearText();
break;
case JM_SIGNAL:
if (msg->signal.num == JI_SIGNAL_BUTTON_SELECT) {
// If the popup window was not created or shown yet..
@ -108,8 +124,8 @@ bool ColorButton::onProcessMessage(JMessage msg)
color = pickedColBut->getColor();
}
// Pick a color from the color-bar
else if (picked->type == colorbar_type()) {
color = ((ColorBar*)picked)->getColorByPosition(msg->mouse.x, msg->mouse.y);
else if (picked->type == palette_view_type()) {
color = ((PaletteView*)picked)->getColorByPosition(msg->mouse.x, msg->mouse.y);
}
// Pick a color from a editor
else if (picked->type == editor_type()) {
@ -194,9 +210,10 @@ void ColorButton::onPaint(PaintEvent& ev) // TODO use "ev.getGraphics()"
setTextQuiet(str.c_str());
jwidget_get_texticon_info(this, &box, &text, &icon, 0, 0, 0);
int textcolor = color_utils::blackandwhite_neg(color.getRed(),
color.getGreen(),
color.getBlue());
int textcolor = makecol(255, 255, 255);
if (color.isValid())
textcolor = color_utils::blackandwhite_neg(color.getRed(), color.getGreen(), color.getBlue());
jdraw_text(ji_screen, getFont(), getText(), text.x1, text.y1,
textcolor, -1, false, jguiscale());
}

View File

@ -32,12 +32,13 @@ public:
~ColorButton();
int getImgType() const;
void setImgType(int imgtype);
Color getColor() const;
void setColor(const Color& color);
// Signals
Signal1<void, Color> Change;
Signal1<void, const Color&> Change;
protected:
// Events

View File

@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include "app.h"
#include "app/color.h"
#include "gfx/point.h"
#include "gui/manager.h"
@ -37,8 +38,9 @@
#include "raster/image.h"
#include "raster/palette.h"
#include "widgets/palette_view.h"
#include "widgets/statebar.h"
static int palette_view_type()
int palette_view_type()
{
static int type = 0;
if (!type)
@ -325,6 +327,44 @@ void PaletteView::getSelectedEntries(bool array[256])
}
}
Color PaletteView::getColorByPosition(int target_x, int target_y)
{
Palette* palette = get_current_palette();
JRect cpos = jwidget_get_child_rect(this);
div_t d = div(256, m_columns);
int cols = m_columns;
int rows = d.quot + ((d.rem)? 1: 0);
int req_w, req_h;
int x, y, u, v;
int c;
request_size(&req_w, &req_h);
y = cpos->y1;
c = 0;
for (v=0; v<rows; v++) {
x = cpos->x1;
for (u=0; u<cols; u++) {
if (c >= palette->size())
break;
if ((target_x >= x) && (target_x <= x+m_boxsize) &&
(target_y >= y) && (target_y <= y+m_boxsize))
return Color::fromIndex(c);
x += m_boxsize+this->child_spacing;
c++;
}
y += m_boxsize+this->child_spacing;
}
jrect_free(cpos);
return Color::fromMask();
}
bool PaletteView::onProcessMessage(JMessage msg)
{
switch (msg->type) {
@ -491,66 +531,44 @@ bool PaletteView::onProcessMessage(JMessage msg)
captureMouse();
/* continue... */
case JM_MOTION:
if (hasCapture()) {
JRect cpos = jwidget_get_child_rect(this);
div_t d = div(256, m_columns);
int cols = m_columns;
int rows = d.quot + ((d.rem)? 1: 0);
int mouse_x, mouse_y;
int req_w, req_h;
int x, y, u, v;
int c;
Palette* palette = get_current_palette();
case JM_MOTION: {
JRect cpos = jwidget_get_child_rect(this);
request_size(&req_w, &req_h);
int req_w, req_h;
request_size(&req_w, &req_h);
mouse_x = MID(cpos->x1, msg->mouse.x,
cpos->x1+req_w-this->border_width.r-1);
mouse_y = MID(cpos->y1, msg->mouse.y,
cpos->y1+req_h-this->border_width.b-1);
int mouse_x = MID(cpos->x1, msg->mouse.x, cpos->x1+req_w-this->border_width.r-1);
int mouse_y = MID(cpos->y1, msg->mouse.y, cpos->y1+req_h-this->border_width.b-1);
y = cpos->y1;
c = 0;
jrect_free(cpos);
for (v=0; v<rows; v++) {
x = cpos->x1;
Color color = getColorByPosition(mouse_x, mouse_y);
if (color.getType() == Color::IndexType) {
app_get_statusbar()->showColor(0, "", color, 255);
for (u=0; u<cols; u++) {
if (c >= palette->size())
break;
if (hasCapture() && color.getIndex() != m_color[1]) {
int idx = color.getIndex();
if ((mouse_x >= x) && (mouse_x <= x+m_boxsize) &&
(mouse_y >= y) && (mouse_y <= y+m_boxsize) &&
(c != m_color[1])) {
if (msg->any.shifts & KB_SHIFT_FLAG)
selectRange(m_color[0], c, PALETTE_EDITOR_RANGE_LINEAL);
else if (msg->any.shifts & KB_CTRL_FLAG)
selectRange(m_color[0], c, PALETTE_EDITOR_RANGE_RECTANGULAR);
else
selectColor(c);
if (msg->any.shifts & KB_SHIFT_FLAG)
selectRange(m_color[0], idx, PALETTE_EDITOR_RANGE_LINEAL);
else if (msg->any.shifts & KB_CTRL_FLAG)
selectRange(m_color[0], idx, PALETTE_EDITOR_RANGE_RECTANGULAR);
else
selectColor(idx);
update_scroll(c);
update_scroll(idx);
// Emit signals
jwidget_emit_signal(this, SIGNAL_PALETTE_EDITOR_CHANGE);
IndexChange(c);
c = 256;
break;
}
x += m_boxsize+this->child_spacing;
c++;
}
y += m_boxsize+this->child_spacing;
// Emit signals
jwidget_emit_signal(this, SIGNAL_PALETTE_EDITOR_CHANGE);
IndexChange(idx);
}
jrect_free(cpos);
return true;
}
if (hasCapture())
return true;
break;
}
case JM_BUTTONRELEASED:
releaseMouse();
@ -566,6 +584,10 @@ bool PaletteView::onProcessMessage(JMessage msg)
break;
}
case JM_MOUSELEAVE:
app_get_statusbar()->clearText();
break;
}
return Widget::onProcessMessage(msg);

View File

@ -53,6 +53,8 @@ public:
int get2ndColor();
void getSelectedEntries(bool array[256]);
Color getColorByPosition(int x, int y);
// Signals
Signal1<void, int> IndexChange;
@ -70,4 +72,6 @@ private:
int m_color[2];
};
int palette_view_type();
#endif