diff --git a/GUI/GUITools.cpp b/GUI/GUITools.cpp index 3524965..7a46d16 100644 --- a/GUI/GUITools.cpp +++ b/GUI/GUITools.cpp @@ -4,49 +4,104 @@ namespace GraphicalUserInterface { - void PutRect(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height, uint32_t Color) + inline void InlineSetPixel(ScreenBitmap *Bitmap, long X, long Y, uint32_t Color) { - for (uint32_t i = 0; i < Width; i++) - for (uint32_t j = 0; j < Height; j++) - Display->SetPixel(X + i, Y + j, Color, 200); + if (unlikely(!Bitmap)) + return; + + if (unlikely(!Bitmap->Data)) + return; + + if (unlikely(X < 0 || Y < 0 || X >= Bitmap->Width || Y >= Bitmap->Height)) + return; + + uint32_t *Pixel = (uint32_t *)((uintptr_t)Bitmap->Data + (Y * Bitmap->Width + X) * (Bitmap->BitsPerPixel / 8)); + *Pixel = Color; + // Bitmap->Data[Y * Bitmap->Width + X] = Color; } - void PutBorder(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height, uint32_t Color) + void SetPixel(ScreenBitmap *Bitmap, long X, long Y, uint32_t Color) { - for (uint32_t i = 0; i < Width; i++) + InlineSetPixel(Bitmap, X, Y, Color); + } + + uint32_t GetPixel(ScreenBitmap *Bitmap, long X, long Y) + { + if (unlikely(!Bitmap)) + return 0; + + if (unlikely(!Bitmap->Data)) + return 0; + + if (unlikely(X < 0 || Y < 0 || X >= Bitmap->Width || Y >= Bitmap->Height)) + return 0; + + uint32_t *Pixel = (uint32_t *)((uintptr_t)Bitmap->Data + (Y * Bitmap->Width + X) * (Bitmap->BitsPerPixel / 8)); + return *Pixel; + } + + void DrawOverBitmap(ScreenBitmap *DestinationBitmap, + ScreenBitmap *SourceBitmap, + long Top, + long Left, bool IgnoreZero) + { + for (uint32_t i = 0; i < SourceBitmap->Width; i++) + for (uint32_t j = 0; j < SourceBitmap->Height; j++) + { + uint32_t *Pixel = (uint32_t *)((uintptr_t)SourceBitmap->Data + (j * SourceBitmap->Width + i) * (SourceBitmap->BitsPerPixel / 8)); + if (IgnoreZero && (*Pixel != 0x000000)) + InlineSetPixel(DestinationBitmap, Left + i, Top + j, *Pixel); + } + } + + void PutRect(ScreenBitmap *Bitmap, Rect rect, uint32_t Color) + { + for (uint32_t i = 0; i < rect.Width; i++) + for (uint32_t j = 0; j < rect.Height; j++) + InlineSetPixel(Bitmap, rect.Left + i, rect.Top + j, Color); + } + + void PutBorder(ScreenBitmap *Bitmap, Rect rect, uint32_t Color) + { + for (uint32_t i = 0; i < rect.Width; i++) { - Display->SetPixel(X + i, Y, Color, 200); - Display->SetPixel(X + i, Y + Height - 1, Color, 200); + InlineSetPixel(Bitmap, rect.Left + i, rect.Top, Color); + InlineSetPixel(Bitmap, rect.Left + i, rect.Top + rect.Height - 1, Color); } - for (uint32_t i = 0; i < Height; i++) + for (uint32_t i = 0; i < rect.Height; i++) { - Display->SetPixel(X, Y + i, Color, 200); - Display->SetPixel(X + Width - 1, Y + i, Color, 200); + InlineSetPixel(Bitmap, rect.Left, rect.Top + i, Color); + InlineSetPixel(Bitmap, rect.Left + rect.Width - 1, rect.Top + i, Color); } } - void PutBorderWithShadow(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height, uint32_t Color) + uint32_t BlendColors(uint32_t c1, uint32_t c2, float t) + { + uint8_t r1 = (c1 >> 16) & 0xFF; + uint8_t g1 = (c1 >> 8) & 0xFF; + uint8_t b1 = c1 & 0xFF; + uint8_t r2 = (c2 >> 16) & 0xFF; + uint8_t g2 = (c2 >> 8) & 0xFF; + uint8_t b2 = c2 & 0xFF; + + uint8_t r = (uint8_t)(r1 + t * (r2 - r1)); + uint8_t g = (uint8_t)(g1 + t * (g2 - g1)); + uint8_t b = (uint8_t)(b1 + t * (b2 - b1)); + + return (r << 16) | (g << 8) | b; + } + + void PutBorderWithShadow(ScreenBitmap *Bitmap, Rect rect, uint32_t Color) + { + } + +#define SHADOW_SIZE 12 + + void DrawShadow(ScreenBitmap *Bitmap, Rect rect) + { + } + + void DrawString(ScreenBitmap *Bitmap, Rect rect, const char *Text, uint32_t Color) { - uint32_t ShadowColor = (Color ? (Color / 2) : 0x000000); - for (uint32_t i = 0; i < Width; i++) - { - Display->SetPixel(X + i, Y, Color, 200); - Display->SetPixel(X + i, Y + Height - 1, Color, 200); - } - for (uint32_t i = 0; i < Height; i++) - { - Display->SetPixel(X, Y + i, Color, 200); - Display->SetPixel(X + Width - 1, Y + i, Color, 200); - } - for (uint32_t i = 0; i < Width; i++) - { - Display->SetPixel(X + i, Y + 1, ShadowColor, 200); - Display->SetPixel(X + i, Y + Height - 2, ShadowColor, 200); - } - for (uint32_t i = 0; i < Height; i++) - { - Display->SetPixel(X + 1, Y + i, ShadowColor, 200); - Display->SetPixel(X + Width - 2, Y + i, ShadowColor, 200); - } } } diff --git a/GUI/GraphicalUserInterface.cpp b/GUI/GraphicalUserInterface.cpp index c2f0743..f76cbe2 100644 --- a/GUI/GraphicalUserInterface.cpp +++ b/GUI/GraphicalUserInterface.cpp @@ -103,58 +103,206 @@ namespace GraphicalUserInterface 1, 1, 1, 0, 1, 1, 1, // }; - char CursorResizeAll[] ={ - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, // 23x23 - 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, // - 0,0,0,0,0,0,0,0,0,1,2,2,2,1,0,0,0,0,0,0,0,0,0, // - 0,0,0,0,0,0,0,0,1,2,2,2,2,2,1,0,0,0,0,0,0,0,0, // - 0,0,0,0,0,0,0,1,1,1,1,2,1,1,1,1,0,0,0,0,0,0,0, // - 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, // - 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, // - 0,0,0,0,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,0,0,0,0, // - 0,0,0,1,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,0,0,0, // - 0,0,1,2,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,2,1,0,0, // - 0,1,2,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,2,1,0, // - 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1, // - 0,1,2,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,2,1,0, // - 0,0,1,2,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,2,1,0,0, // - 0,0,0,1,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,0,0,0, // - 0,0,0,0,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,0,0,0,0, // - 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, // - 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, // - 0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, // - 0,0,0,0,0,0,0,0,1,2,2,2,2,2,1,0,0,0,0,0,0,0,0, // - 0,0,0,0,0,0,0,0,0,1,2,2,2,1,0,0,0,0,0,0,0,0,0, // - 0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, // - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, // + char CursorResizeAll[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 23x23 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, // + 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, // + 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, // + 0, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 0, // + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, // + 0, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 0, // + 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, // + 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, // + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // }; - void GUI::PaintDesktop() - { - PutRect(0, 0, Display->GetBuffer(200)->Width, Display->GetBuffer(200)->Height, 0x282828); - } + uint32_t DesktopFadeEffect[] = { + 0xFF000000, + 0x010101, + 0x040404, + 0x080808, + 0x101010, + 0x121212, + 0x151515, + 0x181818, + 0x1A1A1A, + 0x1D1D1D, + 0x1F1F1F, + 0x222222, + 0x242424, + 0x262626, + 0x282828, + }; - void GUI::PaintWindows() - { - foreach (auto wnd in this->Windows) - wnd->Paint(); - } + char CloseButton[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + }; - void GUI::PaintCursor() + char MinimizeButton[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + }; + + char MaximizeButtonNormal[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + }; + + char MaximizeButtonMaximized[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + }; + + char ResizeHint[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + }; + + uint32_t CloseButtonFade[] = { + 0x404040, + 0x770000, + 0x990000, + 0xBB0000, + 0xDD0000, + 0xFF0000, + }; + + uint32_t MaximizeMinimizeButtonFade[] = { + 0x404040, + 0x454545, + 0x505050, + 0x5F5F5F, + }; + + void GUI::FetchInputs() { KernelCallback callback; + MouseData Mouse; if (DriverManager->GetDrivers().size() > 0) { foreach (auto Driver in DriverManager->GetDrivers()) { if (((FexExtended *)((uintptr_t)Driver->Address + EXTENDED_SECTION_ADDRESS))->Driver.Type == FexDriverType::FexDriverType_Input) { + static uint32_t DisplayWidth = 0; + static uint32_t DisplayHeight = 0; + + if (DisplayWidth == 0) + DisplayWidth = Display->GetBuffer(200)->Width; + + if (DisplayHeight == 0) + DisplayHeight = Display->GetBuffer(200)->Height; + memset(&callback, 0, sizeof(KernelCallback)); callback.Reason = FetchReason; DriverManager->IOCB(Driver->DriverUID, (void *)&callback); // TODO: I think I should check somehow what driver is the one that is mouse and not keyboard - Mouse.X = (callback.InputCallback.Mouse.X * Display->GetBuffer(200)->Width) / 0xFFFF; // VMWARE mouse - Mouse.Y = (callback.InputCallback.Mouse.Y * Display->GetBuffer(200)->Height) / 0xFFFF; // VMWARE mouse + Mouse.X = (callback.InputCallback.Mouse.X * DisplayWidth) / 0xFFFF; // VMWARE mouse + Mouse.Y = (callback.InputCallback.Mouse.Y * DisplayHeight) / 0xFFFF; // VMWARE mouse Mouse.Z = (callback.InputCallback.Mouse.Z); Mouse.Left = callback.InputCallback.Mouse.Buttons.Left; Mouse.Right = callback.InputCallback.Mouse.Buttons.Right; @@ -164,150 +312,455 @@ namespace GraphicalUserInterface } } - uint32_t CursorColorInner = 0xFFFFFFFF; - uint32_t CursorColorOuter = 0x00000000; - - switch (this->Cursor) - { - case CursorType::Visible: - { - CursorVisible = true; - break; - } - case CursorType::Hidden: - { - CursorVisible = false; - break; - } - default: - fixme("Unknown cursor type %d", this->Cursor); - [[fallthrough]]; - case CursorType::Arrow: - { - if (CursorVisible) - for (int i = 0; i < 19; i++) - { - for (int j = 0; j < 12; j++) - { - if (CursorArrow[i * 12 + j] == 1) - { - Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200); - } - else if (CursorArrow[i * 12 + j] == 2) - { - Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200); - } - } - } - break; - } - case CursorType::Hand: - { - if (CursorVisible) - for (int i = 0; i < 24; i++) - { - for (int j = 0; j < 17; j++) - { - if (CursorHand[i * 17 + j] == 1) - { - Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200); - } - else if (CursorHand[i * 17 + j] == 2) - { - Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200); - } - } - } - break; - } - case CursorType::Wait: - { - if (CursorVisible) - for (int i = 0; i < 22; i++) - { - for (int j = 0; j < 13; j++) - { - if (CursorWait[i * 13 + j] == 1) - { - Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200); - } - else if (CursorWait[i * 13 + j] == 2) - { - Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200); - } - } - } - break; - } - case CursorType::IBeam: - { - if (CursorVisible) - for (int i = 0; i < 22; i++) - { - for (int j = 0; j < 13; j++) - { - if (CursorIBeam[i * 13 + j] == 1) - { - Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200); - } - else if (CursorIBeam[i * 13 + j] == 2) - { - Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200); - } - } - } - break; - } - case CursorType::ResizeAll: - { - if (CursorVisible) - for (int i = 0; i < 23; i++) - { - for (int j = 0; j < 23; j++) - { - if (CursorResizeAll[i * 23 + j] == 1) - { - Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200); - } - else if (CursorResizeAll[i * 23 + j] == 2) - { - Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200); - } - } - } - break; - } - } - + Event eTemplate; + memset(&eTemplate, 0, sizeof(Event)); foreach (auto wnd in this->Windows) { - Event ev; - ev.Type = EventType::MouseEvent; - ev.Mouse.X = Mouse.X; - ev.Mouse.Y = Mouse.Y; - ev.Mouse.Z = Mouse.Z; - ev.Mouse.Left = Mouse.Left; - ev.Mouse.Right = Mouse.Right; - ev.Mouse.Middle = Mouse.Middle; - ev.LastMouse.X = LastMouse.X; - ev.LastMouse.Y = LastMouse.Y; - ev.LastMouse.Z = LastMouse.Z; - ev.LastMouse.Left = LastMouse.Left; - ev.LastMouse.Right = LastMouse.Right; - ev.LastMouse.Middle = LastMouse.Middle; - wnd->HandleEvent(&ev); + if ((!MouseArray[1].Left || !MouseArray[1].Right || !MouseArray[1].Middle) && + (Mouse.Left || Mouse.Right || Mouse.Middle)) + { + eTemplate.MouseDown.X = Mouse.X; + eTemplate.MouseDown.Y = Mouse.Y; + eTemplate.MouseDown.Left = Mouse.Left; + eTemplate.MouseDown.Right = Mouse.Right; + eTemplate.MouseDown.Middle = Mouse.Middle; + wnd->OnMouseDown(&eTemplate); + } + + if ((MouseArray[1].Left || MouseArray[1].Right || MouseArray[1].Middle) && + (!Mouse.Left || !Mouse.Right || !Mouse.Middle)) + { + eTemplate.MouseUp.X = Mouse.X; + eTemplate.MouseUp.Y = Mouse.Y; + eTemplate.MouseUp.Left = Mouse.Left; + eTemplate.MouseUp.Right = Mouse.Right; + eTemplate.MouseUp.Middle = Mouse.Middle; + wnd->OnMouseUp(&eTemplate); + } + + if (Mouse.X != MouseArray[1].X || Mouse.Y != MouseArray[1].Y) + { + Rect TopBarPos = wnd->GetPosition(); + TopBarPos.Top -= 20; + TopBarPos.Height = 20; + TopBarPos.Width -= 60; /* buttons */ + if (TopBarPos.Top < 0) + { + TopBarPos.Top = 0; + wnd->GetPositionPtr()->Top = 20; + } + + Rect ResizeHintPos = wnd->GetPosition(); + ResizeHintPos.Left += ResizeHintPos.Width - 20; + ResizeHintPos.Top += ResizeHintPos.Height - 20; + ResizeHintPos.Width = 20; + ResizeHintPos.Height = 20; + + if (TopBarPos.Contains(Mouse.X, Mouse.Y) || + TopBarPos.Contains(MouseArray[0].X, MouseArray[0].Y) || + TopBarPos.Contains(MouseArray[1].X, MouseArray[1].Y)) + { + if (Mouse.Left) + { + if (MouseArray[1].Left) + { + wnd->GetPositionPtr()->Left += Mouse.X - MouseArray[0].X; + wnd->GetPositionPtr()->Top += Mouse.Y - MouseArray[0].Y; + OverlayBufferRepaint = true; + OverlayFullRepaint = true; + } + } + } + + if (ResizeHintPos.Contains(Mouse.X, Mouse.Y) || + ResizeHintPos.Contains(MouseArray[0].X, MouseArray[0].Y) || + ResizeHintPos.Contains(MouseArray[1].X, MouseArray[1].Y)) + { + if (Mouse.Left) + { + if (MouseArray[1].Left) + { + wnd->GetPositionPtr()->Width += Mouse.X - MouseArray[0].X; + wnd->GetPositionPtr()->Height += Mouse.Y - MouseArray[0].Y; + OverlayBufferRepaint = true; + OverlayFullRepaint = true; + eTemplate.Resize.Width = wnd->GetPosition().Width; + eTemplate.Resize.Height = wnd->GetPosition().Height; + wnd->OnResize(&eTemplate); + } + } + + if (Cursor != CursorType::ResizeAll) + { + Cursor = CursorType::ResizeAll; + CursorBufferRepaint = true; + } + } + else + { + if (Cursor != CursorType::Arrow) + { + Cursor = CursorType::Arrow; + CursorBufferRepaint = true; + } + } + + eTemplate.MouseMove.X = Mouse.X; + eTemplate.MouseMove.Y = Mouse.Y; + eTemplate.MouseMove.Left = Mouse.Left; + eTemplate.MouseMove.Right = Mouse.Right; + eTemplate.MouseMove.Middle = Mouse.Middle; + wnd->OnMouseMove(&eTemplate); + } } - LastMouse = Mouse; + foreach (auto wdg in this->Widgets) + { + } + + memmove(MouseArray + 1, MouseArray, sizeof(MouseArray) - sizeof(MouseArray[1])); + MouseArray[0] = Mouse; + + LastCursor = Cursor; + } + + void GUI::PaintDesktop() + { + if (DesktopBufferRepaint) + { + PutRect(this->DesktopBuffer, this->Desktop, 0x404040); + DesktopBufferRepaint = false; + } + // Well... I have to do some code optimization on DrawOverBitmap. It's too slow and it's not even using SIMD + memcpy(this->BackBuffer->Data, this->DesktopBuffer->Data, this->DesktopBuffer->Size); + } + + void GUI::PaintWidgets() + { + Event eTemplate; + memset(&eTemplate, 0, sizeof(Event)); + foreach (auto wdg in this->Widgets) + wdg->OnPaint(nullptr); + } + + void GUI::PaintWindows() + { + foreach (auto wnd in this->Windows) + { + ScreenBitmap *wndBuffer = wnd->GetBuffer(); + if (unlikely(wndBuffer == nullptr)) // I think "unlikely" is not needed here + continue; + + Rect WndPos = wnd->GetPosition(); + + // Draw window + DrawOverBitmap(this->BackBuffer, + wndBuffer, + WndPos.Top, + WndPos.Left); + + /* We can't use memcpy because the window buffer + is not the same size as the screen buffer + https://i.imgur.com/OHfaYnS.png */ + // memcpy(this->BackBuffer->Data + wnd->GetPositionPtr()->Top * this->BackBuffer->Width + wnd->GetPositionPtr()->Left, wndBuffer->Data, wndBuffer->Size); + + Rect TopBarPos = WndPos; + TopBarPos.Top -= 20; + TopBarPos.Height = 20; + if (TopBarPos.Top < 0) + { + TopBarPos.Top = 0; + wnd->GetPositionPtr()->Top = 20; + } + + Rect CloseButtonPos; + Rect MinimizeButtonPos; + + CloseButtonPos.Left = TopBarPos.Left + TopBarPos.Width - 20; + CloseButtonPos.Top = TopBarPos.Top; + CloseButtonPos.Width = 20; + CloseButtonPos.Height = 20; + + MinimizeButtonPos.Left = TopBarPos.Left + TopBarPos.Width - 60; + + if (unlikely(MouseArray[0].X >= MinimizeButtonPos.Left && + MouseArray[0].X <= CloseButtonPos.Left + CloseButtonPos.Width && + MouseArray[0].Y >= CloseButtonPos.Top && + MouseArray[0].Y <= CloseButtonPos.Top + CloseButtonPos.Height)) + { + OverlayBufferRepaint = true; + } + + // Title bar + if (unlikely(OverlayBufferRepaint)) + { + if (OverlayFullRepaint) + { + memset(this->OverlayBuffer->Data, 0, this->OverlayBuffer->Size); + OverlayFullRepaint = false; + } + + static bool RepaintNeeded = false; + DrawShadow(this->OverlayBuffer, wnd->GetPosition()); + + Rect MaximizeButtonPos; + MaximizeButtonPos.Left = TopBarPos.Left + TopBarPos.Width - 40; + MaximizeButtonPos.Top = TopBarPos.Top; + MaximizeButtonPos.Width = 20; + MaximizeButtonPos.Height = 20; + + MinimizeButtonPos.Top = TopBarPos.Top; + MinimizeButtonPos.Width = 20; + MinimizeButtonPos.Height = 20; + + PutRect(this->OverlayBuffer, TopBarPos, 0x282828); + // Title bar buttons (close, minimize, maximize) on the right + if (MouseArray[0].X >= CloseButtonPos.Left && + MouseArray[0].X <= CloseButtonPos.Left + CloseButtonPos.Width && + MouseArray[0].Y >= CloseButtonPos.Top && + MouseArray[0].Y <= CloseButtonPos.Top + CloseButtonPos.Height) + { + PutRect(this->OverlayBuffer, CloseButtonPos, 0xFF0000); + RepaintNeeded = true; + } + else + { + PutRect(this->OverlayBuffer, MaximizeButtonPos, 0x282828); + } + + if (MouseArray[0].X >= MaximizeButtonPos.Left && + MouseArray[0].X <= MaximizeButtonPos.Left + MaximizeButtonPos.Width && + MouseArray[0].Y >= MaximizeButtonPos.Top && + MouseArray[0].Y <= MaximizeButtonPos.Top + MaximizeButtonPos.Height) + { + PutRect(this->OverlayBuffer, MaximizeButtonPos, 0x404040); + RepaintNeeded = true; + } + else + { + PutRect(this->OverlayBuffer, MaximizeButtonPos, 0x282828); + } + + if (MouseArray[0].X >= MinimizeButtonPos.Left && + MouseArray[0].X <= MinimizeButtonPos.Left + MinimizeButtonPos.Width && + MouseArray[0].Y >= MinimizeButtonPos.Top && + MouseArray[0].Y <= MinimizeButtonPos.Top + MinimizeButtonPos.Height) + { + PutRect(this->OverlayBuffer, MinimizeButtonPos, 0x404040); + RepaintNeeded = true; + } + else + { + PutRect(this->OverlayBuffer, MinimizeButtonPos, 0x282828); + } + + // Title bar icons (close, minimize, maximize) on the right + for (short i = 0; i < 20; i++) + { + for (short j = 0; j < 20; j++) + { + if (CloseButton[i * 20 + j] == 1) + SetPixel(this->OverlayBuffer, + CloseButtonPos.Left + j, + CloseButtonPos.Top + i, + 0xFFFFFF); + + if ((MaximizeButtonMaximized[i * 20 + j] == 1) && !wnd->IsMaximized()) + SetPixel(this->OverlayBuffer, + MaximizeButtonPos.Left + j, + MaximizeButtonPos.Top + i, + 0xFFFFFF); + else if ((MaximizeButtonNormal[i * 20 + j] == 1) && wnd->IsMaximized()) + SetPixel(this->OverlayBuffer, + MaximizeButtonPos.Left + j, + MaximizeButtonPos.Top + i, + 0xFFFFFF); + + if (MinimizeButton[i * 20 + j] == 1) + SetPixel(this->OverlayBuffer, + MinimizeButtonPos.Left + j, + MinimizeButtonPos.Top + i, + 0xFFFFFF); + } + } + + Rect wndPos = wnd->GetPosition(); + + // Resize hint + for (short i = 0; i < 20; i++) + for (short j = 0; j < 20; j++) + if (ResizeHint[i * 20 + j] == 1) + SetPixel(this->OverlayBuffer, wndPos.Left + wndPos.Width - 20 + j, wndPos.Top + wndPos.Height - 20 + i, 0xFFFFFF); + + // Title bar border + PutBorder(this->OverlayBuffer, TopBarPos, 0xFF000000); + // Window border + PutBorder(this->OverlayBuffer, wndPos, 0xFF000000); + + Rect TopBarTextPos = TopBarPos; + TopBarTextPos.Left += 5; + TopBarTextPos.Top += 5; + + // Title bar text + DrawString(this->OverlayBuffer, TopBarTextPos, wnd->GetTitle(), 0xFFFFFFFF); + + if (!RepaintNeeded) + { + OverlayBufferRepaint = false; + RepaintNeeded = false; + } + } + wnd->OnPaint(nullptr); + } + DrawOverBitmap(this->BackBuffer, this->OverlayBuffer, 0, 0); + } + +/* + "* 2" to increase the size of the cursor + "/ 2" to decrease the size of the cursor +*/ +#define ICON_SIZE + + void GUI::PaintCursor() + { + uint32_t CursorColorInner = 0xFFFFFFFF; + uint32_t CursorColorOuter = 0xFF000000; + + if (MouseArray[0].X != MouseArray[1].X || + MouseArray[0].Y != MouseArray[1].Y || + MouseArray[0].Z != MouseArray[1].Z || + Cursor != LastCursor) + CursorBufferRepaint = true; + + if (CursorBufferRepaint) + { + memset(this->CursorBuffer->Data, 0, this->CursorBuffer->Size); + switch (this->Cursor) + { + case CursorType::Visible: + { + CursorVisible = true; + break; + } + case CursorType::Hidden: + { + CursorVisible = false; + break; + } + default: + fixme("Unknown cursor type %d", this->Cursor); + [[fallthrough]]; + case CursorType::Arrow: + { + if (CursorVisible) + for (int i = 0; i < 19; i++) + { + for (int j = 0; j < 12; j++) + { + if (CursorArrow[i * 12 + j] == 1) + { + SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorOuter); + } + else if (CursorArrow[i * 12 + j] == 2) + { + SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorInner); + } + } + } + break; + } + case CursorType::Hand: + { + if (CursorVisible) + for (int i = 0; i < 24; i++) + { + for (int j = 0; j < 17; j++) + { + if (CursorHand[i * 17 + j] == 1) + { + SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorOuter); + } + else if (CursorHand[i * 17 + j] == 2) + { + SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorInner); + } + } + } + break; + } + case CursorType::Wait: + { + if (CursorVisible) + for (int i = 0; i < 22; i++) + { + for (int j = 0; j < 13; j++) + { + if (CursorWait[i * 13 + j] == 1) + { + SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorOuter); + } + else if (CursorWait[i * 13 + j] == 2) + { + SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorInner); + } + } + } + break; + } + case CursorType::IBeam: + { + if (CursorVisible) + for (int i = 0; i < 22; i++) + { + for (int j = 0; j < 13; j++) + { + if (CursorIBeam[i * 13 + j] == 1) + { + SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorOuter); + } + else if (CursorIBeam[i * 13 + j] == 2) + { + SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorInner); + } + } + } + break; + } + case CursorType::ResizeAll: + { + if (CursorVisible) + for (int i = 0; i < 23; i++) + { + for (int j = 0; j < 23; j++) + { + if (CursorResizeAll[i * 23 + j] == 1) + { + SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorOuter); + } + else if (CursorResizeAll[i * 23 + j] == 2) + { + SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorInner); + } + } + } + break; + } + } + CursorBufferRepaint = false; + } + DrawOverBitmap(this->BackBuffer, this->CursorBuffer, MouseArray[0].Y, MouseArray[0].X); } void GUI::Loop() { while (IsRunning) { + FetchInputs(); PaintDesktop(); + PaintWidgets(); PaintWindows(); PaintCursor(); + memcpy(Display->GetBuffer(200)->Buffer, this->BackBuffer->Data, this->BackBuffer->Size); Display->SetBuffer(200); } } @@ -317,16 +770,66 @@ namespace GraphicalUserInterface this->Windows.push_back(window); } + void GUI::AddWidget(WidgetCollection *widget) + { + this->Widgets.push_back(widget); + } + GUI::GUI() { - this->mem = new Memory::MemMgr; Display->CreateBuffer(0, 0, 200); + this->mem = new Memory::MemMgr; + this->Desktop.Top = 0; + this->Desktop.Left = 0; + this->Desktop.Width = Display->GetBuffer(200)->Width; + this->Desktop.Height = Display->GetBuffer(200)->Height; + + this->BackBuffer = new ScreenBitmap; + this->BackBuffer->Width = this->Desktop.Width; + this->BackBuffer->Height = this->Desktop.Height; + this->BackBuffer->BitsPerPixel = Display->GetBitsPerPixel(); + this->BackBuffer->Pitch = Display->GetPitch(); + this->BackBuffer->Size = Display->GetBuffer(200)->Size; + this->BackBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->BackBuffer->Size)); + memset(this->BackBuffer->Data, 0, this->BackBuffer->Size); + + this->DesktopBuffer = new ScreenBitmap; + this->DesktopBuffer->Width = this->Desktop.Width; + this->DesktopBuffer->Height = this->Desktop.Height; + this->DesktopBuffer->BitsPerPixel = Display->GetBitsPerPixel(); + this->DesktopBuffer->Pitch = Display->GetPitch(); + this->DesktopBuffer->Size = Display->GetBuffer(200)->Size; + this->DesktopBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->DesktopBuffer->Size)); + memset(this->DesktopBuffer->Data, 0, this->DesktopBuffer->Size); + + this->OverlayBuffer = new ScreenBitmap; + this->OverlayBuffer->Width = this->Desktop.Width; + this->OverlayBuffer->Height = this->Desktop.Height; + this->OverlayBuffer->BitsPerPixel = Display->GetBitsPerPixel(); + this->OverlayBuffer->Pitch = Display->GetPitch(); + this->OverlayBuffer->Size = Display->GetBuffer(200)->Size; + this->OverlayBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->OverlayBuffer->Size)); + memset(this->OverlayBuffer->Data, 0, this->OverlayBuffer->Size); + + this->CursorBuffer = new ScreenBitmap; + this->CursorBuffer->Width = 25; + this->CursorBuffer->Height = 25; + this->CursorBuffer->BitsPerPixel = Display->GetBitsPerPixel(); + this->CursorBuffer->Pitch = Display->GetPitch(); + this->CursorBuffer->Size = this->CursorBuffer->Width * this->CursorBuffer->Height * (this->CursorBuffer->BitsPerPixel / 8); + this->CursorBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->CursorBuffer->Size)); + memset(this->CursorBuffer->Data, 0, this->CursorBuffer->Size); + this->IsRunning = true; } GUI::~GUI() { delete this->mem; + delete this->BackBuffer; + delete this->DesktopBuffer; + delete this->OverlayBuffer; + delete this->CursorBuffer; Display->DeleteBuffer(200); for (size_t i = 0; i < this->Windows.size(); i++) this->Windows.remove(i); diff --git a/GUI/WidgetEvents.cpp b/GUI/WidgetEvents.cpp new file mode 100644 index 0000000..7626b35 --- /dev/null +++ b/GUI/WidgetEvents.cpp @@ -0,0 +1,17 @@ +#include + +#include +#include +#include +#include + +#include "../kernel.h" +#include "../DAPI.hpp" +#include "../Fex.hpp" + +namespace GraphicalUserInterface +{ + void WidgetCollection::OnPaint(Event *e) + { + } +} diff --git a/GUI/Widgets.cpp b/GUI/Widgets.cpp index 0da32bb..5ea5ae5 100644 --- a/GUI/Widgets.cpp +++ b/GUI/Widgets.cpp @@ -11,20 +11,17 @@ namespace GraphicalUserInterface { - void Widget::Paint() + Handle WidgetCollection::CreatePanel(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height) { + return 0; } - void Widget::HandleEvent(Event *e) - { - } - - Widget::Widget(void *ParentWindow) + WidgetCollection::WidgetCollection(void *ParentWindow) { this->mem = new Memory::MemMgr; } - Widget::~Widget() + WidgetCollection::~WidgetCollection() { delete this->mem; } diff --git a/GUI/Window.cpp b/GUI/Window.cpp index 9b68020..3eb7492 100644 --- a/GUI/Window.cpp +++ b/GUI/Window.cpp @@ -11,406 +11,52 @@ namespace GraphicalUserInterface { - char CloseButton[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - }; - char MinimizeButton[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - }; +#define TASKBAR_HEIGHT 25 - char MaximizeButtonNormal[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - }; - char MaximizeButtonMaximized[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - }; + // if (!Maximized) + // { + // this->LastPosition.Left = this->Position.Left; + // this->LastPosition.Top = this->Position.Top; + // this->LastPosition.Width = this->Position.Width; + // this->LastPosition.Height = this->Position.Height; + // this->Position.Left = 0; + // this->Position.Top = 0; + // this->Position.Width = Display->GetBuffer(200)->Width; + // this->Position.Height = Display->GetBuffer(200)->Height - 20 - TASKBAR_HEIGHT; + // Maximized = true; + // } + // else + // { + // this->Position.Left = this->LastPosition.Left; + // this->Position.Top = this->LastPosition.Top; + // this->Position.Width = this->LastPosition.Width; + // this->Position.Height = this->LastPosition.Height; + // Maximized = false; + // } - char ResizeHint[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - }; - - uint32_t CloseButtonFade[] = { - 0x404040, - 0x770000, - 0x990000, - 0xBB0000, - 0xDD0000, - 0xFF0000, - }; - - uint32_t MaximizeMinimizeButtonFade[] = { - 0x404040, - 0x454545, - 0x505050, - 0x5F5F5F, - }; - - void Window::Paint() - { - // Window background - PutRect(this->Left, this->Top + 20, this->Width, this->Height, 0x121212); - // Title bar - PutRect(this->Left, this->Top, this->Width, 20, 0x404040); - // Title bar buttons (close, minimize, maximize) on the right - static int CloseButtonIteration = 0; - static int MaximizeButtonIteration = 0; - static int MinimizeButtonIteration = 0; - if (CloseButtonFocused) - { - PutRect(this->Left + this->Width - 20, this->Top, 20, 20, CloseButtonFade[CloseButtonIteration]); - if (CloseButtonIteration < 5) - CloseButtonIteration++; - } - else - { - PutRect(this->Left + this->Width - 20, this->Top, 20, 20, CloseButtonFade[CloseButtonIteration]); - if (CloseButtonIteration > 0) - CloseButtonIteration--; - } - - if (MaximizeButtonFocused) - { - PutRect(this->Left + this->Width - 40, this->Top, 20, 20, MaximizeMinimizeButtonFade[MaximizeButtonIteration]); - if (MaximizeButtonIteration < 3) - MaximizeButtonIteration++; - } - else - { - PutRect(this->Left + this->Width - 40, this->Top, 20, 20, MaximizeMinimizeButtonFade[MaximizeButtonIteration]); - if (MaximizeButtonIteration > 0) - MaximizeButtonIteration--; - } - - if (MinimizeButtonFocused) - { - PutRect(this->Left + this->Width - 60, this->Top, 20, 20, MaximizeMinimizeButtonFade[MinimizeButtonIteration]); - if (MinimizeButtonIteration < 3) - MinimizeButtonIteration++; - } - else - { - PutRect(this->Left + this->Width - 60, this->Top, 20, 20, MaximizeMinimizeButtonFade[MinimizeButtonIteration]); - if (MinimizeButtonIteration > 0) - MinimizeButtonIteration--; - } - - // Title bar icons (close, minimize, maximize) on the right - for (int i = 0; i < 20; i++) - { - for (int j = 0; j < 20; j++) - { - if (CloseButton[i * 20 + j] == 1) - { - Display->SetPixel(this->Left + this->Width - 20 + j, this->Top + i, 0xFFFFFF, 200); - } - if ((MaximizeButtonMaximized[i * 20 + j] == 1) && !this->Maximized) - { - Display->SetPixel(this->Left + this->Width - 40 + j, this->Top + i, 0xFFFFFF, 200); - } - else if ((MaximizeButtonNormal[i * 20 + j] == 1) && this->Maximized) - { - Display->SetPixel(this->Left + this->Width - 40 + j, this->Top + i, 0xFFFFFF, 200); - } - if (MinimizeButton[i * 20 + j] == 1) - { - Display->SetPixel(this->Left + this->Width - 60 + j, this->Top + i, 0xFFFFFF, 200); - } - } - } - - // Resize hint - for (int i = 0; i < 20; i++) - { - for (int j = 0; j < 20; j++) - { - if (ResizeHint[i * 20 + j] == 1) - { - Display->SetPixel(this->Left + this->Width - 20 + j, this->Top + this->Height + i, 0xFFFFFF, 200); - } - } - } - - // Title bar border - PutBorder(this->Left, this->Top, this->Width, 20, 0x000000); - // Window border - PutBorder(this->Left, this->Top + 20, this->Width, this->Height, 0x000000); - // Title bar text - Display->DrawString(this->Title, this->Left + 5, this->Top + 5, 200); - - // Window content - foreach (auto var in this->Widgets) - { - var->Paint(); - } - - if (!this->Maximized) - { - char buf[100]; - sprintf_(buf, "Left:\eAA11FF%ld\eFFFFFF Top:\eAA11FF%ld\eFFFFFF W:\eAA11FF%ld\eFFFFFF H:\eAA11FF%ld\eFFFFFF", this->Left, this->Top, this->Width, this->Height); - Display->DrawString(buf, this->Left + 20, this->Top + 25, 200); - } - } - - void Window::Close() - { - fixme("Window::Close() not implemented"); - } - - void Window::Maximize() - { - if (!Maximized) - { - this->Last_Left = this->Left; - this->Last_Top = this->Top; - this->Last_Width = this->Width; - this->Last_Height = this->Height; - this->Left = 0; - this->Top = 0; - this->Width = Display->GetBuffer(200)->Width; - this->Height = Display->GetBuffer(200)->Height; - Maximized = true; - } - else - { - this->Left = this->Last_Left; - this->Top = this->Last_Top; - this->Width = this->Last_Width; - this->Height = this->Last_Height; - Maximized = false; - } - } - - void Window::Minimize() - { - fixme("Window::Minimize() not implemented"); - } - - void Window::HandleEvent(Event *e) - { - if (e->Type == EventType::MouseEvent) - { - // close button - if (!WindowDragging && - e->Mouse.X >= this->Left + this->Width - 20 && - e->Mouse.X <= this->Left + this->Width && - e->Mouse.Y >= this->Top && - e->Mouse.Y <= this->Top + 20) - { - if (e->Mouse.Left) - { - this->Close(); - } - CloseButtonFocused = true; - } - else - CloseButtonFocused = false; - - // maximize button - if (!WindowDragging && - e->Mouse.X >= this->Left + this->Width - 40 && - e->Mouse.X <= this->Left + this->Width - 20 && - e->Mouse.Y >= this->Top && - e->Mouse.Y <= this->Top + 20) - { - if (e->Mouse.Left) - { - this->Maximize(); - } - MaximizeButtonFocused = true; - } - else - MaximizeButtonFocused = false; - - // minimize button - if (!WindowDragging && - e->Mouse.X >= this->Left + this->Width - 60 && - e->Mouse.X <= this->Left + this->Width - 40 && - e->Mouse.Y >= this->Top && - e->Mouse.Y <= this->Top + 20) - { - if (e->Mouse.Left) - { - this->Minimize(); - } - MinimizeButtonFocused = true; - } - else - MinimizeButtonFocused = false; - - // window dragging - if (e->Mouse.X >= this->Left && - e->Mouse.X <= this->Left + this->Width && - e->Mouse.Y >= this->Top && - e->Mouse.Y <= this->Top + 20) - { - if (e->Mouse.Left && - !Maximized) - { - long X = (long)this->Left + (long)e->Mouse.X - (long)e->LastMouse.X; - long Y = (long)this->Top + (long)e->Mouse.Y - (long)e->LastMouse.Y; - - if (X < 0) - X = 0; - else if (X + this->Width > Display->GetBuffer(200)->Width) - X = Display->GetBuffer(200)->Width - this->Width; - - if (Y < 0) - Y = 0; - else if (Y + this->Height + 20 > Display->GetBuffer(200)->Height) - Y = Display->GetBuffer(200)->Height - this->Height - 20; - - this->Left = X; - this->Top = Y; - WindowDragging = true; - } - else - WindowDragging = false; - } - - // resize - if (!WindowDragging && - e->Mouse.X >= this->Left + this->Width - 20 && - e->Mouse.X <= this->Left + this->Width && - e->Mouse.Y >= this->Top + this->Height && - e->Mouse.Y <= this->Top + this->Height + 20) - { - if (e->Mouse.Left) - { - long X = this->Width + (long)e->Mouse.X - (long)e->LastMouse.X; - long Y = this->Height + (long)e->Mouse.Y - (long)e->LastMouse.Y; - if (X < 250) - X = 250; - if (Y < 150) - Y = 150; - this->Width = X; - this->Height = Y; - } - ((GUI *)this->ParentGUI)->SetCursorType(CursorType::ResizeAll); - } - else - { - ((GUI *)this->ParentGUI)->SetCursorType(CursorType::Arrow); - } - } - } - - void Window::AddWidget(Widget *widget) + void Window::AddWidget(WidgetCollection *widget) { this->Widgets.push_back(widget); } - Window::Window(void *ParentGUI, uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Title) + Window::Window(void *ParentGUI, Rect rect, const char *Title) { this->mem = new Memory::MemMgr; + this->Buffer = new ScreenBitmap; + this->Buffer->Width = rect.Width; + this->Buffer->Height = rect.Height; + this->Buffer->BitsPerPixel = Display->GetBitsPerPixel(); + this->Buffer->Pitch = Display->GetPitch(); + this->Buffer->Size = this->Buffer->Pitch * rect.Height; + this->Buffer->Data = (uint8_t*)this->mem->RequestPages(TO_PAGES(this->Buffer->Size)); + memset(this->Buffer->Data, 0, this->Buffer->Size); this->ParentGUI = ParentGUI; - this->Left = Left; - this->Top = Top; - this->Width = Width; - this->Height = Height; + this->Position = rect; strcpy(this->Title, Title); this->Maximized = false; this->Minimized = false; - this->CloseButtonFocused = false; - this->MaximizeButtonFocused = false; - this->MinimizeButtonFocused = false; - this->WindowDragging = false; } Window::~Window() diff --git a/GUI/WindowEvents.cpp b/GUI/WindowEvents.cpp new file mode 100644 index 0000000..86c5e8d --- /dev/null +++ b/GUI/WindowEvents.cpp @@ -0,0 +1,72 @@ +#include + +#include +#include +#include +#include + +#include "../kernel.h" +#include "../DAPI.hpp" +#include "../Fex.hpp" + +namespace GraphicalUserInterface +{ + void Window::OnResize(Event *e) + { + fixme("Window::OnResize() not implemented"); + } + + void Window::OnMinimize(Event *e) + { + fixme("Window::OnMinimize() not implemented"); + } + + void Window::OnMaximize(Event *e) + { + fixme("Window::OnMaximize() not implemented"); + } + + void Window::OnClose(Event *e) + { + fixme("Window::OnClose() not implemented"); + } + + void Window::OnPaintBackground(Event *e) + { + PutRect(this->Buffer, this->Position, /*0x121212*/ 0xFF00FF); + } + + void Window::OnPaintForeground(Event *e) + { + // Window content + if (!this->Maximized) + { + char buf[256]; + sprintf_(buf, "Left:\eAA11FF%ld\eFFFFFF Top:\eAA11FF%ld\eFFFFFF W:\eAA11FF%ld\eFFFFFF H:\eAA11FF%ld\eFFFFFF", this->Position.Left, this->Position.Top, this->Position.Width, this->Position.Height); + // Display->DrawString(buf, this->Position.Left + 20, this->Position.Top + 25, 200); + } + + foreach (auto var in this->Widgets) + { + var->OnPaint(e); + } + } + + void Window::OnPaint(Event *e) + { + this->OnPaintBackground(e); + this->OnPaintForeground(e); + } + + void Window::OnMouseDown(Event *e) + { + } + + void Window::OnMouseUp(Event *e) + { + } + + void Window::OnMouseMove(Event *e) + { + } +} diff --git a/Recovery/RecoveryMain.cpp b/Recovery/RecoveryMain.cpp index 0c81f53..e0545a7 100644 --- a/Recovery/RecoveryMain.cpp +++ b/Recovery/RecoveryMain.cpp @@ -35,9 +35,13 @@ namespace Recovery auxv.push_back({.archaux = {.a_type = AT_NULL, .a_un = {.a_val = 0}}}); // TaskManager->CreateThread(proc, (IP)RecoveryThreadWrapper, nullptr, nullptr, auxv); TCB *guiThread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (IP)GUIWrapper, nullptr, nullptr, auxv); + guiThread->Rename("GUI Thread"); guiThread->SetPriority(100); - Window *win = new Window(gui, 50, 50, 400, 250, "Recovery"); + Window *win = new Window(gui, {50, 50, 400, 250}, "Recovery"); + WidgetCollection *wdg = new WidgetCollection(nullptr); + wdg->CreatePanel(0, Display->GetBuffer(0)->Height - 25, Display->GetBuffer(0)->Width, 25); gui->AddWindow(win); + win->AddWidget(wdg); } KernelRecovery::~KernelRecovery() diff --git a/include/gui.hpp b/include/gui.hpp index d9dc84e..d075ccd 100644 --- a/include/gui.hpp +++ b/include/gui.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace GraphicalUserInterface { @@ -11,14 +12,42 @@ namespace GraphicalUserInterface struct MouseData { - uint32_t X; - uint32_t Y; - uint32_t Z; + int64_t X; + int64_t Y; + int64_t Z; bool Left; bool Right; bool Middle; }; + struct ScreenBitmap + { + int64_t Width; + int64_t Height; + uint64_t Size; + uint64_t Pitch; + uint64_t BitsPerPixel; + uint8_t *Data; + }; + + struct Rect + { + int64_t Left; + int64_t Top; + int64_t Width; + int64_t Height; + + bool Contains(int64_t X, int64_t Y) + { + return (X >= Left && X <= Left + Width && Y >= Top && Y <= Top + Height); + } + + bool Contains(Rect rect) + { + return (rect.Left >= Left && rect.Left + rect.Width <= Left + Width && rect.Top >= Top && rect.Top + rect.Height <= Top + Height); + } + }; + enum CursorType { Visible = 0, @@ -38,101 +67,119 @@ namespace GraphicalUserInterface AppStarting, }; - enum EventType - { - MouseEvent, - KeyboardEvent, - FocusEvent, - WidgetEvent - }; - struct Event { - EventType Type; - Handle Source; - Handle Target; - MouseData Mouse; - MouseData LastMouse; + struct + { + int64_t Width; + int64_t Height; + } Resize; struct { - bool MouseMove; - bool MouseClick; - bool MouseDoubleClick; - bool MouseDown; - bool MouseUp; - bool MouseWheel; - bool MouseEnter; - bool MouseLeave; - bool MouseHover; - bool MouseDrag; - bool MouseDragStart; - bool MouseDragEnd; - bool MouseDragEnter; - bool MouseDragLeave; - bool MouseDragHover; - bool MouseDragDrop; - bool MouseDragDropEnter; - bool MouseDragDropLeave; - bool MouseDragDropHover; - bool MouseDragDropEnd; - bool MouseDragDropStart; - bool MouseDragDropCancel; - bool MouseDragDropComplete; - bool MouseDragDropAbort; - } MouseEventData; + int64_t X; + int64_t Y; + bool Left; + bool Right; + bool Middle; + } MouseDown; struct { - bool KeyDown; - bool KeyUp; - bool KeyPress; - } KeyboardEventData; + int64_t X; + int64_t Y; + bool Left; + bool Right; + bool Middle; + } MouseUp; struct { - bool FocusEnter; - bool FocusLeave; - bool FocusHover; - } FocusEventData; - - struct - { - bool Resize; - bool Move; - bool Show; - bool Hide; - bool Close; - bool Destroy; - bool Paint; - bool PaintBackground; - bool PaintForeground; - bool PaintBorder; - bool PaintShadow; - bool PaintOverlay; - bool PaintAll; - bool PaintChildren; - bool PaintChildrenBackground; - bool PaintChildrenForeground; - bool PaintChildrenBorder; - bool PaintChildrenShadow; - bool PaintChildrenOverlay; - bool PaintChildrenAll; - } WidgetEventData; + int64_t X; + int64_t Y; + bool Left; + bool Right; + bool Middle; + } MouseMove; }; - void PutRect(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height, uint32_t Color); - void PutBorder(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height, uint32_t Color); - void PutBorderWithShadow(uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height, uint32_t Color); + /* + virtual void OnMouseMove(Event *e) {} + virtual void OnMouseClick(Event *e) {} + virtual void OnMouseDoubleClick(Event *e) {} + virtual void OnMouseDown(Event *e) {} + virtual void OnMouseUp(Event *e) {} + virtual void OnMouseWheel(Event *e) {} + virtual void OnMouseEnter(Event *e) {} + virtual void OnMouseLeave(Event *e) {} + virtual void OnMouseHover(Event *e) {} + virtual void OnMouseDrag(Event *e) {} + virtual void OnMouseDragStart(Event *e) {} + virtual void OnMouseDragEnd(Event *e) {} + virtual void OnMouseDragEnter(Event *e) {} + virtual void OnMouseDragLeave(Event *e) {} + virtual void OnMouseDragHover(Event *e) {} + virtual void OnMouseDragDrop(Event *e) {} + virtual void OnMouseDragDropEnter(Event *e) {} + virtual void OnMouseDragDropLeave(Event *e) {} + virtual void OnMouseDragDropHover(Event *e) {} + virtual void OnMouseDragDropEnd(Event *e) {} + virtual void OnMouseDragDropStart(Event *e) {} + virtual void OnMouseDragDropCancel(Event *e) {} + virtual void OnMouseDragDropComplete(Event *e) {} + virtual void OnMouseDragDropAbort(Event *e) {} - class Widget + virtual void OnKeyDown(Event *e) {} + virtual void OnKeyUp(Event *e) {} + virtual void OnKeyPress(Event *e) {} + + virtual void OnFocusEnter(Event *e) {} + virtual void OnFocusLeave(Event *e) {} + virtual void OnFocusHover(Event *e) {} + + virtual void OnResize(Event *e) {} + virtual void OnMinimize(Event *e) {} + virtual void OnMaximize(Event *e) {} + virtual void OnMove(Event *e) {} + virtual void OnShow(Event *e) {} + virtual void OnHide(Event *e) {} + virtual void OnClose(Event *e) {} + virtual void OnDestroy(Event *e) {} + + virtual void OnPaint(Event *e) {} + virtual void OnPaintBackground(Event *e) {} + virtual void OnPaintForeground(Event *e) {} + virtual void OnPaintOverlay(Event *e) {} + virtual void OnPaintAll(Event *e) {} + virtual void OnPaintChildren(Event *e) {} + virtual void OnPaintChildrenBackground(Event *e) {} + virtual void OnPaintChildrenForeground(Event *e) {} + virtual void OnPaintChildrenBorder(Event *e) {} + virtual void OnPaintChildrenShadow(Event *e) {} + virtual void OnPaintChildrenOverlay(Event *e) {} + virtual void OnPaintChildrenAll(Event *e) {} + */ + + void SetPixel(ScreenBitmap *Bitmap, long X, long Y, uint32_t Color); + void DrawOverBitmap(ScreenBitmap *DestinationBitmap, + ScreenBitmap *SourceBitmap, + long Top, + long Left, + bool IgnoreZero = true); + void PutRect(ScreenBitmap *Bitmap, Rect rect, uint32_t Color); + void PutBorder(ScreenBitmap *Bitmap, Rect rect, uint32_t Color); + uint32_t BlendColors(uint32_t c1, uint32_t c2, float t); + void PutBorderWithShadow(ScreenBitmap *Bitmap, Rect rect, uint32_t Color); + void DrawShadow(ScreenBitmap *Bitmap, Rect rect); + void DrawString(ScreenBitmap *Bitmap, Rect rect, const char *Text, uint32_t Color); + + class WidgetCollection { private: Memory::MemMgr *mem; public: - void Paint(); - Handle CreatePanel(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); + Handle CreatePanel(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height); Handle CreateButton(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); Handle CreateLabel(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); Handle CreateTextBox(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); @@ -142,51 +189,128 @@ namespace GraphicalUserInterface Handle CreateListBox(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); Handle CreateProgressBar(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); Handle CreateContextMenu(uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Text); - void HandleEvent(Event *e); - Widget(void /* Window */ *ParentWindow); - ~Widget(); + + WidgetCollection(void /* Window */ *ParentWindow); + ~WidgetCollection(); + + void OnMouseMove(Event *e); + void OnMouseClick(Event *e); + void OnMouseDoubleClick(Event *e); + void OnMouseDown(Event *e); + void OnMouseUp(Event *e); + void OnMouseWheel(Event *e); + void OnMouseEnter(Event *e); + void OnMouseLeave(Event *e); + void OnMouseHover(Event *e); + void OnMouseDrag(Event *e); + void OnMouseDragStart(Event *e); + void OnMouseDragEnd(Event *e); + + void OnKeyDown(Event *e); + void OnKeyUp(Event *e); + void OnKeyPress(Event *e); + + void OnShow(Event *e); + void OnHide(Event *e); + void OnDestroy(Event *e); + + void OnPaint(Event *e); }; class Window { private: Memory::MemMgr *mem; - void *ParentGUI; - long Left, Top, Width, Height; - long Last_Left, Last_Top, Last_Width, Last_Height; + ScreenBitmap *Buffer; + Rect Position; + Rect LastPosition; char Title[256]; - Vector Widgets; + Vector Widgets; + void *ParentGUI; + bool Maximized; bool Minimized; - bool CloseButtonFocused; - bool MaximizeButtonFocused; - bool MinimizeButtonFocused; - bool WindowDragging; - public: - void Close(); - void Maximize(); - void Minimize(); - void HandleEvent(Event *e); - void Paint(); - void AddWidget(Widget *widget); - Window(void *ParentGUI, uint32_t Left, uint32_t Top, uint32_t Width, uint32_t Height, const char *Title); + bool IsMaximized() { return Maximized; } + bool IsMinimized() { return Minimized; } + ScreenBitmap *GetBuffer() { return Buffer; } + Rect GetPosition() { return Position; } + Rect *GetPositionPtr() { return &Position; } + const char *GetTitle() { return (const char *)Title; } + void AddWidget(WidgetCollection *widget); + + Window(void *ParentGUI, Rect rect, const char *Title); ~Window(); + + void OnMouseMove(Event *e); + void OnMouseClick(Event *e); + void OnMouseDoubleClick(Event *e); + void OnMouseDown(Event *e); + void OnMouseUp(Event *e); + void OnMouseWheel(Event *e); + void OnMouseEnter(Event *e); + void OnMouseLeave(Event *e); + void OnMouseHover(Event *e); + void OnMouseDrag(Event *e); + void OnMouseDragStart(Event *e); + void OnMouseDragEnd(Event *e); + + void OnKeyDown(Event *e); + void OnKeyUp(Event *e); + void OnKeyPress(Event *e); + + void OnFocusEnter(Event *e); + void OnFocusLeave(Event *e); + void OnFocusHover(Event *e); + + void OnResize(Event *e); + void OnMinimize(Event *e); + void OnMaximize(Event *e); + void OnMove(Event *e); + void OnShow(Event *e); + void OnHide(Event *e); + void OnClose(Event *e); + void OnDestroy(Event *e); + + void OnPaint(Event *e); + void OnPaintBackground(Event *e); + void OnPaintForeground(Event *e); + void OnPaintOverlay(Event *e); + void OnPaintAll(Event *e); + void OnPaintChildren(Event *e); + void OnPaintChildrenBackground(Event *e); + void OnPaintChildrenForeground(Event *e); + void OnPaintChildrenBorder(Event *e); + void OnPaintChildrenShadow(Event *e); + void OnPaintChildrenOverlay(Event *e); + void OnPaintChildrenAll(Event *e); }; class GUI { private: - MouseData Mouse; - MouseData LastMouse; + MouseData MouseArray[256]; Memory::MemMgr *mem; + Rect Desktop; + ScreenBitmap *BackBuffer; + ScreenBitmap *DesktopBuffer; + ScreenBitmap *OverlayBuffer; + ScreenBitmap *CursorBuffer; + Vector Widgets; Vector Windows; - bool IsRunning; CursorType Cursor = CursorType::Arrow; + CursorType LastCursor = CursorType::Arrow; bool CursorVisible = true; + bool IsRunning = false; + bool DesktopBufferRepaint = true; + bool OverlayBufferRepaint = true; bool OverlayFullRepaint = true; + bool CursorBufferRepaint = true; + + void FetchInputs(); void PaintDesktop(); + void PaintWidgets(); void PaintWindows(); void PaintCursor(); @@ -194,6 +318,7 @@ namespace GraphicalUserInterface void SetCursorType(CursorType Type = CursorType::Visible) { this->Cursor = Type; } void Loop(); void AddWindow(Window *window); + void AddWidget(WidgetCollection *widget); GUI(); ~GUI(); };