[C++] 04 FLTK:Fl_Tabs, Fl_Group, Fl_Button

[M1 Mac, Big Sur 11.6.1, FLTK 1.3.8]

自製GUIアプリの移植に本格着手しました。まずはFL_Buttonの格子状配置です。

もっと苦労するかと思いましたが、案外すんなりでした。Java・SwingのGridBagLayoutを使うより断然書きやすいです。ただ日本語ユーザーでFLTKを使っている方はネットではほとんど見かけず、少ない英語情報を参考に基本的には自分でマニュアルを読みながら進めていくという形になります。

FL_Buttonのconst char*型引数を作成する所で配列の要素をそのまま渡すと配列の最後の文字列が全てのボタンに表示されてしまうというトラブルがありましたが、要素のポインタを渡すと各々の文字列が問題なく表示されました。ポインタはしばらく扱っていなかったので慣れるまで少し時間がかかりそうです。

移植開始前、C/C++とJavaは似ても似つかぬ言語だという印象でした。書き進めていくとFor文の書き方や配列からの値の取り出し方などC/C++がJavaにかなりの影響を与えているところが垣間見え、徐々に親しみが湧いてきました。

ネットにてC言語の様々な自作関数を目にしますが、実はC++では正式な関数として用意されているといったケースが多々あり、余計な遠回りをしないよう注意を払う必要があります。

今回は危うくsubstr関数を自製しようとしましたし、16進数の文字列を数値に変換する際、C++11から採用のstoiを使わずにatoiで処理しかけました。C言語専門あるいはC++11以降を知らない方も多くいらっしゃるようです。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Widget.H>

using std::cout; using std::cin;
using std::endl; using std::string;
using std::vector; using std::stoi;

int main(int argc, char **argv) {
    Fl_Window *window = new Fl_Window(50,50,660,480);

    <色名などの配列は省略>

    Fl_Tabs *tabs = new Fl_Tabs(10,10,400,480);
    {
        for (auto &i : tab_names) {
            string tab_name = i;
            const char* tab_name_p = i.c_str();
            Fl_Group *grp = new Fl_Group(30,30,380,440,tab_name_p);{
                int num = 0;
                grp->labelsize(10);
                for (int x = 0; x < 5; x++){
                    int loc_x = x * 75 + 23;
                    for (int y = 0; y < 28; y++){
                        int loc_y = y * 15 + 43;

                        string* color_name_p = &(color_names[num]);
                        const char* color_name_p2 = color_name_p->c_str();

                        string color_code = color_codes[num];
                        string red0 = color_code.substr(2,2);
                        int red = stoi(red0, nullptr, 16);
                        
                        string green0 = color_code.substr(4,2);
                        int green = stoi(green0, nullptr, 16);

                        string blue0 = color_code.substr(6,2);
                        int blue = stoi(blue0, nullptr, 16);

                        Fl_Button *button = new Fl_Button(loc_x, loc_y, 75, 15,color_name_p2);
                        button->color(fl_rgb_color(red,green,blue));
                        button->labelcolor(fl_rgb_color(169,169,169));
                        button->labelsize(8);
                        num = num + 1;
                    }
                } 
            }
            grp->end();
        }
    }
    tabs->end();
    
    window->end();
    window->show(argc, argv);
    return Fl::run();
}