-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsubwindow.d
182 lines (154 loc) · 4.35 KB
/
subwindow.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/**
Interface for subwindows in main enotracker window.
Copyright:
This file is part of enotracker $(LINK https://github.com/epi/enotracker)
Copyright (C) 2014 Adrian Matoga
enotracker is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
enotracker is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with enotracker. If not, see $(LINK http://www.gnu.org/licenses/).
*/
import std.string;
import sdl;
public import sdl: Surface, SDLKey, SDLMod;
class SubWindow
{
this(Surface s, uint x, uint y, uint width, uint height)
{
_surface = s;
_xo = x;
_yo = y;
_width = width;
_height = height;
}
@property bool active() const pure nothrow { return _active; }
@property void active(bool a)
{
_active = a;
draw();
}
@property SubWindow next()
{
if (!_next)
throw new Exception("Next SubWindow not assigned");
return _next;
}
@property void next(SubWindow sw) { _next = sw; }
bool key(SDLKey key, SDLMod mod, wchar unicode) { return false; }
@property uint width() const pure nothrow { return _width; }
@property uint height() const pure nothrow { return _height; }
protected:
abstract void draw();
void text(uint fg, uint bg, uint x, uint y, in char[] t)
{
_surface.lock();
scope(exit) _surface.unlock();
uint sx = (_xo + x) * 8;
uint sy = (_yo + y) * 8;
foreach (char c; t)
{
uint addr = c * 8;
foreach (l; 0 .. 8)
{
ubyte d = _font[addr + l];
foreach (p; 0 .. 8)
{
_surface.putPixel(sx + p, sy + l, (d & 0x80) ? fg : bg);
d <<= 1;
}
}
sx += 8;
}
}
void text(uint fg, uint x, uint y, in char[] t)
{
text(fg, bgcolor, x, y, t);
}
void text(uint x, uint y, in char[] t)
{
text(fgcolor, bgcolor, x, y, t);
}
void textf(A...)(uint fg, uint bg, uint x, uint y, in char[] fmt, A args)
{
text(fg, bg, x, y, format(fmt, args));
}
void textf(A...)(uint fg, uint x, uint y, in char[] fmt, A args)
{
text(fg, bgcolor, x, y, format(fmt, args));
}
void textf(A...)(uint x, uint y, in char[] fmt, A args)
{
text(fgcolor, bgcolor, x, y, format(fmt, args));
}
void box(uint x, uint y, uint w, uint h, uint col)
{
_surface.fillRect(
SDL_Rect(
cast(ushort) ((_xo + x) * 8), cast(ushort) ((_yo + y) * 8),
cast(ushort) (w * 8), cast(ushort) (h * 8)), col);
}
static uint rgbAverage(uint col1, uint col2)
{
return (((col1 ^ col2) & 0xfffefefe) >>> 1) + (col1 & col2);
}
void bar(uint x, uint y, uint vol, uint colbar, uint colbak, uint hshift = 0)
{
enum step = 2;
auto leftX = cast(ushort) ((_xo + x) * 8 + hshift);
auto topY = cast(ushort) ((_yo + y) * 8 - 15 * step);
auto botY = cast(ushort) (topY + 16 * step);
auto barHeight = cast(ushort) (vol * step);
auto remHeight = cast(ushort) ((15 - vol) * step);
uint avgCol = rgbAverage(colbak, colbar);
_surface.fillRect(SDL_Rect(leftX, topY, 8, remHeight), colbak);
for (uint yy = topY + remHeight; yy < botY; yy += 2)
{
_surface.fillRect(SDL_Rect(leftX, cast(ushort) yy, 7, 1), colbar);
_surface.fillRect(SDL_Rect(leftX, cast(ushort) (yy + 1), 7, 1), avgCol);
}
}
void frame(int x, int y, int w, int h, uint col)
{
_surface.lock();
scope(exit) _surface.unlock();
int leftX = (_xo + x) * 8 - 2;
int rightX = (_xo + x + w) * 8 + 1;
if (y >= _topLimit && y < _bottomLimit)
{
foreach (xx; leftX .. rightX)
_surface.putPixel(xx, (_yo + y) * 8 - 2, col);
}
if (y + h >= _topLimit && y + h < _bottomLimit)
{
foreach (xx; leftX .. rightX + 1)
_surface.putPixel(xx, (_yo + y + h) * 8 + 1, col);
}
foreach (yy;
(_yo + (y >= _topLimit ? y : _topLimit)) * 8 - 2 ..
(_yo + (y + h >= _bottomLimit ? _bottomLimit : y + h)) * 8 + 1)
{
_surface.putPixel(leftX, yy, col);
_surface.putPixel(rightX, yy, col);
}
}
uint fgcolor;
uint bgcolor;
protected:
Surface _surface;
uint _xo;
uint _yo;
int _topLimit;
int _bottomLimit;
private:
bool _active;
SubWindow _next;
uint _width;
uint _height;
static _font = cast(immutable(ubyte)[]) import("default.fnt");
}