/* ** colorpickermenu.txt ** The color picker menu ** **--------------------------------------------------------------------------- ** Copyright 2010-2017 Christoph Oelckers ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions ** are met: ** ** 1. Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** 2. Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** 3. The name of the author may not be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **--------------------------------------------------------------------------- ** */ //============================================================================= // // This is only used by the color picker // //============================================================================= class OptionMenuSliderVar : OptionMenuSliderBase { int mIndex; OptionMenuSliderVar Init(String label, int index, double min, double max, double step, int showval) { Super.Init(label, min, max, step, showval); mIndex = index; return self; } override double GetSliderValue() { return ColorpickerMenu(Menu.GetCurrentMenu()).GetColor(mIndex); } override void SetSliderValue(double val) { ColorpickerMenu(Menu.GetCurrentMenu()).setColor(mIndex, val); } } class ColorpickerMenu : OptionMenu { float mRed; float mGreen; float mBlue; int mGridPosX; int mGridPosY; int mStartItem; CVar mCVar; double GetColor(int index) { double v = index == 0? mRed : index == 1? mGreen : mBlue; return v; } void SetColor(int index, double val) { if (index == 0) mRed = val; else if (index == 1) mGreen = val; else mBlue = val; } //============================================================================= // // // //============================================================================= void Init(Menu parent, String name, OptionMenuDescriptor desc, CVar cv) { Super.Init(parent, desc); mStartItem = mDesc.mItems.Size(); mCVar = cv; ResetColor(); mGridPosX = 0; mGridPosY = 0; // This menu uses some features that are hard to implement in an external control lump // so it creates its own list of menu items. mDesc.mItems.Resize(mStartItem+8); mDesc.mItems[mStartItem+0] = new ("OptionMenuItemStaticText").Init(name, false); mDesc.mItems[mStartItem+1] = new ("OptionMenuItemStaticText").Init(" ", false); mDesc.mItems[mStartItem+2] = new ("OptionMenuSliderVar").Init("$TXT_COLOR_RED", 0, 0, 255, 15, 0); mDesc.mItems[mStartItem+3] = new ("OptionMenuSliderVar").Init("$TXT_COLOR_GREEN", 1, 0, 255, 15, 0); mDesc.mItems[mStartItem+4] = new ("OptionMenuSliderVar").Init("$TXT_COLOR_BLUE", 2, 0, 255, 15, 0); mDesc.mItems[mStartItem+5] = new ("OptionMenuItemStaticText").Init(" ", false); mDesc.mItems[mStartItem+6] = new ("OptionMenuItemCommand").Init("$TXT_UNDOCHANGES", "undocolorpic"); mDesc.mItems[mStartItem+7] = new ("OptionMenuItemStaticText").Init(" ", false); mDesc.mSelectedItem = mStartItem + 2; mDesc.mIndent = 0; mDesc.CalcIndent(); } //============================================================================= // // // //============================================================================= override bool MenuEvent (int mkey, bool fromcontroller) { switch (mkey) { case MKEY_Down: if (mDesc.mSelectedItem == mStartItem+6) // last valid item { MenuSound ("menu/cursor"); mGridPosY = 0; // let it point to the last static item so that the super class code still has a valid item mDesc.mSelectedItem = mStartItem+7; return true; } else if (mDesc.mSelectedItem == mStartItem+7) { if (mGridPosY < 15) { MenuSound ("menu/cursor"); mGridPosY++; } return true; } break; case MKEY_Up: if (mDesc.mSelectedItem == mStartItem+7) { if (mGridPosY > 0) { MenuSound ("menu/cursor"); mGridPosY--; } else { MenuSound ("menu/cursor"); mDesc.mSelectedItem = mStartItem+6; } return true; } break; case MKEY_Left: if (mDesc.mSelectedItem == mStartItem+7) { MenuSound ("menu/cursor"); if (--mGridPosX < 0) mGridPosX = 15; return true; } break; case MKEY_Right: if (mDesc.mSelectedItem == mStartItem+7) { MenuSound ("menu/cursor"); if (++mGridPosX > 15) mGridPosX = 0; return true; } break; case MKEY_Enter: if (mDesc.mSelectedItem == mStartItem+7) { // Choose selected palette entry int index = mGridPosX + mGridPosY * 16; color col = Screen.PaletteColor(index); mRed = col.r; mGreen = col.g; mBlue = col.b; MenuSound ("menu/choose"); return true; } break; } if (mDesc.mSelectedItem >= 0 && mDesc.mSelectedItem < mStartItem+7) { if (mDesc.mItems[mDesc.mSelectedItem].MenuEvent(mkey, fromcontroller)) return true; } return Super.MenuEvent(mkey, fromcontroller); } //============================================================================= // // // //============================================================================= override bool MouseEvent(int type, int mx, int my) { int olditem = mDesc.mSelectedItem; bool res = Super.MouseEvent(type, mx, my); if (mDesc.mSelectedItem == -1 || mDesc.mSelectedItem == mStartItem+7) { int y = (-mDesc.mPosition + BigFont.GetHeight() + mDesc.mItems.Size() * linespacing) * CleanYfac_1; int h = (screen.GetHeight() - y) / 16; int fh = linespacing * CleanYfac_1; int w = fh; int yy = y + 2 * CleanYfac_1; int indent = (screen.GetWidth() / 2); if (h > fh) h = fh; else if (h < 4) return res; // no space to draw it. int box_y = y - 2 * CleanYfac_1; int box_x = indent - 16*w; if (mx >= box_x && mx < box_x + 16*w && my >= box_y && my < box_y + 16*h) { int cell_x = (mx - box_x) / w; int cell_y = (my - box_y) / h; if (olditem != mStartItem+7 || cell_x != mGridPosX || cell_y != mGridPosY) { mGridPosX = cell_x; mGridPosY = cell_y; } mDesc.mSelectedItem = mStartItem+7; if (type == MOUSE_Release) { MenuEvent(MKEY_Enter, true); if (m_use_mouse == 2) mDesc.mSelectedItem = -1; } res = true; } } return res; } //============================================================================= // // // //============================================================================= override void Drawer() { Super.Drawer(); if (mCVar == null) return; int y = (-mDesc.mPosition + BigFont.GetHeight() + mDesc.mItems.Size() * linespacing) * CleanYfac_1; int fh = linespacing * CleanYfac_1; int h = (screen.GetHeight() - y) / 16; int w = fh; int yy = y; if (h > fh) h = fh; else if (h < 4) return; // no space to draw it. int indent = (screen.GetWidth() / 2); int p = 0; for(int i = 0; i < 16; i++) { int box_x, box_y; int x1; box_y = y - 2 * CleanYfac_1; box_x = indent - 16*w; for (x1 = 0; x1 < 16; ++x1) { screen.Clear (box_x, box_y, box_x + w, box_y + h, 0, p); if ((mDesc.mSelectedItem == mStartItem+7) && (/*p == CurrColorIndex ||*/ (i == mGridPosY && x1 == mGridPosX))) { int r, g, b; Color col; double blinky; if (i == mGridPosY && x1 == mGridPosX) { r = 255; g = 128; b = 0; } else { r = 200; g = 200; b = 255; } // Make sure the cursors stand out against similar colors // by pulsing them. blinky = abs(sin(MSTimeF()/1000.0)) * 0.5 + 0.5; col = Color(255, int(r*blinky), int(g*blinky), int(b*blinky)); screen.Clear (box_x, box_y, box_x + w, box_y + 1, col); screen.Clear (box_x, box_y + h-1, box_x + w, box_y + h, col); screen.Clear (box_x, box_y, box_x + 1, box_y + h, col); screen.Clear (box_x + w - 1, box_y, box_x + w, box_y + h, col); } box_x += w; p++; } y += h; } y = yy; color newColor = Color(255, int(mRed), int(mGreen), int(mBlue)); color oldColor = mCVar.GetInt() | 0xFF000000; int x = screen.GetWidth()*2/3; screen.Clear (x, y, x + 48*CleanXfac_1, y + 48*CleanYfac_1, oldColor); screen.Clear (x + 48*CleanXfac_1, y, x + 48*2*CleanXfac_1, y + 48*CleanYfac_1, newColor); y += 49*CleanYfac_1; screen.DrawText (SmallFont, Font.CR_GRAY, x+(48-SmallFont.StringWidth("---->")/2)*CleanXfac_1, y, "---->", DTA_CleanNoMove_1, true); } override void OnDestroy() { if (mStartItem >= 0) { mDesc.mItems.Resize(mStartItem); if (mCVar != null) { mCVar.SetInt(Color(int(mRed), int(mGreen), int(mBlue))); } mStartItem = -1; } } override void ResetColor() { if (mCVar != null) { Color clr = Color(mCVar.GetInt()); mRed = clr.r; mGreen = clr.g; mBlue = clr.b; } } }