xref: /haiku/src/apps/debugger/user_interface/gui/util/AlertWithCheckbox.cpp (revision 445d4fd926c569e7b9ae28017da86280aaecbae2)
1 /*
2  * Copyright 2019-2023, Adrien Destugues, pulkomandy@pulkomandy.tk.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "AlertWithCheckbox.h"
8 
9 #include <algorithm>
10 #include <stdio.h>
11 
12 #include <Button.h>
13 #include <Catalog.h>
14 #include <CheckBox.h>
15 #include <ControlLook.h>
16 #include <GroupLayout.h>
17 #include <LayoutBuilder.h>
18 #include <Locale.h>
19 #include <IconUtils.h>
20 #include <Resources.h>
21 #include <StripeView.h>
22 #include <TextView.h>
23 
24 #undef B_TRANSLATION_CONTEXT
25 #define B_TRANSLATION_CONTEXT "DebugServer"
26 
27 
28 enum {
29 	kButton1Message,
30 	kButton2Message,
31 	kButton3Message
32 };
33 
34 
35 AlertWithCheckbox::AlertWithCheckbox(const char* title, const char* messageText,
36 	const char* checkboxLabel, const char* label1, const char* label2, const char* label3)
37 	:
38 	BWindow(BRect(0, 0, 100, 50), title,
39 		B_MODAL_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL,
40 		B_CLOSE_ON_ESCAPE | B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS),
41 	fBitmap(IconSize(), B_RGBA32),
42 	fSemaphore(create_sem(0, "AlertWithCheckbox")),
43 	fAction(0)
44 {
45 	BIconUtils::GetSystemIcon("dialog-information", &fBitmap);
46 	BStripeView *stripeView = new BStripeView(fBitmap);
47 
48 	BTextView *message = new BTextView("_tv_");
49 	message->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
50 	rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);
51 	message->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor);
52 	message->MakeEditable(false);
53 	message->MakeSelectable(false);
54 	message->SetText(messageText);
55 	BRect textRect = message->TextRect();
56 	textRect.PrintToStream();
57 	message->SetWordWrap(true);
58 	message->SetExplicitMaxSize(BSize(B_SIZE_UNSET, B_SIZE_UNSET));
59 	float width = message->StringWidth("W") * 40;
60 	if (width < textRect.Width()) {
61 		message->SetExplicitMinSize(BSize(width, B_SIZE_UNSET));
62 	}
63 
64 	fDontAskAgain = new BCheckBox("checkbox", checkboxLabel, NULL);
65 
66 	BGroupView* buttonGroup = new BGroupView(B_HORIZONTAL);
67 	BLayoutBuilder::Group<> layoutBuilder(buttonGroup);
68 
69 	layoutBuilder.AddGlue();
70 
71 	if (label1) {
72 		BButton* button = new BButton(label1, label1, new BMessage(kButton1Message));
73 		button->MakeDefault(true);
74 		layoutBuilder.Add(button);
75 	}
76 
77 	if (label2) {
78 		BButton* button = new BButton(label2, label2, new BMessage(kButton2Message));
79 		layoutBuilder.Add(button);
80 	}
81 
82 	if (label3) {
83 		BButton* button = new BButton(label3, label3, new BMessage(kButton3Message));
84 		layoutBuilder.Add(button);
85 	}
86 
87 	BLayoutBuilder::Group<>(this)
88 		.AddGroup(B_HORIZONTAL)
89 			.Add(stripeView)
90 			.AddGroup(B_VERTICAL)
91 				.SetInsets(B_USE_SMALL_SPACING)
92 				.Add(message)
93 				.AddGroup(B_HORIZONTAL, 0)
94 					.Add(fDontAskAgain)
95 					.AddGlue()
96 				.End()
97 				.Add(buttonGroup)
98 			.End()
99 		.End();
100 
101 	ResizeToPreferred();
102 	CenterOnScreen();
103 }
104 
105 
106 AlertWithCheckbox::~AlertWithCheckbox()
107 {
108 	delete_sem(fSemaphore);
109 }
110 
111 
112 void
113 AlertWithCheckbox::MessageReceived(BMessage* message)
114 {
115 	switch(message->what) {
116 		case B_QUIT_REQUESTED:
117 			release_sem(fSemaphore);
118 			break;
119 
120 		case 0:
121 		case 1:
122 		case 2:
123 			fAction = message->what;
124 			PostMessage(B_QUIT_REQUESTED);
125 			return;
126 	}
127 
128 	BWindow::MessageReceived(message);
129 }
130 
131 
132 int32
133 AlertWithCheckbox::Go(bool& dontAskAgain)
134 {
135 	Show();
136 
137 	// Wait for user to close the window
138 	acquire_sem(fSemaphore);
139 	dontAskAgain = fDontAskAgain->Value();
140 	return fAction;
141 }
142 
143 
144 BRect
145 AlertWithCheckbox::IconSize()
146 {
147 	return BRect(BPoint(0, 0), be_control_look->ComposeIconSize(32));
148 }
149