...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

DFL: コントロールの左寄せ・センタリング・右寄せのサンプルコード

コントロールの配置を簡単に設定するために、ControlクラスにlocationAlignmentプロパティを追加しました。

先日作成したStackPanelと一緒に使うと便利です。

ちなみに、WinformsだとAnchorというのがあって、DFLのlocationAlignmentはそれに近いものですが、少し挙動が異なるので名前も変えています。

WinFormsのAnchorの場合

指定した方向について、親コントロールの端までの距離を一定に保ちます。

DFLのLocationAlignmentの場合

単純に、MS Excelの左寄せ・センタリング・右寄せです。

DFLでは、dockPaddingプロパティで親コントロールの端までの距離(パディング)を設定でき、 dockMarginプロパティでコントロール間の距離(マージン)を設定できるので、 locationAlignmentはパディングとマージンを残して寄せるようにしています。

dockStyleとlocationAlignmentは、同時に使うことはできません。 後で指定した方だけが有効になります。

指定できる配置は、中央と、上下左右に斜めを加えたの8方向で、合わせて9種類あります。

enum LocationAlignment: ubyte
{
    NONE, /// 指定なし
    TOP_LEFT, /// 左上寄せ
    BOTTOM_CENTER, /// 下寄せ・左右センタリング
    BOTTOM_LEFT, /// 下左寄せ
    BOTTOM_RIGHT, /// 下右寄せ
    MIDDLE_CENTER, /// 上下左右センタリング
    MIDDLE_LEFT, /// 上下センタリング・左寄せ
    MIDDLE_RIGHT, /// 上下センタリング・右寄せ
    TOP_CENTER, /// 上寄せ・左右センタリング
    TOP_RIGHT, /// 右上寄せ
}

サンプルコード

import dfl;

class MainForm : Form
{
    private StackPanel _contentPanel;
    private Panel[] _configPanels;

    private enum DEFAULT_PANEL_SIZE = Size(240, 80);

    this()
    {
        this.text = "LocationAlignment example";
        this.size = Size(1200, 500);
        this.minimumSize = Size(400, 400);

        _contentPanel = new StackPanel;
        _contentPanel.orientation = Orientation.VERTICAL;
        _contentPanel.dock = DockStyle.FILL;
        _contentPanel.dockPadding.all = 10;
        _contentPanel.parent = this;

        _configPanels ~= createSwitchConfigPanel("Top Left Label");
        _configPanels ~= createSwitchConfigPanel("Top Left Label");
        _configPanels ~= createComboBoxConfigPanel("Middle Center Label", ["Option 1", "Option 2", "Option 3", "Option 4", "Option 5"]);
        _configPanels ~= createButtonConfigPanel("Bottom Center Label", "Rotate", &rotateOrientaion);

        foreach (panel; _configPanels)
            _contentPanel.add(panel);
    }

    static Panel createSwitchConfigPanel(string name)
    {
        Panel p = new Panel;
        p.backColor = SystemColors.controlLightLight;
        p.borderStyle = BorderStyle.FIXED_SINGLE;
        p.dockPadding.all = 10;
        p.dockMargin.right = 10;
        p.dockMargin.bottom = 10;
        p.size = DEFAULT_PANEL_SIZE;

        Label label = new Label;
        label.text = name;
        label.autoSize = true;
        label.locationAlignment = LocationAlignment.TOP_LEFT;
        label.parent = p;

        ToggleSwitch sw = new ToggleSwitch;
        sw.width = 100;
        sw.height = 50;
        sw.locationAlignment = LocationAlignment.MIDDLE_RIGHT;
        sw.parent = p;

        return p;
    }

    static Panel createComboBoxConfigPanel(string name, string[] items)
    {
        Panel p = new Panel;
        p.backColor = SystemColors.controlLightLight;
        p.borderStyle = BorderStyle.FIXED_SINGLE;
        p.dockPadding.all = 10;
        p.dockMargin.right = 10;
        p.dockMargin.bottom = 10;
        p.size = DEFAULT_PANEL_SIZE;

        Label label = new Label;
        label.text = name;
        label.autoSize = true;
        label.locationAlignment = LocationAlignment.TOP_CENTER;
        label.parent = p;

        ComboBox cb = new ComboBox;
        cb.dropDownStyle = ComboBoxStyle.DROP_DOWN_LIST;
        cb.width = 120;
        cb.locationAlignment = LocationAlignment.MIDDLE_RIGHT;
        cb.items.addRange(items);
        cb.text = items[0]; // initial selected item text
        cb.selectedIndex = 0; // initial selected item
        cb.parent = p;

        return p;
    }

    static Panel createButtonConfigPanel(string name, string text, void delegate(Control, EventArgs) clickEvent)
    {
        Panel p = new Panel;
        p.backColor = SystemColors.controlLightLight;
        p.borderStyle = BorderStyle.FIXED_SINGLE;
        p.dockPadding.all = 10;
        p.dockMargin.right = 10;
        p.dockMargin.bottom = 10;
        p.size = DEFAULT_PANEL_SIZE;

        Label label = new Label;
        label.text = name;
        label.autoSize = true;
        label.locationAlignment = LocationAlignment.BOTTOM_CENTER;
        label.parent = p;

        Button b = new Button;
        b.text = text;
        b.width = 120;
        b.height = 60;
        b.locationAlignment = LocationAlignment.MIDDLE_RIGHT;
        b.click ~= clickEvent;
        b.parent = p;

        return p;
    }

    void rotateOrientaion(Control c, EventArgs e)
    {
        if (_contentPanel.orientation != Orientation.HORIZONTAL)
            _contentPanel.orientation = Orientation.HORIZONTAL;
        else
            _contentPanel.orientation = Orientation.VERTICAL;
        
        // NOTE: Reset panel size to default after orientation changed.
        foreach (panel; _configPanels)
            panel.size = DEFAULT_PANEL_SIZE;
    }
}

void main(string[] args)
{
        Application.enableVisualStyles();

        import dfl.internal.dpiaware;
        SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);

        Application.run(new MainForm());
}

DFL のダウンロード

github.com

DUB のパッケージ

code.dlang.org