Commit 9ecc8993 authored by ROOL's avatar ROOL 🤖

Colour handling enhancements

Detail:
  * Artist friendly colour ordering of 256 colour palette, and option to reorder pixel data for the remapped palette
  * Full 256 colour sprites can be created (as well as 64/16 entry VIDC compatible ones)
  * Colour indicator swatch in the bottom left corner of the sprite window
  * Adjust click on colours to paint with background colour
  * Shift-select as a shortcut to Paint > Select colour
  * Shift-adjust ditto for background colour
Admin:
  Submission for the Paint bounty.
parent eff0967c
......@@ -83,15 +83,14 @@ DFILES = \
debug.${APP}.Sprites\
debug.${APP}.Templates
OBJS = o.colours o.main o.menus o.psprite o.sprwindow o.tools o.toolwindow \
OBJS = o.colourpanel o.colours o.main o.menus o.psprite o.sprwindow o.tools o.toolwindow \
o.AltRename o.PaintLib o.CnPDrag o.Clipboard o.Drawfile
OBJSZ = oz.colours oz.main oz.menus oz.psprite oz.sprwindow\
OBJSZ = oz.colourpanel oz.colours oz.main oz.menus oz.psprite oz.sprwindow\
oz.tools oz.toolwindow oz.AltRename oz.PaintLib oz.CnPDrag oz.Clipboard oz.Drawfile
OBJSD = od.colours od.ftrace od.guard od.main od.menus\
OBJSD = od.colourpanel od.colours od.ftrace od.guard od.main od.menus\
od.psprite od.sprwindow od.tools od.toolwindow o.m\
od.AltRename od.PaintLib od.CnPDrag od.Clipboard od.Drawfile
ASMS = s.colours s.main s.menus s.psprite s.sprwindow s.tools s.toolwindow
INCS = i.colours i.main i.menus i.psprite i.sprwindow i.tools i.toolwindow
ASMS = s.colourpanel s.colours s.main s.menus s.psprite s.sprwindow s.tools s.toolwindow
#
# Rule patterns
......
No preview for this file type
......@@ -56,7 +56,7 @@ static void altrename_renamesprite (main_sprite *sprite, char *newname)
/* rename must reset the titles of all the windows open on
the sprite */
if (sprite->colourdialogue != NULL)
{ char new_title [80];
{ char new_title [128];
colourpicker_dialogue dialogue;
dialogue.title = new_title;
......@@ -88,6 +88,17 @@ static void altrename_renamesprite (main_sprite *sprite, char *newname)
redraw_str.box.y0 = wstate.o.box.y1;
wimpt_noerr (wimp_force_redraw (&redraw_str));
}
if (sprite->bgcolourdialogue != NULL)
{ char new_title [128];
colourpicker_dialogue dialogue;
dialogue.title = new_title;
sprintf (new_title, msgs_lookup ("PntWF"), newname);
ftracef0 ("ColourPicker_UpdateDialogue: setting new bgcolour title");
wimpt_complain (os_swix3 (ColourPicker_UpdateDialogue,
colourpicker_UPDATE_TITLE, sprite->bgcolourdialogue,
&dialogue));
}
}
void altrename_delete (void)
......
/* Copyright 2019 RISC OS Open Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <swis.h>
#include "bbc.h"
#include "werr.h"
#include "wimpt.h"
#include "ftrace.h"
#include "m.h"
#include "main.h"
#include "PSprite.h"
#include "SprWindow.h"
#include "ToolWindow.h"
#include "Colours.h"
#include "ColourPanel.h"
/**************************************************************************
* *
* Static variables. *
* *
**************************************************************************/
main_template colourpanel_template;
/*******************************************************************
* *
* Get height of the horizontal scroll bar for given window *
* *
*******************************************************************/
int get_horizontal_scrollbar_height (wimp_w wind)
{ int height;
int win_info [25];
os_error *error;
ftracef0 ("get_horizontal_scrollbar_height\n");
win_info [0] = (int)wind;
win_info [2] = 0xBADBAD;
error = os_swix2 (Wimp_Extend, 11, win_info);
if (error)
{ ftracef1 ("Error getting height: %s. No nested WIMP?\n", error->errmess);
return 0;
}
height = win_info [2]; /* It is 40 at 1024x768 on RISC OS 5 */
ftracef1 ("hor. scrollbar height: %d\n", height);
if (height == 0xBADBAD)
{ ftracef0 ("No height returned. No nested WIMP?\n");
return 0;
}
if (height < 6 || height > 600)
{ ftracef0 ("Invalid height returned. No nested WIMP?\n");
return 0;
}
return height;
}
/*******************************************************************
* *
* Get total width of horizontal arrow buttons for given window *
* *
*******************************************************************/
int get_horizontal_arrows_width (wimp_w wind)
{ int l_arrow_width, r_arrow_width;
int total;
int win_info [25];
os_error *error;
ftracef0 ("get_horizontal_arrows_width\n");
win_info [0] = (int)wind;
win_info [23] = win_info [21] = 0xBADBAD;
error = os_swix2 (Wimp_Extend, 11, win_info);
if (error)
{ ftracef1 ("Error getting widths: %s. No nested WIMP?\n", error->errmess);
return 0;
}
l_arrow_width = win_info [23]; /* It is 80 at 1024 x 768 on RISC OS 5 */
r_arrow_width = win_info [21];
ftracef2 ("left arrow width: %d right arrow width: %d.\n", l_arrow_width, r_arrow_width);
total = l_arrow_width + r_arrow_width;
if (l_arrow_width == 0xBADBAD || r_arrow_width == 0xBADBAD)
{ ftracef0 ("No width returned. No nested WIMP?\n");
return 0;
}
if (total < 12 || total > 1200)
{ ftracef0 ("Invalid height returned. No nested WIMP?\n");
return 0;
}
return total;
}
/*************************************************************************
* *
* Initiates a redraw for all colour panels on all windows of the sprite *
* *
*************************************************************************/
void colourpanel_redraw (main_window *window)
{ main_sprite_window *sprite_window;
ftracef0 ("colourpanel_redraw\n");
if (window == NULL)
return;
sprite_window = &window->data->sprite;
if (sprite_window == NULL || sprite_window->sprite == NULL)
return;
sprite_window = sprite_window->sprite->windows;
while (sprite_window != NULL)
{
colour_panel *colpanel = sprite_window->colourpanel;
wimp_wstate currinfo;
wimp_redrawstr r;
if (colpanel != NULL)
{ wimpt_noerr (wimp_get_wind_state (colpanel->handle, &currinfo));
r.w = -1;
r.box = currinfo.o.box;
ftracef1("Redrawing colourpanel with handle: %d.\n", colpanel->handle);
ftracef1("Colours window handle is: %d\n", sprite_window->sprite->colourhandle);
wimp_force_redraw (&r);
}
sprite_window = sprite_window->link;
}
}
/***********************************************************************
* *
* Drag processor to swap colours on the colour panel *
* *
***********************************************************************/
static BOOL colourpanel_drag_processor (wimp_eventstr *event, void *handle)
{ wimp_wstate ws;
main_window *window = (main_window *)handle;
main_sprite *sprite = window->data->sprite.sprite;
colour_panel *colpanel = window->data->sprite.colourpanel;
if (event->e != wimp_EUSERDRAG)
return FALSE;
ftracef0("colourpanel_drag_processor\n");
win_remove_unknown_event_processor (colourpanel_drag_processor, handle);
if (colpanel == NULL)
{ ftracef0 ("Error: sprite.colourpanel NULL in drag processor.\n");
return TRUE;
}
wimp_get_wind_state (window->handle, &ws);
ftracef0("Colour panel user drag event received.\n");
wimp_redrawstr r;
int centrex, mx, my;
int x_eig, y_eig, max_eig;
int colpanelwidth, colpanelheight, bgndwidth, bgndheight, coloursize;
int colourxoffset, colouryoffset;
wimp_mousestr mouse;
wimpt_noerr (wimp_get_point_info (&mouse));
mx = mouse.x;
my = mouse.y;
wimp_get_wind_state (window->handle, &ws);
x_eig = bbc_vduvar (bbc_XEigFactor);
y_eig = bbc_vduvar (bbc_YEigFactor);
if (x_eig > y_eig) max_eig = x_eig; else max_eig = y_eig;
colpanelheight = colpanel->size;
bgndheight = colpanelheight - (2 << y_eig);
coloursize = bgndheight - (2 << y_eig);
colourxoffset = 2 << x_eig;
colouryoffset = 1 << y_eig;
/*Round DOWN to nearest whole number of pixels*/
coloursize = (coloursize >> max_eig) << max_eig;
colpanelwidth = coloursize * 2 + (4 << x_eig );
/*Background excludes 1 pixel border*/
bgndwidth = colpanelwidth - (1 << x_eig);
/* Work out which colour icon the mouse is over. */
/* At the start of the drag, we want to centre the dragbox */
/* around that icon. */
centrex = ws.o.box.x0 - ws.o.x + colpanelwidth / 2;
ftracef4("ws.o.box.y1: %d ws.o.y: %d colouryoffset: %d my: %d\n", ws.o.box.y1, ws.o.y, colouryoffset, my);
if (mx < centrex && colpanel->state == 1 ||
mx > centrex && colpanel->state == 0)
{ ftracef3("Swapping colours. mx: %d centrex: %d state: %d\n", mx, centrex, colpanel->state);
ftracef4("Colours to swap: gcol.colour: %d gcol.alpha %d gcol2.colour: %d gcol.alpha: %d\n",
sprite->gcol.colour, sprite->gcol.alpha, sprite->gcol2.colour, sprite->gcol2.alpha);
/* Swap the fore and background colours */
unsigned int forecolour = sprite->gcol.colour;
BOOL foreECF = sprite->gcol.ecf;
char foreAlpha = sprite->gcol.alpha;
sprite->gcol.colour = sprite->gcol2.colour;
sprite->gcol.ecf = sprite->gcol2.ecf;
sprite->gcol.alpha = sprite->gcol2.alpha;
sprite->gcol2.colour = forecolour;
sprite->gcol2.ecf = foreECF;
sprite->gcol2.alpha = foreAlpha;
ftracef4("Colours after swap: gcol.colour: %d gcol.alpha %d gcol2.colour: %d gcol.alpha: %d\n", sprite->gcol.colour, sprite->gcol.alpha, sprite->gcol2.colour, sprite->gcol2.alpha);
colourpanel_redraw (window);
if (window->data->sprite.sprite->colourhandle != NULL)
main_force_redraw (window->data->sprite.sprite->colourhandle);
/* Update any foreground / background colourpickers */
main_colour *gcol = &sprite->gcol;
colourpicker_dialogue dialogue;
for (int i = 0; i < 2; i++)
{ if (i == 0 && sprite->colourdialogue == 0)
{ gcol = &sprite->gcol2;
continue;
}
else if (i == 1 && sprite->bgcolourdialogue == 0)
break;
if (!gcol->alpha)
{ dialogue.flags = colourpicker_DIALOGUE_TRANSPARENT;
ftracef0 ("ColourPicker_UpdateDialogue: setting transparent\n");
os_swi3 (ColourPicker_UpdateDialogue,
colourpicker_UPDATE_TRANSPARENT,
(i == 1) ? sprite->bgcolourdialogue : sprite->colourdialogue,
&dialogue);
}
else
{ dialogue.colour = colours_entry (psprite_address(sprite)->mode, gcol->colour);
ftracef1 ("ColourPicker_UpdateDialogue: setting RGB colour to 0x%X\n",
dialogue.colour);
os_swi3 (ColourPicker_UpdateDialogue,
colourpicker_UPDATE_COLOUR,
(i == 1) ? sprite->bgcolourdialogue : sprite->colourdialogue,
&dialogue);
}
gcol = &sprite->gcol2;
}
ftracef4("Colours after swap and picker updates: gcol.colour: %d gcol.alpha %d gcol2.colour: %d gcol.alpha: %d\n",
sprite->gcol.colour, sprite->gcol.alpha, sprite->gcol2.colour, sprite->gcol2.alpha);
}
else
{ ftracef3("NOT swapping colours. mx: %d centrex: %d state: %d\n", mx, centrex, colpanel->state);
}
colpanel->state = 0;
r.w = window->handle;
r.box.y1 = 0;
r.box.y0 = -colpanelheight + 4;
r.box.x0 = 0;
r.box.x1 = colpanelwidth;
wimp_force_redraw (&r);
return TRUE;
}
/***********************************************************************
* *
* Event handler for the colour panel *
* *
***********************************************************************/
void colourpanel_event_handler (wimp_eventstr *e, void *handle)
{ int more;
int x_eig, y_eig, max_eig;
int colpanelwidth, colpanelheight, bgndwidth, bgndheight, coloursize;
int colourxoffset, colouryoffset;
more = 0;
colour_panel *colpanel = (colour_panel *)handle;
main_window *window = colpanel->window;
main_sprite *sprite = window->data->sprite.sprite;
ftracef0 ("colourpanel_event_handler\n");
ftracef4 ("event type: %d &window: %d &data: %d &sprite: %d\n", e->e, (int)window, (int)(window->data), (int)(sprite));
ftracef1 ("Colour panel: %d\n", colpanel);
x_eig = bbc_vduvar (bbc_XEigFactor);
y_eig = bbc_vduvar (bbc_YEigFactor);
if (x_eig > y_eig) max_eig = x_eig; else max_eig = y_eig;
colpanelheight = colpanel->size;
bgndheight = colpanelheight - (2 << y_eig);
coloursize = bgndheight - (2 << y_eig);
colourxoffset = 2 << x_eig;
colouryoffset = 1 << y_eig;
/*Round DOWN to nearest whole number of pixels*/
coloursize = (coloursize >> max_eig) << max_eig;
colpanelwidth = coloursize * 2 + (4 << x_eig );
bgndwidth = colpanelwidth - (1 << x_eig);/* background excludes 1 pixel borders */
ftracef5 ("coloursize: %d colpanelwidth: %d colpanelheight: %d bgndwidth: %d bgndheight: %d\n",
coloursize, colpanelwidth, colpanelheight, bgndwidth, bgndheight);
switch (e->e)
{ case wimp_EREDRAW:
{ ftracef0 ("colour panel redraw event.\n");
int nc, lim, lb_bpp;
BOOL more, mask;
wimp_redrawstr rds;
unsigned char mono_ttab [256];
static const unsigned int mono_palette [] = {0x00000000, 0xFFFFFF00};
mask = psprite_hasmask (sprite);
lim = nc = colours_count (sprite);
if (mask) lim++;
for (more = 0; more < 4; more++)
if (sprite->ECFs [more].sarea != NULL)
lim++;
lb_bpp = bbc_modevar (psprite_address (sprite)->mode, bbc_Log2BPP);
rds.w = e->data.o.w;
wimpt_noerr (wimp_redraw_wind (&rds, &more));
/*Get a mapping from the sprite to black and white.*/
if (psprite_haspal (sprite))
os_swi6 (ColourTrans_GenerateTable, sprite->file->spritearea,
psprite_address (sprite), 0, (int) mono_palette, (int) mono_ttab,
1 << 0 /*R1 is sprite*/);
else
os_swi6 (ColourTrans_GenerateTable, psprite_address (sprite)->mode,
psprite_std_palettes [sprite->file->use_current_palette? 0: 1]
[lb_bpp], 0, (int) mono_palette, (int) mono_ttab, 0);
#ifdef XTRACE
{ int i;
for (i = 0; i < 1 << (1 << lb_bpp); i++)
ftracef2 ("mono_ttab [%d]: %d\n", i, mono_ttab [i]);
}
#endif
while (more)
{ int k, colourx = -coloursize, coloury = 0, xpos, ypos;
/*Is this a wide table?*/
ftracef2 ("got a %d-entry sprite, table size %d\n",
nc, sprite->transtab->ttab_size);
wimp_setcolour ((1<<7)+7);
bbc_clg ();
wimpt_noerr (wimp_setcolour (1));
bbc_rectanglefill (rds.box.x0 - rds.scx + (1 << x_eig),
rds.box.y1 - rds.scy - (1 << y_eig),
bgndwidth - (1 << x_eig),
-bgndheight + (1 << y_eig));
unsigned int forecolour = sprite->gcol.colour;
unsigned int backcolour = sprite->gcol2.colour;
unsigned int foreECF = 0;
unsigned int backECF = 0;
if (sprite->gcol.ecf)
foreECF = sprite->gcol.colour + 1;
else if (!sprite->gcol.alpha)
forecolour = nc; /* Transparent colour */
if (sprite->gcol2.ecf)
backECF = sprite->gcol2.colour + 1;
else if (!sprite->gcol2.alpha)
backcolour = nc; /*Transparent colour */
ftracef4 ("Foreground colour: %d alpha: %d; Background colour: %d alpha: %d\n",
sprite->gcol.colour, sprite->gcol.alpha, sprite->gcol2.colour, sprite->gcol2.alpha);
/* now convert to on_screen coordinates */
for (k = 0; k < 2; k++)
{ int ECF = 0;
int i;
/* Find the selected fore and background colours */
/* selected_colour < nc means a standard colour */
/* if mask, selected_colour == nc means transparent colour, else 1st ECF */
/* if selected_colour > nc, it's an ECF where ECFs are where */
/* sprite->ECFs [<0 to 4>].sarea != NULL */
i = (k) ? backcolour : forecolour;
colourx += coloursize;
xpos = colourx + rds.box.x0 - rds.scx;
ypos = coloury + rds.box.y1 - rds.scy;
ftracef4 ("xpos: %d colourx: %d rds.box.x0: %d rds.scx: %d\n", xpos, colourx, rds.box.x0, rds.scx);
ftracef4 ("ypos: %d coloury: %d rds.box.y1: %d rds.scy: %d\n", ypos, coloury, rds.box.y1, rds.scy);
xpos += colourxoffset;
ypos -= colouryoffset;
if (main_CLIPS (&rds.g, xpos, ypos - coloursize,
xpos + coloursize, ypos))
{ int x, y;
x = xpos;
y = ypos - coloursize;
main_colour gcol = (k) ? sprite->gcol2 : sprite->gcol;
if ((i == nc && mask) || (nc > 256 && gcol.alpha == 0))
psprite_ecf (0);
else
{ if ((k && backECF) || (!k && foreECF))
{ ECF = (k)? backECF : foreECF;
psprite_plot_ecf_sprite_sized (sprite, ECF-1, x, y, colours_SIZE/2);
ftracef2 ("Got ECF %d; gcol %d\n", ECF, sprite->gcol);
}
else
{ if (nc > 256)
{ /*Need to convert the colour to current mode via true colour*/
int col = colours_entry (psprite_address(sprite)->mode, gcol.colour);
sprite_colour col2;
wimpt_noerr(os_swi1r(ColourTrans_ReturnColourNumber, col, &col2));
ftracef1 ("OS_SetColour (0, %d)\n", col2);
os_swix2 (OS_SetColour, 0, col2);
}
else if (sprite->transtab->table != 0)
switch (sprite->transtab->ttab_size/nc)
{ case 1:
#ifdef JRC
colours_set_gcol (sprite->transtab->table [i], 0, 0);
#else
{ unsigned char *t =
(unsigned char *) sprite->transtab->table;
os_swi2 (OS_SetColour, 0, t [i]);
ftracef1 ("Colour set to %d\n", t [i]);
}
#endif
break;
case 2:
{ short *t = (short *) sprite->transtab->table;
os_swi2 (OS_SetColour, 0, t [i]);
ftracef1 ("Colour set to %d\n", t [i]);
}
break;
case 4:
{ int *t = (int *) sprite->transtab->table;
os_swi2 (OS_SetColour, 0, t [i]);
ftracef1 ("Colour set to %d\n", t [i]);
}
break;
}
else
ftracef0 ("Error in colourpanel redraw. Sprite has no translation table!\n");
}
}
if (!ECF) bbc_rectanglefill (x, y, coloursize - (1 << x_eig),
coloursize - (1 << y_eig));
/*If this is the selected colour, border is white, otherwise
black.*/
BOOL selected;
if (ECF)
selected = sprite->gcol.ecf && (sprite->gcol.colour == ECF-1);
else if(i == nc)
selected = !sprite->gcol.ecf && !sprite->gcol.alpha;
else
selected = !sprite->gcol.ecf && sprite->gcol.alpha && (sprite->gcol.colour == i);
wimpt_noerr (wimp_setcolour (7));
bbc_rectangle (x, y, coloursize - (1 << x_eig),
coloursize - (1 << y_eig));
}
colourx += 1 << x_eig;
}
wimpt_noerr (wimp_get_rectangle (&rds, &more));
}
}
break;
case wimp_EBUT:
ftracef0 ("colour panel button event.\n");
if (e->data.but.m.bbits & (wimp_BDRAGLEFT | wimp_BDRAGRIGHT))
{ int centrex, mx, my;
wimp_dragstr drag;
wimp_wstate ws;
mx = e->data.but.m.x;
my = e->data.but.m.y;
wimp_get_wind_state (/*window->handle*/colpanel->handle, &ws);
drag.window = colpanel->handle;//window->handle;
drag.type = wimp_USER_FIXED;
/* Work out which colour icon the mouse is over. */
/* At the start of the drag, we want to centre the dragbox */
/* around that icon. */
centrex = ws.o.box.x0 - ws.o.x + colpanelwidth / 2;
ftracef4("ws.o.box.y1: %d ws.o.y: %d colouryoffset: %d my: %d\n", ws.o.box.y1, ws.o.y, colouryoffset, my);
if (mx == centrex ||
mx < colourxoffset + ws.o.box.x0 - ws.o.x ||
my > (ws.o.box.y1 - ws.o.y - colouryoffset) ||
my < (ws.o.box.y1 - ws.o.y - colouryoffset - coloursize) ||
mx > colourxoffset + ws.o.box.x0 - ws.o.x + coloursize * 2 + (1 << x_eig))
{ ftracef2 ("Drag outside colour panel bounds. coloursize: %d centerx: %d\n", coloursize, centrex);
break;
}
if (mx < centrex)
{ drag.box.x0 = drag.box.x1 = colourxoffset + ws.o.box.x0 - ws.o.x;
colpanel->state = 0;
}
else
{ drag.box.x0 = drag.box.x1 = colourxoffset + ws.o.box.x0 - ws.o.x +
coloursize + (1 << x_eig);
colpanel->state = 1;
}
drag.box.y0 = drag.box.y1 = ws.o.box.y1 - ws.o.y - colouryoffset;
drag.box.x1 += coloursize;
drag.box.y1 -= coloursize;
drag.parent = ws.o.box;
ftracef0("Colour panel drag detected. Initiating colour drag.\n");
os_swix4 (Wimp_DragBox, 0, &drag, *(int *)"TASK", 3);
win_add_unknown_event_processor (colourpanel_drag_processor, window);
}
else if ((e->data.but.m.bbits & wimp_BLEFT) && !window->data->sprite.read_only)
{ int centrex, mx, my;
wimp_wstate ws;
mx = e->data.but.m.x;
my = e->data.but.m.y;
wimp_get_wind_state (/*window->handle*/colpanel->handle, &ws);
/* Work out which colour icon the mouse is over. */
centrex = ws.o.box.x0 - ws.o.x + colpanelwidth / 2;
ftracef4("ws.o.box.y1: %d ws.o.y: %d colouryoffset: %d my: %d\n", ws.o.box.y1, ws.o.y, colouryoffset, my);
if (mx == centrex ||
mx < colourxoffset + ws.o.box.x0 - ws.o.x ||
my > (ws.o.box.y1 - ws.o.y - colouryoffset) ||
my < (ws.o.box.y1 - ws.o.y - colouryoffset - coloursize) ||
mx > colourxoffset + ws.o.box.x0 - ws.o.x + coloursize * 2 + (1 << x_eig))
{ ftracef2 ("Click outside colour panel bounds. coloursize: %d centerx: %d\n", coloursize, centrex);
ftracef4 ("mx: %d colourxoffset: %d box.x0: %d o.x: %d\n", mx, colourxoffset, ws.o.box.x0, ws.o.x);
break;
}
ftracef0 ("Colour panel show colours window\n");
if (mx < centrex)
{ /* Foreground colour */
colours_create_window (sprite, FALSE);
main_current_options.colours.show_colours = TRUE;
}
else
{ /* Background colour */
/* If true colour, we'll make a special colour picker */
int smode = psprite_address (sprite)->mode;
int slb_bpp = bbc_modevar (smode, bbc_Log2BPP);
colours_create_window (sprite, TRUE);
if (slb_bpp <= 3)
{ /* It's the standard Colours window */
main_current_options.colours.show_colours = TRUE;
}
}
}
else if ((e->data.but.m.bbits & wimp_BRIGHT) && !window->data->sprite.read_only)
{ ftracef0 ("Colour show tool menu\n");
toolwindow_display (/*at pointer?*/ FALSE);
main_current_options.tools.show_tools = TRUE;
}
break;
case wimp_ESEND:
case wimp_ESENDWANTACK:
if (e->data.msg.hdr.action == wimp_MHELPREQUEST)
{ wimp_mousestr mouse;
wimp_wstate ws;
int centrex, mx, my;
ftracef0 ("Help request on colour panel\n");
wimp_get_wind_state (/*window->handle*/colpanel->handle, &ws);
/* Work out which colour icon the mouse is over. */
centrex = ws.o.box.x0 - ws.o.x + colpanelwidth / 2;
wimpt_noerr (wimp_get_point_info (&mouse));
mx = mouse.x;
my = mouse.y;
if (mx == centrex ||
mx < colourxoffset + ws.o.box.x0 - ws.o.x ||
my > (ws.o.box.y1 - ws.o.y - colouryoffset) ||
my < (ws.o.box.y1 - ws.o.y - colouryoffset - coloursize) ||
mx > colourxoffset + ws.o.box.x0 - ws.o.x + coloursize * 2 + (1 << x_eig))
break;
if (mx < centrex)
{ /* Foreground colour */
main_help_message ("PntHI", e);
}
else
{ /* Background colour */
main_help_message ("PntHJ", e);
}
}
break;
default:
ftracef1 ("Unhandled colour panel event type: %d\n", e->e);
break;
}
}
/***********************************************************************
* *
* Create a new colour panel with given sprite window *
* *
***********************************************************************/
colour_panel *colourpanel_new (main_sprite_window *sprite_window)
{ main_sprite *sprite = sprite_window->sprite;
main_window *window = sprite_window->window;
colour_panel *colpanel;
wimp_w w = window->handle;
wimp_wstate sprite_w_state;
wimp_redrawstr sprite_redraw_str;
int wimpVersion;
os_error *error;
ftracef0 ("colourpanel_new\n");
/*Create fore/background colour selection panel at bottom of window RO 3.8+*/
wimpt_noerr (os_swix1r (Wimp_ReadSysInfo, 7, &wimpVersion));
if (wimpVersion < 380)
{ ftracef1 (
"Window Manager too old (%d) for nested WIMP. Disabling colour panel.\n",
wimpVersion);
return NULL;
}
if ((colpanel = m_ALLOC (sizeof (colour_panel))) == NULL)
{ main_NO_ROOM ("colour_panel");
return NULL;
}
/*Get the state of the new sprite window*/
wimpt_noerr (wimp_get_wind_state (sprite->windows->window->handle,
&sprite_w_state));
/*And its outline*/
sprite_redraw_str.w = sprite->windows->window->handle;
wimpt_noerr (wimp_getwindowoutline (&sprite_redraw_str));
int linkage = 0x5550000;
wimp_wind colpanel_wind;
wimp_openstr colpanel_open_str;
wimp_w colpanel_w;
int colpanel_height;
int colpanel_width;
int coloursize;
int x_eig, y_eig, max_eig;
x_eig = bbc_vduvar (bbc_XEigFactor);