xref: /haiku/src/apps/debugger/user_interface/gui/util/AlertWithCheckbox.cpp (revision e82f2e19431b5797fd18c8d7bf0f677080894103)
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 	BResources resources;
46 	resources.SetToImage(B_TRANSLATION_CONTEXT);
47 	size_t size;
48 	const uint8* iconData = (const uint8*)resources.LoadResource('VICN', 1,
49 		&size);
50 
51 	// TODO load "info" icon from app_server instead?
52 	BIconUtils::GetVectorIcon(iconData, size, &fBitmap);
53 	BStripeView *stripeView = new BStripeView(fBitmap);
54 
55 	BTextView *message = new BTextView("_tv_");
56 	message->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
57 	rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);
58 	message->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor);
59 	message->MakeEditable(false);
60 	message->MakeSelectable(false);
61 	message->SetWordWrap(true);
62 	message->SetText(messageText);
63 	message->SetExplicitMaxSize(BSize(B_SIZE_UNSET, B_SIZE_UNSET));
64 	float width = message->StringWidth("W") * 40;
65 	message->SetExplicitMinSize(BSize(width, B_SIZE_UNSET));
66 
67 	fDontAskAgain = new BCheckBox("checkbox",
68 		checkboxLabel, NULL);
69 
70 	BButton* button1 = new BButton(label1, label1, new BMessage(kButton1Message));
71 	BButton* button2 = new BButton(label2, label2, new BMessage(kButton2Message));
72 	BButton* button3 = new BButton(label3, label3, new BMessage(kButton3Message));
73 	button1->MakeDefault(true);
74 
75 	BLayoutBuilder::Group<>(this)
76 		.AddGroup(B_HORIZONTAL)
77 			.Add(stripeView)
78 			.AddGroup(B_VERTICAL)
79 				.SetInsets(B_USE_SMALL_SPACING)
80 				.Add(message)
81 				.AddGroup(B_HORIZONTAL, 0)
82 					.Add(fDontAskAgain)
83 					.AddGlue()
84 				.End()
85 				.AddGroup(B_HORIZONTAL)
86 					.AddGlue()
87 					.Add(button1)
88 					.Add(button2)
89 					.Add(button3)
90 				.End()
91 			.End()
92 		.End();
93 
94 	ResizeToPreferred();
95 	CenterOnScreen();
96 }
97 
98 
99 AlertWithCheckbox::~AlertWithCheckbox()
100 {
101 	delete_sem(fSemaphore);
102 }
103 
104 
105 void
106 AlertWithCheckbox::MessageReceived(BMessage* message)
107 {
108 	switch(message->what) {
109 		case B_QUIT_REQUESTED:
110 			release_sem(fSemaphore);
111 			break;
112 
113 		case 0:
114 		case 1:
115 		case 2:
116 			fAction = message->what;
117 			PostMessage(B_QUIT_REQUESTED);
118 			return;
119 	}
120 
121 	BWindow::MessageReceived(message);
122 }
123 
124 
125 int32
126 AlertWithCheckbox::Go(bool& dontAskAgain)
127 {
128 	Show();
129 
130 	// Wait for user to close the window
131 	acquire_sem(fSemaphore);
132 	dontAskAgain = fDontAskAgain->Value();
133 	return fAction;
134 }
135 
136 
137 BRect
138 AlertWithCheckbox::IconSize()
139 {
140 	return BRect(BPoint(0, 0), be_control_look->ComposeIconSize(32));
141 }
142