File: message-dialog.cpp

package info (click to toggle)
ares 134%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 34,680 kB
  • sloc: cpp: 338,717; ansic: 89,036; sh: 52; makefile: 27
file content (130 lines) | stat: -rw-r--r-- 4,025 bytes parent folder | download | duplicates (2)
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
#if defined(Hiro_MessageDialog)

MessageDialog::MessageDialog(const string& text) {
  state.text = text;
}

auto MessageDialog::checked() const -> bool {
  return state.checked;
}

auto MessageDialog::error(const vector<string>& buttons) -> string {
  state.buttons = buttons;
  state.icon = Icon::Prompt::Error;
  return _run();
}

auto MessageDialog::information(const vector<string>& buttons) -> string {
  state.buttons = buttons;
  state.icon = Icon::Prompt::Information;
  return _run();
}

auto MessageDialog::question(const vector<string>& buttons) -> string {
  state.buttons = buttons;
  state.icon = Icon::Prompt::Question;
  return _run();
}

auto MessageDialog::setAlignment(Alignment alignment) -> type& {
  state.alignment = alignment;
  state.relativeTo = {};
  return *this;
}

auto MessageDialog::setAlignment(sWindow relativeTo, Alignment alignment) -> type& {
  state.alignment = alignment;
  state.relativeTo = relativeTo;
  return *this;
}

auto MessageDialog::setChecked(bool checked) -> type& {
  state.checked = checked;
  return *this;
}

auto MessageDialog::setOption(const string& option) -> type& {
  state.option = option;
  return *this;
}

auto MessageDialog::setText(const string& text) -> type& {
  state.text = text;
  return *this;
}

auto MessageDialog::setTitle(const string& title) -> type& {
  state.title = title;
  return *this;
}

auto MessageDialog::warning(const vector<string>& buttons) -> string {
  state.buttons = buttons;
  state.icon = Icon::Prompt::Warning;
  return _run();
}

auto MessageDialog::_run() -> string {
  if(!state.buttons) return {};  //nothing to do
  Application::Namespace tr{"MessageDialog"};

  Window window;
    VerticalLayout layout{&window};
      HorizontalLayout messageLayout{&layout, Size{~0, 0}, 5_sy};
        VerticalLayout messageIconLayout{&messageLayout, Size{16_sx, ~0}, 5_sx};
          Canvas messageIcon{&messageIconLayout, Size{16_sx, 16_sy}, 0};
          Widget messageIconSpacer{&messageIconLayout, Size{16_sx, ~0}};
        Label messageText{&messageLayout, Size{~0, 0}};
      Widget optionSpacer{&layout, Size{0, 0}};
      CheckLabel optionText{&layout, Size{~0, 0}};
      HorizontalLayout controlLayout{&layout, Size{~0, 0}};
        Widget controlSpacer{&controlLayout, Size{~0, 0}};

  layout.setPadding(5_sx, 5_sy);
  image icon{state.icon};
  icon.scale(16_sx, 16_sy);
  messageIcon.setIcon(icon);
  messageText.setText(state.text);
  optionSpacer.setCollapsible().setVisible((bool)state.option);
  optionText.setCollapsible().setChecked(state.checked).setText(state.option).setVisible((bool)state.option).onToggle([&] {
    state.checked = optionText.checked();
  });
  for(auto n : range(state.buttons.size())) {
    Button button{&controlLayout, Size{80_sx, 0}, 5_sx};
    button.onActivate([&, n] {
      state.response = state.buttons[n];
      window.setModal(false);
    });
    button.setText(tr(state.buttons[n]));
    button.setFocused();  //the last button will have effective focus
  }

  s32 widthMessage = 5_sx + 16 + 5_sx + Font().size(state.text).width() + 5_sx;
  s32 widthButtons = 5_sx + state.buttons.size() * 85_sx;
  s32 width = max(320_sx, widthMessage, widthButtons);

  window.onClose([&] {
    //if the dialog is dismissed (escape pressed, or window manager close button clicked),
    //set the response to the last button shown (which is also the default selected button),
    //and set a flag to indicate that the dialog was dismissed to the caller.
    //note that the safest option should always be the last option in the buttons list.
    if(!state.response) {
      state.response = state.buttons.last();
      state.dismissed = true;
    }
    window.setModal(false);
  });

  window.setTitle(state.title);
  window.setResizable(false);
  window.setSize({width, layout.minimumSize().height()});
  window.setAlignment(state.relativeTo, state.alignment);
  window.setDismissable();
  window.setVisible();
  window.setModal();
  window.setVisible(false);

  return state.response;
}

#endif