Usermode/AxWin4 - Tweak handling of AcessNative (doesn't have SHM and mmap)
[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
13 // === CODE ===
14 namespace AxWin {
15
16 CControl::CControl(int EdgeX, int FillX, int InnerX, int EdgeY, int FillY, int InnerY, ::std::vector<uint32_t>&& data):
17         m_edge_x(EdgeX),
18         m_fill_x(FillX),
19         m_inner_x(InnerX),
20         m_edge_y(EdgeY),
21         m_fill_y(FillY),
22         m_inner_y(InnerY),
23         m_data(data)
24 {
25         
26 }
27
28 void CControl::Render(CSurface& dest, const CRect& rect) const
29 {
30         if( rect.m_w < m_edge_x*2 + m_fill_x*2 + m_inner_x )
31                 return ;
32         if( rect.m_h < m_edge_y*2 + m_fill_y*2 + m_inner_y )
33                 return ;
34         
35         const int ctrl_width = m_edge_x + m_fill_x + m_inner_x + (m_inner_x ? m_fill_x : 0) + m_edge_x;
36         
37         const int top_fill_end = rect.m_h / 2 - m_inner_y;
38         const int bot_fill_start = top_fill_end + m_inner_y;
39         const int bot_fill_end   = rect.m_h - m_edge_y;
40         
41         ::std::vector<uint32_t> scanline( rect.m_w );
42          int    y = 0;
43          int    base_ofs = 0;
44         // EdgeY
45         for( int i = 0; i < m_edge_y; i ++ )
46                 renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
47         base_ofs += m_edge_y;
48         // FillY
49         while( y < top_fill_end )
50         {
51                 for( int i = 0; i < m_fill_y && y < top_fill_end; i ++ )
52                         renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
53         }
54         base_ofs += m_fill_y;
55         // InnerY
56         if( m_inner_y > 0 )
57         {
58                 for( int i = 0; i < m_inner_y; i ++ )
59                         renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
60                 base_ofs += m_inner_y;
61         }
62         else
63         {
64                 base_ofs -= m_fill_x;
65         }
66         // FillY
67         while( y < bot_fill_end )
68         {
69                 for( int i = 0; i < m_fill_y && y < bot_fill_end; i ++ )
70                         renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
71         }
72         base_ofs += m_fill_y;
73         // EdgeY
74         for( int i = 0; i < m_edge_y; i ++ )
75                 renderLine(dest, y++, scanline, rect, &m_data[(base_ofs+i)*ctrl_width]);
76         base_ofs += m_edge_y;
77 }
78
79 void CControl::renderLine(CSurface& dest, int y, ::std::vector<uint32_t>& scanline, const CRect& rect, const uint32_t* ctrl_line) const
80 {
81         const int left_fill_end = rect.m_w / 2 - m_inner_x;
82         const int right_fill_end = rect.m_w - m_edge_x;
83         
84          int    x = 0;
85          int    base_ofs = 0;
86         // EdgeX
87         for( int i = 0; i < m_edge_x; i ++ )
88                 scanline[x++] = ctrl_line[base_ofs + i];
89         base_ofs += m_edge_x;
90         // FillX
91         while( x < left_fill_end )
92         {
93                 for( int i = 0; i < m_fill_x && x < left_fill_end; i ++ )
94                         scanline[x++] = ctrl_line[base_ofs + i];
95         }
96         base_ofs += m_fill_x;
97         // InnerX
98         if( m_inner_x > 0 )
99         {
100                 for( int i = 0; i < m_inner_x; i ++ )
101                         scanline[x++] = ctrl_line[base_ofs + i];
102                 base_ofs += m_inner_x;
103         }
104         else
105         {
106                 base_ofs -= m_fill_x;
107         }
108         // FillX
109         while( x < right_fill_end )
110         {
111                 for( int i = 0; i < m_fill_x && x < right_fill_end; i ++ )
112                         scanline[x++] = ctrl_line[base_ofs + i];
113         }
114         base_ofs += m_fill_x;
115         // EdgeX
116         for( int i = 0; i < m_edge_x; i ++ )
117                 scanline[x++] = ctrl_line[base_ofs + i];
118         base_ofs += m_edge_x;
119         
120         dest.DrawScanline(rect.m_y + y, rect.m_x, rect.m_w, scanline.data());
121 }
122
123 // ---- Standard Controls ---
124 // Standard button control
125 CControl StdButton(2, 1, 0, 2, 1, 0, ::std::vector<uint32_t> {
126         0xC0C0C0, 0xC0C0C0, 0xC0C0C0, 0xC0C0C0, 0xC0C0C0,
127         0xC0C0C0, 0xFFD0D0, 0xFFD0D0, 0xFFD0D0, 0xC0C0C0,
128         0xC0C0C0, 0xFFD0D0, 0xFFD0D0, 0xFFD0D0, 0xC0C0C0,
129         0xC0C0C0, 0xFFD0D0, 0xFFD0D0, 0xFFD0D0, 0xC0C0C0,
130         0xC0C0C0, 0xC0C0C0, 0xC0C0C0, 0xC0C0C0, 0xC0C0C0,
131         });
132
133 // Toolbar
134 CControl StdToolbar(2, 1, 0, 2, 1, 0, ::std::vector<uint32_t> {
135         0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
136         0x000000, 0xA0A0A0, 0x0A0000, 0xA0A0A0, 0x000000,
137         0x000000, 0xA0A0A0, 0xFFFFFF, 0xA0A0A0, 0x000000,
138         0x000000, 0xA0A0A0, 0x0A0000, 0xA0A0A0, 0x000000,
139         0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
140         });
141
142 // Text Area
143 CControl StdText(2, 1, 0, 2, 1, 0, ::std::vector<uint32_t> {
144         0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
145         0x000000, 0xA0A0A0, 0x0A0000, 0xA0A0A0, 0x000000,
146         0x000000, 0xA0A0A0, 0xFFFFFF, 0xA0A0A0, 0x000000,
147         0x000000, 0xA0A0A0, 0x0A0000, 0xA0A0A0, 0x000000,
148         0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
149         });
150
151 const CControl* CControl::GetByName(const ::std::string& name)
152 {
153         if( name == "StdButton" )
154                 return &StdButton;
155         if( name == "StdText" )
156                 return &StdText;
157         // TODO: Use another exception
158         return nullptr;
159 }
160
161 const CControl* CControl::GetByID(uint16_t id)
162 {
163         switch(id)
164         {
165         case AXWIN4_CTL_BUTTON: return &StdButton;
166         case AXWIN4_CTL_TOOLBAR:        return &StdToolbar;
167         case AXWIN4_CTL_TEXTBOX:        return &StdText;
168         default:        return nullptr;
169         }
170 }
171
172 };      // AxWin
173

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