import "ecere" static define borderSize = (radius * 8 / 20); struct RoundMatch { DisplaySystem displaySystem; int radius; }; static Map roundedBMPs { }; static byte borderData[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x4B, 0x8D, 0xC9, 0xCC, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xAE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x78, 0x36, 0x33, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xB3, 0xFF, 0xFF, 0xFF, 0xF6, 0x8D, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xD4, 0xFF, 0xFF, 0xFF, 0xB1, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xFF, 0xFF, 0xFF, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xFF, 0xFF, 0xFF, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, 0xFF, 0xFF, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xFF, 0xFF, 0xF9, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xFF, 0xFF, 0x8A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0xFF, 0xFF, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0xFF, 0xFF, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xFF, 0xFF, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xFF, 0xFF, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xFF, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static byte insideData[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x87, 0xC9, 0xCC, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x72, 0xEA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x06, 0xE4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x75, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xEA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x93, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xC6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xEA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; class RoundedBMPs { int count; DisplaySystem displaySystem; int radius; Bitmap tl { alphaBlend = true }; Bitmap bl { alphaBlend = true }; Bitmap tr { alphaBlend = true }; Bitmap br { alphaBlend = true }; Bitmap vert { alphaBlend = true }; Bitmap horz { alphaBlend = true }; Bitmap eVert { alphaBlend = true }; Bitmap eHorz { alphaBlend = true }; Bitmap itl { alphaBlend = true }; Bitmap ibl { alphaBlend = true }; Bitmap itr { alphaBlend = true }; Bitmap ibr { alphaBlend = true }; Bitmap ivert { alphaBlend = true }; Bitmap ihorz { alphaBlend = true }; Bitmap ieVert { alphaBlend = true }; Bitmap ieHorz { alphaBlend = true }; bool OnLoadGraphics() { /*tl.Load(":roundedTL.png", null, null); itl.Load(":insideTL.png", null, null); tl.Convert(null, pixelFormatAlpha, null); itl.Convert(null, pixelFormatAlpha, null);*/ tl.Allocate(null, radius, radius, 0, pixelFormatAlpha, false); itl.Allocate(null, radius, radius, 0, pixelFormatAlpha, false); if(radius == 20) { memcpy(tl.picture, borderData, sizeof(borderData)); memcpy(itl.picture, insideData, sizeof(insideData)); } else { Bitmap temp { alphaBlend = true }; Surface surface; temp.Allocate(null, 20, 20, 0, pixelFormatAlpha, false); memcpy(temp.picture, borderData, sizeof(borderData)); surface = tl.GetSurface(0,0, null); surface.blend = false; surface.Filter(temp, 0,0,0,0, radius, radius, 20,20); delete surface; memcpy(temp.picture, insideData, sizeof(insideData)); surface = itl.GetSurface(0,0, null); surface.blend = false; surface.Filter(temp, 0,0,0,0, radius, radius, 20,20); delete surface; delete temp; } bl.Allocate(null, tl.width, tl.height, 0, pixelFormatAlpha, false); tr.Allocate(null, tl.width, tl.height, 0, pixelFormatAlpha, false); br.Allocate(null, tl.width, tl.height, 0, pixelFormatAlpha, false); ibl.Allocate(null, itl.width, itl.height, 0, pixelFormatAlpha, false); itr.Allocate(null, itl.width, itl.height, 0, pixelFormatAlpha, false); ibr.Allocate(null, itl.width, itl.height, 0, pixelFormatAlpha, false); vert.Allocate(null, tl.width, 1, 0, pixelFormatAlpha, false); horz.Allocate(null, 1, tl.height, 0, pixelFormatAlpha, false); eVert.Allocate(null, borderSize /*tl.width*/, 1, 0, pixelFormatAlpha, false); eHorz.Allocate(null, 1, borderSize /*tl.height*/, 0, pixelFormatAlpha, false); ivert.Allocate(null, tl.width, 1, 0, pixelFormatAlpha, false); ihorz.Allocate(null, 1, tl.height, 0, pixelFormatAlpha, false); ieVert.Allocate(null, borderSize /*tl.width*/, 1, 0, pixelFormatAlpha, false); ieHorz.Allocate(null, 1, borderSize /*tl.height*/, 0, pixelFormatAlpha, false); { int x, y; int w = tl.width, h = tl.height, s = tl.stride; byte * picture = tl.picture, * ipicture = itl.picture; for(y = 0; y < tl.height; y++) { for(x = 0; x < tl.width; x++) { byte b = picture[y * s + x]; byte ib = ipicture[y * s + x]; ((byte *)bl.picture)[(h-1-y) * s + x] = b; ((byte *)br.picture)[(h-1-y) * s + (w-1-x)] = b; ((byte *)tr.picture)[y * s + (w-1-x)] = b; ((byte *)ibl.picture)[(h-1-y) * s + x] = ib; ((byte *)ibr.picture)[(h-1-y) * s + (w-1-x)] = ib; ((byte *)itr.picture)[y * s + (w-1-x)] = ib; /*if(x) Print(", "); printf("0x%02X", b);*/ } /*if(y < tl.height-1) Print(","); PrintLn("");*/ } /*PrintLn(""); PrintLn(""); for(y = 0; y < tl.height; y++) { for(x = 0; x < tl.width; x++) { byte ib = ipicture[y * s + x]; if(x) Print(", "); printf("0x%02X", ib); } if(y < tl.height-1) Print(","); PrintLn(""); }*/ } vert.Grab(tl, 0, tl.height - vert.height); horz.Grab(tl, tl.width - horz.width, 0); eVert.Grab(br, tl.width - borderSize, 0); eHorz.Grab(br, 0, tl.height - borderSize); ivert.Grab(itl, 0, tl.height - vert.height); ihorz.Grab(itl, tl.width - horz.width, 0); ieVert.Grab(ibr, tl.width - borderSize, 0); ieHorz.Grab(ibr, 0, tl.height - borderSize); tl.MakeDD(displaySystem); bl.MakeDD(displaySystem); tr.MakeDD(displaySystem); br.MakeDD(displaySystem); vert.MakeDD(displaySystem); horz.MakeDD(displaySystem); eVert.MakeDD(displaySystem); eHorz.MakeDD(displaySystem); itl.MakeDD(displaySystem); ibl.MakeDD(displaySystem); itr.MakeDD(displaySystem); ibr.MakeDD(displaySystem); ivert.MakeDD(displaySystem); ihorz.MakeDD(displaySystem); ieVert.MakeDD(displaySystem); ieHorz.MakeDD(displaySystem); return true; } void RenderBack(Surface surface, Size size, ColorAlpha background) { if(background) { surface.blitTint = background; surface.Tile(ihorz, tl.width,0, size.w - 2*tl.width, borderSize); surface.Tile(ivert, 0, tl.height, borderSize, size.h - 2*tl.height); surface.Tile(ieHorz, br.width, size.h - ieHorz.height, size.w - 2*br.width, ieHorz.height); surface.Tile(ieVert, size.w - ieVert.width, br.height, ieVert.width, size.h - 2*br.height); surface.Blit(itl, 0,0,0,0, borderSize, tl.height); surface.Blit(itl, 0,0,0,0, tl.width, borderSize); surface.Blit(itr, size.w - borderSize, 0, itr.width - borderSize, 0, borderSize, tr.height); surface.Blit(itr, size.w - tr.width, 0, 0, 0, tr.width, borderSize); surface.Blit(ibl, 0,size.h - borderSize, 0,bl.height - borderSize, bl.width, bl.height - borderSize); surface.Blit(ibl, 0,size.h - bl.height,0,0, borderSize, bl.height); surface.Blit(ibr, size.w - borderSize, size.h - tr.height, bl.width - borderSize, 0, borderSize, br.height); surface.Blit(ibr, size.w - br.width, size.h - borderSize, 0, bl.height - borderSize, br.width, borderSize); } } void RenderBorder(Surface surface, Size size, ColorAlpha borderColor) { if(borderColor) { surface.blitTint = borderColor; /* surface.Tile(horz, tl.width,0, size.w - 2*tl.width, horz.height); surface.Tile(vert, 0, tl.height, vert.width, size.h - 2*tl.height); surface.Tile(eHorz, br.width, size.h - eHorz.height, size.w - 2*br.width, eHorz.height); surface.Tile(eVert, size.w - eVert.width, br.height, eVert.width, size.h - 2*br.height); surface.Blit(tl, 0,0,0,0, tl.width, tl.height); surface.Blit(tr, size.w - tr.width,0,0,0, tr.width, tr.height); surface.Blit(bl, 0,size.h - bl.height,0,0, bl.width, bl.height); surface.Blit(br, size.w - br.width, size.h - tr.height,0,0, br.width, br.height);*/ surface.Tile(horz, tl.width,0, size.w - 2*tl.width, borderSize); surface.Tile(vert, 0, tl.height, borderSize, size.h - 2*tl.height); surface.Tile(eHorz, br.width, size.h - ieHorz.height, size.w - 2*br.width, ieHorz.height); surface.Tile(eVert, size.w - ieVert.width, br.height, ieVert.width, size.h - 2*br.height); surface.Blit(tl, 0,0,0,0, borderSize, tl.height); surface.Blit(tl, 0,0,0,0, tl.width, borderSize); surface.Blit(tr, size.w - borderSize, 0, itr.width - borderSize, 0, borderSize, tr.height); surface.Blit(tr, size.w - tr.width, 0, 0, 0, tr.width, borderSize); surface.Blit(bl, 0,size.h - borderSize, 0,bl.height - borderSize, bl.width, bl.height - borderSize); surface.Blit(bl, 0,size.h - bl.height,0,0, borderSize, bl.height); surface.Blit(br, size.w - borderSize, size.h - tr.height, bl.width - borderSize, 0, borderSize, br.height); surface.Blit(br, size.w - br.width, size.h - borderSize, 0, bl.height - borderSize, br.width, borderSize); } } } class RoundedSquare : Window { ColorAlpha borderColor; moveable = true; alphaBlend = true; RoundedBMPs bmps; int radius; radius = 20; bool OnLoadGraphics() { bmps = roundedBMPs[RoundMatch { displaySystem, radius }]; if(!bmps) { bmps = RoundedBMPs { displaySystem = displaySystem, radius = radius }; roundedBMPs[RoundMatch { displaySystem, radius }] = bmps; bmps.OnLoadGraphics(); } bmps.count++; return true; } void OnUnloadGraphics() { RoundedBMPs bmps = roundedBMPs[RoundMatch { displaySystem, radius }]; bmps.count--; if(!bmps.count) { //Iterator it { }; it.Find(bmps); it.Remove(); roundedBMPs[RoundMatch { displaySystem, radius }] = null; delete bmps; } } void GetDecorationsSize(MinMaxValue * w, MinMaxValue * h) { *w = borderSize * 2; *h = borderSize * 2; } void SetWindowArea(int * x, int * y, MinMaxValue * w, MinMaxValue * h, MinMaxValue * cw, MinMaxValue * ch) { *x = borderSize; *y = borderSize; *cw = *w - borderSize * 2; *ch = *h - borderSize * 2; *cw = Max(*cw, 0); *ch = Max(*ch, 0); } void PreShowDecorations(Font captionFont, Surface surface, const char * name, bool active, bool moving) { bmps.RenderBack(surface, size, { (byte)(opacity * 255), background }); } void ShowDecorations(Font captionFont, Surface surface, const char * name, bool active, bool moving) { //if(borderStyle == contour) bmps.RenderBorder(surface, size, borderColor); } bool IsOpaque() { return false;//(!style.drawBehind && opacity == 1.0); } } /* class MyRoundedSquare : RoundedSquare { background = lightBlue; //opacity = 0; borderColor = teal; radius = 15; size = { 100, 100 }; Label test { this, position = { 0, 0 }, size = { 100, 20 }, text = "Bubble Window" }; } */ /*MyRoundedSquare testRounded { };*/