-
-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathwidget.hpp
669 lines (552 loc) · 23.5 KB
/
widget.hpp
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
#pragma once
//=====================================================================//
/*! @file
@brief Widget クラス
@author 平松邦仁 ([email protected])
@copyright Copyright (C) 2019, 2022 Kunihito Hiramatsu @n
Released under the MIT license @n
https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/vtx.hpp"
#include "graphics/color.hpp"
// #include "common/file_io.hpp"
namespace gui {
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
@brief Widget クラス
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
struct widget {
typedef graphics::def_color DEF_COLOR; ///< 標準カラー
static constexpr int16_t DEF_FRAME_ROUND_RADIUS = 6; ///< 標準、フレーム、コーナーの半径
static constexpr int16_t DEF_FRAME_FRAME_WIDTH = 2; ///< 標準、フレーム、外周のフレーム幅
static constexpr int16_t DEF_DIALOG_ROUND_RADIUS = 6; ///< 標準、ダイアログ、コーナーの半径
static constexpr int16_t DEF_DIALOG_FRAME_WIDTH = 2; ///< 標準、ダイアログ、外周のフレーム幅
static constexpr int16_t DEF_BUTTON_ROUND_RADIUS = 6; ///< 標準、ボタン、コーナーの半径
static constexpr int16_t DEF_BUTTON_FRAME_WIDTH = 3; ///< 標準、ボタン、外周のフレーム幅
static constexpr int16_t DEF_BUTTON_HEIGHT = 30; ///< 標準、ボタン、サイズが省略された場合の高さ
static constexpr int16_t DEF_BUTTON_TO_STR = 4; ///< 標準、ボタン、フレームからタイトルまでの距離
static constexpr int16_t DEF_SLIDER_ROUND_RADIUS = 10; ///< 標準、スライダー、コーナーの半径
static constexpr int16_t DEF_SLIDER_FRAME_WIDTH = 3; ///< 標準、スライダー、外周のフレーム幅
static constexpr int16_t DEF_SLIDER_HANDLE_SIZE = 20; ///< 標準、スライダー、ハンドルの大きさ
static constexpr int16_t DEF_MENU_ROUND_RADIUS = 6; ///< 標準、メニュー、コーナー半径
static constexpr int16_t DEF_MENU_HEIGHT = 28; ///< 標準、メニュー、アイテムの高さ
static constexpr int16_t DEF_MENU_SIGN_SPACE = 5; ///< 標準、メニュー、サインまでの隙間
static constexpr int16_t DEF_MENU_SIGN_SIZE = 6; ///< 標準、メニュー、サインの大きさ
static constexpr int16_t DEF_CHECK_ROUND_RADIUS = 2; ///< 標準、チェックボックス、コーナー半径
static constexpr int16_t DEF_CHECK_FRAME_WIDTH = 3; ///< 標準、チェックボックス、外周フレーム幅
static constexpr int16_t DEF_CHECK_BOX_SIZE = 22; ///< 標準、チェックボックス、大きさ
static constexpr int16_t DEF_CHECK_SPACE = 4; ///< 標準、チェックボックス、有効アイテムの隙間
static constexpr int16_t DEF_CHECK_TO_STR = 5; ///< 標準、チェックボックス、文字までの隙間
static constexpr int16_t DEF_RADIO_FRAME_WIDTH = 3; ///< 標準、ラジオボタン、外周フレーム幅
static constexpr int16_t DEF_RADIO_BOX = 22; ///< 標準、ラジオボタン、大きさ
static constexpr int16_t DEF_RADIO_SPACE = 4; ///< 標準、ラジオボタン、有効アイテムの隙間
static constexpr int16_t DEF_RADIO_TO_STR = 5; ///< 標準、ラジオボタン、文字までの隙間
static constexpr int16_t DEF_SPINBOX_ROUND_RADIUS = 6; ///< 標準、スピンボックス、コーナー半径
static constexpr int16_t DEF_SPINBOX_FRAME_WIDTH = 2; ///< 標準、スピンボックス、外周フレーム幅
static constexpr int16_t DEF_SPINBOX_HEIGHT = 30; ///< 標準、スピンボックス、サイズが省略された場合の高さ
static constexpr int16_t DEF_SPINBOX_ARROW_SPACE = 2; ///< 標準、スピンボックス、矢印までの隙間
static constexpr int16_t DEF_SPINBOX_ARROW_W = 5; ///< 標準、スピンボックス、矢印の幅
static constexpr int16_t DEF_SPINBOX_ARROW_H = 8; ///< 標準、スピンボックス、矢印の高さ
static constexpr int16_t DEF_SPINBOXT_ROUND_RADIUS = 6; ///< 標準、スピンボックスT、コーナー半径
static constexpr int16_t DEF_SPINBOXT_FRAME_WIDTH = 2; ///< 標準、スピンボックスT、外周フレーム幅
static constexpr int16_t DEF_SPINBOXT_HEIGHT = 30; ///< 標準、スピンボックスT、サイズが省略された場合の高さ
static constexpr int16_t DEF_SPINBOXT_ARROW_SPACE = 2; ///< 標準、スピンボックスT、矢印までの隙間
static constexpr int16_t DEF_SPINBOXT_ARROW_W = 5; ///< 標準、スピンボックスT、矢印の幅
static constexpr int16_t DEF_SPINBOXT_ARROW_H = 8; ///< 標準、スピンボックスT、矢印の高さ
static constexpr int16_t DEF_TOGGLE_WIDTH = 58; ///< 標準、トグルスイッチ、横幅
static constexpr int16_t DEF_TOGGLE_HEIGHT = 29; ///< 標準、トグルスイッチ、サイズが省略された場合の高さ
static constexpr int16_t DEF_TOGGLE_FRAME_WIDTH = 2; ///< 標準、トグルスイッチ、外周フレーム幅
static constexpr int16_t DEF_PROGRESS_HEIGHT = 24; ///< 標準、プログレスバー、サイズが省略された場合の高さ
static constexpr int16_t DEF_PROGRESS_FRAME_WIDTH = 2; ///< 標準、プログレスバー、フレーム幅
static constexpr int16_t DEF_FILER_HEIGHT = 20; ///< 標準、ファイラー、アイテムの高さ
static constexpr int16_t DEF_FILER_DRAG_TH = 10; ///< 標準、ファイラー、ドラッグ開始のスレッショルド幅
static constexpr uint16_t DEF_FILER_LOOP = 2; ///< 標準、1フレームに取得するファイル情報数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
@brief レイヤー型(最大8つ)
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
enum class LAYER : uint8_t {
_0, ///< レイヤー0
_1, ///< レイヤー1
_2, ///< レイヤー2
_3, ///< レイヤー3
_4, ///< レイヤー4
_5, ///< レイヤー5
_6, ///< レイヤー6
_7 ///< レイヤー7
};
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
@brief widget ID
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
enum class ID : uint8_t {
GROUP, ///< グループ
FRAME, ///< フレーム
BOX, ///< ボックス(シンプルな単型)
TEXT, ///< テキスト
TEXTBOX, ///< テキスト・ボックス
DIALOG, ///< ダイアログ
BUTTON, ///< ボタン
CHECK, ///< チェック・ボタン
RADIO, ///< ラジオ・ボタン
SLIDER, ///< スライダー
MENU, ///< メニュー
TERM, ///< ターミナル
SPINBOX, ///< スピンボックス
SPINBOXT, ///< スピンボックス・テキスト
TOGGLE, ///< トグルスイッチ
PROGRESS, ///< プログレスバー
CLOSEBOX, ///< クローズボックス
FILER, ///< ファイラー
KEY_ASC, ///< ASCII ソフトキーボード
KEY_10, ///< 10ソフトキーボード
};
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
@brief ステート
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
enum class STATE : uint8_t {
DISABLE, ///< 無効状態(表示されない)
ENABLE, ///< 有効
STALL, ///< 表示されているが、ストール状態
};
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
@brief タッチ・ステート
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
struct touch_state {
vtx::spos position_; ///< タッチしている絶対位置
vtx::spos relative_; ///< タッチしている相対位置
vtx::spos expand_; ///< フォーカス拡張領域
bool positive_; ///< タッチした瞬間「true」になる
bool level_; ///< タッチしている間「true」になる
bool negative_; ///< 離した瞬間「true」になる
touch_state(const vtx::spos& fexp = vtx::spos(4)) noexcept :
position_(-1), expand_(fexp),
positive_(false), level_(false), negative_(false) { }
};
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
@brief 水平配置型
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
enum class H_ALIGNMENT : uint8_t {
LEFT, ///< 左寄せ
CENTER, ///< 中央
RIGHT, ///< 右寄せ
};
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
@brief 垂直配置型
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
enum class V_ALIGNMENT : uint8_t {
TOP, ///< 上寄せ
CENTER, ///< 中央
BOTTOM, ///< 下寄せ
};
static constexpr int16_t SIZE_AUTO = 0; ///< 自動で最適なサイズをロードする。
private:
widget* parents_; ///< 親
widget* next_; ///< リンク
vtx::srect location_; ///< 位置とサイズ
const char* title_; ///< タイトル
const void* mobj_; ///< モーションオブジェクト(ビットマップ表示)
graphics::share_color base_color_; ///< GUI 基本色
graphics::share_color font_color_; ///< フォント基本色
STATE state_;
bool focus_;
bool touch_;
touch_state touch_state_;
bool update_;
uint8_t exec_request_;
uint8_t layer_;
public:
//-----------------------------------------------------------------//
/*!
@brief コンストラクター
@param[in] loc ロケーション
@param[in] title タイトル
@param[in] fexp フォーカス拡張領域
*/
//-----------------------------------------------------------------//
widget(const vtx::srect& loc = vtx::srect(0), const char* title = nullptr, const vtx::spos& fexp = vtx::spos(0)) noexcept :
parents_(nullptr), next_(nullptr),
location_(loc), title_(title), mobj_(nullptr),
base_color_(graphics::def_color::White), font_color_(graphics::def_color::White),
state_(STATE::DISABLE), focus_(false), touch_(false),
touch_state_(fexp), update_(false),
exec_request_(0), layer_(0)
{ }
//-----------------------------------------------------------------//
/*!
@brief widget 名称の取得
@return widget 名称
*/
//-----------------------------------------------------------------//
virtual const char* get_name() const = 0;
//-----------------------------------------------------------------//
/*!
@brief ID を取得
@return ID
*/
//-----------------------------------------------------------------//
virtual ID get_id() const = 0;
//-----------------------------------------------------------------//
/*!
@brief ハイブリッド・タイプか検査
@return ハイブリッドの場合「true」
*/
//-----------------------------------------------------------------//
virtual bool hybrid() const noexcept { return false; }
//-----------------------------------------------------------------//
/*!
@brief 初期化 @n
GUI が有効になった場合に実行される
*/
//-----------------------------------------------------------------//
virtual void init() = 0;
//-----------------------------------------------------------------//
/*!
@brief タッチ判定を更新(通常毎フレーム呼ばれる)
@param[in] pos 判定位置
@param[in] num タッチ数
*/
//-----------------------------------------------------------------//
virtual void update_touch(const vtx::spos& pos, uint16_t num) = 0;
//-----------------------------------------------------------------//
/*!
@brief 選択推移 @n
状態の変化が起きた場合に呼び出される。
*/
//-----------------------------------------------------------------//
virtual void exec_select() = 0;
//-----------------------------------------------------------------//
/*!
@brief 許可・不許可
@param[in] ena 不許可の場合「false」
*/
//-----------------------------------------------------------------//
virtual void enable(bool ena = true) = 0;
//-----------------------------------------------------------------//
/*!
@brief プロパティのセーブ
@param[in] fio ファイル I/O コンテキスト
@return 成功なら「true」
*/
//-----------------------------------------------------------------//
// virtual bool save(utils::file_io& fio) { return false; }
//-----------------------------------------------------------------//
/*!
@brief プロパティのロード
@param[in] fio ファイル I/O コンテキスト
@return 成功なら「true」
*/
//-----------------------------------------------------------------//
// virtual bool load(utils::file_io& fio) { return false; }
//-----------------------------------------------------------------//
/*!
@brief 親を設定
@param[in] w 親 widget
*/
//-----------------------------------------------------------------//
void set_parents(widget* w) noexcept { parents_ = w; }
//-----------------------------------------------------------------//
/*!
@brief 親 widget を返す
@return 親 widget
*/
//-----------------------------------------------------------------//
widget* get_parents() const noexcept { return parents_; }
//-----------------------------------------------------------------//
/*!
@brief 次接続設定
@param[in] w 親 widget
*/
//-----------------------------------------------------------------//
void set_next(widget* w) noexcept { next_ = w; }
//-----------------------------------------------------------------//
/*!
@brief 次接続 widget を返す
@return 次接続 widget
*/
//-----------------------------------------------------------------//
widget* get_next() const noexcept { return next_; }
//-----------------------------------------------------------------//
/*!
@brief ロケーションの取得
@return ロケーション
*/
//-----------------------------------------------------------------//
const vtx::srect& get_location() const noexcept { return location_; }
//-----------------------------------------------------------------//
/*!
@brief ロケーションの参照
@return ロケーション
*/
//-----------------------------------------------------------------//
vtx::srect& at_location() noexcept { return location_; }
//-----------------------------------------------------------------//
/*!
@brief タイトルの設定
@param[in] title タイトル
*/
//-----------------------------------------------------------------//
void set_title(const char* title) noexcept { title_ = title; }
//-----------------------------------------------------------------//
/*!
@brief タイトルの取得
@return タイトル
*/
//-----------------------------------------------------------------//
const char* get_title() const noexcept { return title_; }
//-----------------------------------------------------------------//
/*!
@brief タイトル更新前処理
*/
//-----------------------------------------------------------------//
virtual void update_title() noexcept { }
//-----------------------------------------------------------------//
/*!
@brief モーションオブジェクトの設定
@param[in] mobj モーションオブジェクト
*/
//-----------------------------------------------------------------//
void set_mobj(const void* mobj) noexcept {
mobj_ = mobj;
set_update();
}
//-----------------------------------------------------------------//
/*!
@brief モーションオブジェクトの取得
@return モーションオブジェクト
*/
//-----------------------------------------------------------------//
const void* get_mobj() const noexcept { return mobj_; }
//-----------------------------------------------------------------//
/*!
@brief ベースカラーの設定
@param[in] color カラー
*/
//-----------------------------------------------------------------//
void set_base_color(const graphics::share_color& color) noexcept {
base_color_ = color;
set_update();
}
//-----------------------------------------------------------------//
/*!
@brief ベースカラーの取得
@return ベースカラー
*/
//-----------------------------------------------------------------//
auto get_base_color() const noexcept {
if(state_ == STATE::STALL) {
graphics::share_color sh(0, 0, 0);
sh.set_color(base_color_.rgba8, 96);
return sh;
} else {
return base_color_;
}
}
//-----------------------------------------------------------------//
/*!
@brief フォントカラーの設定
@param[in] color カラー
*/
//-----------------------------------------------------------------//
void set_font_color(const graphics::share_color& color) noexcept {
font_color_ = color;
set_update();
}
//-----------------------------------------------------------------//
/*!
@brief フォントカラーの取得
@return フォントカラー
*/
//-----------------------------------------------------------------//
auto get_font_color() const noexcept
{
if(state_ == STATE::STALL) {
graphics::share_color sh(0, 0, 0);
sh.set_color(font_color_.rgba8, 96);
return sh;
} else {
return font_color_;
}
}
//-----------------------------------------------------------------//
/*!
@brief 「更新」の設定
@param[in] update 更新をしない場合「false」
*/
//-----------------------------------------------------------------//
void set_update(bool update = true) noexcept { update_ = update; }
//-----------------------------------------------------------------//
/*!
@brief 「更新」の取得
@return 「更新」
*/
//-----------------------------------------------------------------//
auto get_update() const noexcept { return update_; }
//-----------------------------------------------------------------//
/*!
@brief レイヤーの設定
@param[in] layer レイヤー
*/
//-----------------------------------------------------------------//
void set_layer(LAYER layer) noexcept { layer_ = 1 << static_cast<uint8_t>(layer); }
//-----------------------------------------------------------------//
/*!
@brief レイヤービットの取得
@return レイヤー
*/
//-----------------------------------------------------------------//
auto get_layer_bits() const noexcept { return layer_; }
//-----------------------------------------------------------------//
/*!
@brief ステートの設定
@param[in] state ステート
*/
//-----------------------------------------------------------------//
void set_state(STATE state) noexcept { state_ = state; }
//-----------------------------------------------------------------//
/*!
@brief ステートの取得
@return ステート
*/
//-----------------------------------------------------------------//
auto get_state() const noexcept { return state_; }
//-----------------------------------------------------------------//
/*!
@brief フォーカスを取得
@return フォーカス
*/
//-----------------------------------------------------------------//
bool get_focus() const noexcept { return focus_; }
//-----------------------------------------------------------------//
/*!
@brief タッチ・ステートを取得
@return タッチ・ステート
*/
//-----------------------------------------------------------------//
const auto& get_touch_state() const noexcept { return touch_state_; }
//-----------------------------------------------------------------//
/*!
@brief タッチステートをリセット
*/
//-----------------------------------------------------------------//
void reset_touch_state() noexcept
{
touch_state_.positive_ = false;
touch_state_.negative_ = false;
touch_state_.level_ = false;
}
//-----------------------------------------------------------------//
/*!
@brief 標準的なタッチ判定更新
@param[in] pos 判定位置
@param[in] num タッチ数
@param[in] exp タッチ領域拡張を行わない場合「false」
*/
//-----------------------------------------------------------------//
void update_touch_def(const vtx::spos& pos, uint16_t num, bool exp = true) noexcept
{
auto loc = vtx::srect(get_final_position(), location_.size);
if(exp) {
loc.org -= touch_state_.expand_;
loc.size += touch_state_.expand_;
}
focus_ = loc.is_focus(pos);
if(focus_) {
if(num > 0) {
touch_ = true;
touch_state_.position_ = pos;
touch_state_.relative_ = pos - loc.org;
} else {
touch_ = false;
touch_state_.position_.set(-1);
}
auto level = touch_;
touch_state_.positive_ = ( level && !touch_state_.level_);
touch_state_.negative_ = (!level && touch_state_.level_);
touch_state_.level_ = level;
} else {
touch_state_.positive_ = false;
touch_state_.negative_ = false;
touch_state_.level_ = false;
}
}
//-----------------------------------------------------------------//
/*!
@brief タッチ判定を更新(スライダー用)@n
・スライダーの操作性を良くする為の工夫をする。@n
・タッチしたまま、左右、上下にドラッグして、スライダー @n
のフォーカスを外れた場合、操作が中断してしまうのを改善する。
@param[in] pos 判定位置
@param[in] num タッチ数
*/
//-----------------------------------------------------------------//
void update_touch_slider(const vtx::spos& pos, uint16_t num) noexcept
{
if(num == 0) {
focus_ = false;
touch_ = false;
touch_state_.position_.set(-1);
touch_state_.positive_ = false;
touch_state_.negative_ = touch_state_.level_;
touch_state_.level_ = false;
return;
}
auto loc = vtx::srect(get_final_position(), location_.size);
loc.org -= touch_state_.expand_;
loc.size += touch_state_.expand_;
bool focus = loc.is_focus(pos);
if(!focus_ && focus) {
touch_ = true;
}
focus_ = focus;
touch_state_.position_ = pos;
auto level = touch_;
touch_state_.positive_ = ( level && !touch_state_.level_);
touch_state_.negative_ = (!level && touch_state_.level_);
touch_state_.level_ = level;
}
//-----------------------------------------------------------------//
/*!
@brief 最終位置を取得
@return 最終位置
*/
//-----------------------------------------------------------------//
vtx::spos get_final_position() const noexcept
{
auto pos = location_.org;
widget* w = parents_;
while(w != nullptr) {
pos += w->get_location().org;
w = w->get_parents();
}
return pos;
}
//-----------------------------------------------------------------//
/*!
@brief 動作リクエストを取得
@return 動作リクエスト
*/
//-----------------------------------------------------------------//
auto get_exec_request() const noexcept { return exec_request_; }
//-----------------------------------------------------------------//
/*!
@brief 動作リクエストを発行
*/
//-----------------------------------------------------------------//
void set_exec_request() noexcept { ++exec_request_; }
};
}
extern bool insert_widget(gui::widget* w); ///< widget インサートのグローバル関数型
extern void remove_widget(gui::widget* w); ///< widget リムーブのグローバル関数型