Usermode/AxWin4 - Debugging quirks in ARCH=native
[tpg/acess2.git] / Usermode / Applications / axwin4_src / Server / draw_control.cpp
1 /*
2  * Acess2 GUI v4
3  * - By John Hodge (thePowersGang)
4  *
5  * draw_control.cpp
6  * - Common "Control" Drawing
7  *
8  * Handles drawing of resizable controls defined by a bitmap and four region sizes
9  */
10 #include <draw_control.hpp>
11 #include <axwin4/definitions.h>
12 #include <acess/sys.h>
13 #include <cassert>
14
15 // === CODE ===
16 namespace AxWin {
17
18 CControl::CControl(int EdgeX, int FillX, int InnerX, int EdgeY, int FillY, int InnerY, ::std::vector<uint32_t>&& data):
19         m_edge_x(EdgeX),
20         m_fill_x(FillX),
21         m_inner_x(InnerX),
22         m_edge_y(EdgeY),
23         m_fill_y(FillY),
24         m_inner_y(InnerY),
25         m_data(data)
26 {
27         _SysDebug("CControl(X={E:%i,F:%i,I:%i}, Y={E:%i,F:%i,I:%i}, data={Size:%i})",
28                 m_edge_x, m_fill_x, m_inner_x, m_edge_y, m_fill_y, m_inner_y, m_data.size());
29 }
30
31 void CControl::Render(CSurface& dest, const CRect& rect) const
32 {
33         if( rect.m_w < m_edge_x*2 + m_fill_x*2 + m_inner_x )
34                 return ;
35         if( rect.m_h < m_edge_y*2 + m_fill_y*2 + m_inner_y )
36                 return ;
37         
38         const int ctrl_width = m_edge_x + m_fill_x + m_inner_x + (m_inner_x ? m_fill_x : 0) + m_edge_x;
39         
40         const int top_fill_end = rect.m_h / 2 - m_inner_y;
41         const int bot_fill_start = top_fill_end + m_inner_y;
42         const int bot_fill_end   = rect.m_h - m_edge_y;
43         
44         ::std::vector<uint32_t> scanline( rect.m_w );
45          int    y = 0;
46          int    base_ofs = 0;
47         // EdgeY
48         for( int i = 0; i < m_edge_y; i ++ )
49                 renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
50         base_ofs += m_edge_y;
51         // FillY
52         assert(m_fill_y > 0 || y == top_fill_end);
53         while( y < top_fill_end )
54         {
55                 for( int i = 0; i < m_fill_y && y < top_fill_end; i ++ )
56                         renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
57         }
58         base_ofs += m_fill_y;
59         // InnerY
60         if( m_inner_y > 0 )
61         {
62                 for( int i = 0; i < m_inner_y; i ++ )
63                         renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
64                 base_ofs += m_inner_y;
65         }
66         else
67         {
68                 base_ofs -= m_fill_x;
69         }
70         // FillY
71         while( y < bot_fill_end )
72         {
73                 for( int i = 0; i < m_fill_y && y < bot_fill_end; i ++ )
74                         renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
75         }
76         base_ofs += m_fill_y;
77         // EdgeY
78         for( int i = 0; i < m_edge_y; i ++ )
79                 renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
80         base_ofs += m_edge_y;
81 }
82
83 void CControl::renderLine(CSurface& dest, int y, ::std::vector<uint32_t>& scanline, const CRect& rect, const uint32_t* ctrl_line) const
84 {
85         _SysDebug("renderLine: (y=%i,rect={(%i,%i)  %ix%i}", y, rect.m_x, rect.m_y, rect.m_w, rect.m_h);
86         const int left_fill_end = rect.m_w / 2 - m_inner_x;
87         const int right_fill_end = rect.m_w - m_edge_x;
88         
89          int    x = 0;
90          int    base_ofs = 0;
91         // EdgeX
92         for( int i = 0; i < m_edge_x; i ++ )
93                 scanline[x++] = ctrl_line[base_ofs + i];
94         base_ofs += m_edge_x;
95         // FillX
96         while( x < left_fill_end )
97         {
98                 for( int i = 0; i < m_fill_x && x < left_fill_end; i ++ )
99                         scanline[x++] = ctrl_line[base_ofs + i];
100         }
101         base_ofs += m_fill_x;
102         // InnerX
103         if( m_inner_x > 0 )
104         {
105                 for( int i = 0; i < m_inner_x; i ++ )
106                         scanline[x++] = ctrl_line[base_ofs + i];
107                 base_ofs += m_inner_x;
108         }
109         else
110         {
111                 base_ofs -= m_fill_x;
112         }
113         // FillX
114         while( x < right_fill_end )
115         {
116                 for( int i = 0; i < m_fill_x && x < right_fill_end; i ++ )
117                         scanline[x++] = ctrl_line[base_ofs + i];
118         }
119         base_ofs += m_fill_x;
120         // EdgeX
121         for( int i = 0; i < m_edge_x; i ++ )
122                 scanline[x++] = ctrl_line[base_ofs + i];
123         base_ofs += m_edge_x;
124         
125         dest.DrawScanline(rect.m_y + y, rect.m_x, rect.m_w, scanline.data());
126 }
127
128 // ---- Standard Controls ---
129 // Standard button control
130 CControl StdButton(2, 1, 0, 2, 1, 0, ::std::vector<uint32_t> {
131         0xC0C0C0, 0xC0C0C0, 0xC0C0C0, 0xC0C0C0, 0xC0C0C0,
132         0xC0C0C0, 0xFFD0D0, 0xFFD0D0, 0xFFD0D0, 0xC0C0C0,
133         0xC0C0C0, 0xFFD0D0, 0xFFD0D0, 0xFFD0D0, 0xC0C0C0,
134         0xC0C0C0, 0xFFD0D0, 0xFFD0D0, 0xFFD0D0, 0xC0C0C0,
135         0xC0C0C0, 0xC0C0C0, 0xC0C0C0, 0xC0C0C0, 0xC0C0C0,
136         });
137
138 // Toolbar
139 CControl StdToolbar(2, 1, 0, 2, 1, 0, ::std::vector<uint32_t> {
140         0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
141         0x000000, 0xA0A0A0, 0x0A0000, 0xA0A0A0, 0x000000,
142         0x000000, 0xA0A0A0, 0xFFFFFF, 0xA0A0A0, 0x000000,
143         0x000000, 0xA0A0A0, 0x0A0000, 0xA0A0A0, 0x000000,
144         0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
145         });
146
147 // Text Area
148 CControl StdText(2, 1, 0, 2, 1, 0, ::std::vector<uint32_t> {
149         0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
150         0x000000, 0xA0A0A0, 0x0A0000, 0xA0A0A0, 0x000000,
151         0x000000, 0xA0A0A0, 0xFFFFFF, 0xA0A0A0, 0x000000,
152         0x000000, 0xA0A0A0, 0x0A0000, 0xA0A0A0, 0x000000,
153         0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
154         });
155
156 const CControl* CControl::GetByName(const ::std::string& name)
157 {
158         if( name == "StdButton" )
159                 return &StdButton;
160         if( name == "StdText" )
161                 return &StdText;
162         // TODO: Use another exception
163         return nullptr;
164 }
165
166 const CControl* CControl::GetByID(uint16_t id)
167 {
168         switch(id)
169         {
170         case AXWIN4_CTL_BUTTON: return &StdButton;
171         case AXWIN4_CTL_TOOLBAR:        return &StdToolbar;
172         case AXWIN4_CTL_TEXTBOX:        return &StdText;
173         default:        return nullptr;
174         }
175 }
176
177 };      // AxWin
178

UCC git Repository :: git.ucc.asn.au