I want to create an ImGui button, when I click on this button, I want it to redirect to a url, that is, to the browser, how can I do that? can you help me please?
Creating a button:
#[imgui(
button(size = "button_size",
label = "Click me!",
catch ="click"),
separator,
display(label = "Clicks"),
)]
count: i32, }
const fn button_size() -> (f32, f32){
(100.0, 20.0)
}
However, opening a webpage is a bit harder since it depends on the api of the os that you're using. Doing that for windows and mac would look like this:
void OsOpenInShell(const char* path) {
#ifdef _WIN32
// Note: executable path must use backslashes!
::ShellExecuteA(NULL, "open", path, NULL, NULL, SW_SHOWDEFAULT);
#else
#if __APPLE__ const char* open_executable = "open";
#else
const char* open_executable = "xdg
open";
#endif char command[256];
snprintf(command, 256, "%s \"%s\"",
open_executable, path);
system(command);
#endif
Then you could put the previous code inside this:
let events = ui.imgui_ext(&mut buttons);
if events.click {
*insert code*
}
Related
I've looked everywhere, and I can't seem to find the solution to my problem. I am wanting to know how I could use imgui to open a popup window and opening a chrome window with a website like "https://google.com". I thought that ImGui::OpenPopup might work, but then I looked at the function and then on google and it seemed like it wouldn't work. When you click a button and it redirects to a window on your computer, like when you click a link in discord and it opens a google tab on your computer.
I assumed it may look a little like this
void GUI::renderAboutMenu() noexcept
{
if (ImGui::MenuItem("My Discord"))
openWebsite("https://discord.gg/myinvitecode");
if (ImGui::MenuItem("My Patreon"))
openWebsite("https://patreon.com/myinvitecode");
}
It's not really a dear imgui question, more about how to use your OS API to perform that.
Something like that would work:
void OsOpenInShell(const char* path)
{
#ifdef _WIN32
// Note: executable path must use backslashes!
::ShellExecuteA(NULL, "open", path, NULL, NULL, SW_SHOWDEFAULT);
#else
#if __APPLE__
const char* open_executable = "open";
#else
const char* open_executable = "xdg-open";
#endif
char command[256];
snprintf(command, 256, "%s \"%s\"", open_executable, path);
system(command);
#endif
}
I have a Dialog-based MFC app, and it has two Dialog Boxes:
IDD_FITNESSAPP_LOGIN_DLG
IDD_FITNESSAPP_MAIN_DLG
On IDD_FITNESSAPP_LOGIN_DLG, I have a button, btnLogin, that runs through some credentials (working so far, and reports failures too).
How do I make it so that when I click btnLogin on IDD_FITNESSAPP_LOGIN_DLG, it leads to IDD_FITNESSAPP_MAIN_DLG?
I read a little on Dlg.DoModal() but I don't understand that if its needed.
Here's the code for the "on button clicked btnLogin":
void CFitnessAppMFC2Dlg::OnBnClickedbtnlogin()
{
// TODO: Add your control notification handler code here
UpdateData();
char UsernameFromFile[20], PasswordFromFile[20];
FILE* fleCredentials;
bool ValidLogin = false;
if (m_Username == "")
{
AfxMessageBox(_T("You must provide a username and a password or click Cancel"));
return;
}
if (m_Password == "")
{
AfxMessageBox(_T("Invalid Login"));
return;
}
try {
// Open the file for reading
fleCredentials = fopen("credentials.txt", "r");
// Scan the file from beginning to end
while (!feof(fleCredentials))
{
// Read a username
fscanf(fleCredentials, "%s", UsernameFromFile);
// Compare the typed username with the username from the file
CT2A ascii(m_Username);
if (strcmp(ascii, UsernameFromFile) == 0)
{
// With the current username, retrieve the corresponding password
fscanf(fleCredentials, "%s", PasswordFromFile);
// Compare the typed password with the one on file
CT2A ascii2(m_Password);
if (strcmp(ascii2, PasswordFromFile) == 0)
{
ValidLogin = true;
}
else
ValidLogin = false;
}
}
if (ValidLogin == true)
OnOK();
else
{
AfxMessageBox(_T("Invalid Credentials. Please try again"));
this->m_EditUsername.SetFocus();
}
fclose(fleCredentials);
}
catch (...)
{
AfxMessageBox(_T("Could not validate the credentials"));
}
UpdateData(FALSE);
}
1.Resourse View-> Dialog->Right click->Add Resource->Dlg, Then add class for the new Dlg.
2.There are two types of Dlgs.
Modal Dialogue Box
When the user wants to operate on applications other than the dialog box, the dialog box must first be responded to.
#include "CXXXDlg.h "
void CXXXDlg::OnBnClickedOk()
{
CMyNewDlg Dlg;
Dlg.DoModal();
}
Modeless Dialogue Box
When the user opens a non-modal dialog box, other windows can still be operated.
#include "CXXXDlg.h"
void CXXXDlg::OnBnClickedOk()
{
CMyNewDlg *pDlg=new CMyNewDlg ;
pDlg->Create(IDD_DIALOG2,this);
pDlg->ShowWindow(SW_SHOW);
}
I am using GTK+ to create a C++ program. For choosing files I used native file chooser as the gtk file chooser has a memory leak.
Here is my question: How can I set a default file name for the native file chooser in GTK+ (while saving) and how can I setup a file filter for it - to be able to open or save only specific file extensions?
My program works on Win32.
Sample code:
static void cb_SaveFileAs(GtkWidget *caller)
{
GtkWindow *parent_window = GTK_WINDOW(caller);
GtkFileChooserNative *native;
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE;
gint res;
native = gtk_file_chooser_native_new("Save File",
parent_window,
action,
"_Save",
"_Cancel");
res = gtk_native_dialog_run(GTK_NATIVE_DIALOG(native));
if (res == GTK_RESPONSE_ACCEPT)
{
char *filename;
GtkFileChooser *chooser = GTK_FILE_CHOOSER(native);
filename = gtk_file_chooser_get_filename(chooser);
// save the file
save_to_file(filename);
g_free(filename);
}
g_object_unref(native);
}
Here is an example of setting a GtkFileFilter with the *.cpp pattern to only show C++ files. It also sets the default document name to test.cpp.
compiling with : g++ filechooser.cpp `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0`
#include <gtk/gtk.h>
static void dialog_result(GtkWidget *dialog, gint resp, gpointer data)
{
if (resp == GTK_RESPONSE_OK) {
// do nothing
} else {
gtk_widget_destroy(dialog);
}
}
static void open_dialog(GtkWidget *button, gpointer window)
{
GtkWidget *dialog;
GtkFileFilter *filter;
dialog = gtk_file_chooser_dialog_new("Choose a file:", GTK_WINDOW(window),
GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_SAVE,
GTK_RESPONSE_OK, GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL, NULL);
filter = gtk_file_filter_new();
gtk_file_filter_add_pattern(filter, "*.cpp");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "test.cpp");
gtk_widget_show_all(dialog);
gint resp = gtk_dialog_run(GTK_DIALOG(dialog));
if (resp == GTK_RESPONSE_OK)
g_print("%s\n", gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
else
g_print("You pressed the cancel\n");
gtk_widget_destroy(dialog);
}
int main()
{
gtk_init(NULL, NULL);
GtkWidget *window, *button;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "delete_event", G_CALLBACK(gtk_main_quit), NULL);
button = gtk_button_new_with_label("Save");
g_signal_connect(button, "clicked", G_CALLBACK(open_dialog), window);
gtk_container_set_border_width(GTK_CONTAINER(window), 100);
gtk_container_add(GTK_CONTAINER(window), button);
gtk_widget_show_all(window);
gtk_main();
}
Here is completed code for GTK native file chooser completed with solution from jackw11111:
static void cb_SaveFileAs(GtkWidget *caller) // callback function
{
GtkWindow *parent_window = GTK_WINDOW(caller); // assuming that the caller is GtkWindow
GtkFileChooserNative *native;
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE;
gint res;
native = gtk_file_chooser_native_new("Save File",
parent_window,
action,
"_Save",
"_Cancel");
// Filters
filter = gtk_file_filter_new(); // filter 1
gtk_file_filter_set_name(filter, "Project file");
gtk_file_filter_add_pattern(filter, ".proj");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(native), filter);
filter = gtk_file_filter_new(); // filter 2
gtk_file_filter_set_name(filter, "All files");
gtk_file_filter_add_pattern(filter, "*");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(native), filter);
// default file name
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(native), "my_file_name");
res = gtk_native_dialog_run(GTK_NATIVE_DIALOG(native));
if (res == GTK_RESPONSE_ACCEPT)
{
char *filename;
GtkFileChooser *chooser = GTK_FILE_CHOOSER(native);
filename = gtk_file_chooser_get_filename(chooser);
// save the file
save_to_file(filename);
g_free(filename);
}
g_object_unref(native);
}
I have two variables, m_GridSize and m_TimeDisplay, which update themselves according to a variable called "world" here. Now, the MFC program will display the words "Grid size: " and "Time: ", but it will not display the actual values of the doubles. I am using Visual Studio Community 2013 to make a Win32 GUI application.
I am having trouble with the CString Format function.
EDIT to include full code:
// smart_parking_guiDlg.cpp : implementation file
//
#include "stdafx.h"
#include "smart_parking_gui.h"
#include "smart_parking_guiDlg.h"
#include "afxdialogex.h"
#include "Cadd_Destination.h"
#include "Cadd_Lot.h"
#include "Cadd_Driver.h"
#include "Commands.h" // Used to handle commands
#include "Grid.h" // Contains the grid
#include <string>
#include <io.h>
#include <fcntl.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// Csmart_parking_guiDlg dialog
Csmart_parking_guiDlg::Csmart_parking_guiDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(Csmart_parking_guiDlg::IDD, pParent)
, m_EchoSize(_T("Grid size: "))
, m_EchoTime(_T("Time: "))
, m_EchoStatus(_T("Open"))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
this->world = new Grid(10, 5); // default grid
}
void Csmart_parking_guiDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_ST_GRIDSIZE, m_EchoSize);
DDX_Text(pDX, IDC_ST_TIME, m_EchoTime);
DDX_Text(pDX, IDC_ST_STATUS, m_EchoStatus);
}
BEGIN_MESSAGE_MAP(Csmart_parking_guiDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_B_OPEN_CONFIG, &Csmart_parking_guiDlg::OnBnClickedBOpenConfig)
ON_BN_CLICKED(IDC_B_SAVECONFIG, &Csmart_parking_guiDlg::OnBnClickedBSaveconfig)
ON_BN_CLICKED(IDC_B_NEXTEVENT, &Csmart_parking_guiDlg::OnBnClickedBNextevent)
ON_BN_CLICKED(IDC_B_NEWDEST, &Csmart_parking_guiDlg::OnBnClickedBNewdest)
ON_BN_CLICKED(IDC_B_NEWLOT, &Csmart_parking_guiDlg::OnBnClickedBNewlot)
ON_BN_CLICKED(IDC_B_NEWDRIVER, &Csmart_parking_guiDlg::OnBnClickedBNewdriver)
ON_BN_CLICKED(IDC_B_SIMEND, &Csmart_parking_guiDlg::OnBnClickedBSimend)
ON_BN_CLICKED(IDC_B_SHOWSTATUS, &Csmart_parking_guiDlg::OnBnClickedBShowstatus)
END_MESSAGE_MAP()
// Csmart_parking_guiDlg message handlers
BOOL Csmart_parking_guiDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE;
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void Csmart_parking_guiDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR Csmart_parking_guiDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void Csmart_parking_guiDlg::OnBnClickedBOpenConfig()
{
wchar_t szFilters[] = _T("Text Files (*.txt)|*.txt|All Files (*.*)|*.*||");
// Create an Open dialog
CFileDialog fileDlg(TRUE, _T("txt"), _T("*.txt"),
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters, this); // Display the file dialog.
// When user clicks OK, fileDlg.DoModal() returns IDOK.
if (fileDlg.DoModal() == IDOK)
{
CString m_strPathname = fileDlg.GetPathName();
CT2CA converter(m_strPathname);
std::string fileToOpen(converter);
// TODO: Open Grid file
open_file(*world, fileToOpen);
//Change the window's title to the opened file's title.
CString fileName = fileDlg.GetFileTitle();
SetWindowText(fileName);
}
}
void Csmart_parking_guiDlg::OnBnClickedBSaveconfig()
{
// TODO: Add your control notification handler code here
// szFilters is a text string that includes two file name filters:
// "*.my" for "MyType Files" and "*.*' for "All Files."
TCHAR szFilters[] = _T("Text Files (*.txt)|*.txt|All Files (*.*)|*.*||");
// Create a Save dialog
CFileDialog fileDlg(FALSE, _T("txt"), _T("*.txt"),
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters);
// Display the file dialog. When user clicks OK, fileDlg.DoModal()
// returns IDOK.
if (fileDlg.DoModal() == IDOK)
{
CString pathName = fileDlg.GetPathName();
CT2CA converter(pathName);
std::string fileToWrite(converter);
// Implement opening and reading file in here.
write_file(*world, fileToWrite);
//Change the window's title to the opened file's title.
CString fileName = fileDlg.GetFileTitle();
SetWindowText(fileName);
}
}
void Csmart_parking_guiDlg::OnBnClickedBNextevent()
{
// TODO: Add your control notification handler code here
run_simulation(*world);
m_GridSize = world->getGridSize(); // double
m_TimeDisplay = world->getTime(); // double
// THIS DOESN'T WORK
m_EchoSize.Format(_T("Grid size: %g"), m_GridSize);
m_EchoTime.Format(_T("Time: %g"), m_TimeDisplay);
UpdateData(FALSE);
GetDlgItem(IDC_ST_GRIDSIZE)->InvalidateRect(NULL);
GetDlgItem(IDC_ST_TIME)->InvalidateRect(NULL);
}
void Csmart_parking_guiDlg::OnBnClickedBSimend() // On clicking, simulation jumps to the very end.
{
jump_to_end(*world);
m_GridSize = world->getGridSize();
m_TimeDisplay = world->getTime();
// THIS DOESN'T WORK
m_EchoSize.Format(_T("Grid size: %g"), m_GridSize);
m_EchoTime.Format(_T("Time: %g"), m_TimeDisplay);
UpdateData(FALSE);
GetDlgItem(IDC_ST_GRIDSIZE)->InvalidateRect(NULL);
GetDlgItem(IDC_ST_TIME)->InvalidateRect(NULL);
}
void Csmart_parking_guiDlg::OnBnClickedBNewdest()
{
// TODO: Add your control notification handler code here
Cadd_Destination Dlg;
Dlg.DoModal();
}
void Csmart_parking_guiDlg::OnBnClickedBNewlot()
{
// TODO: Add your control notification handler code here
Cadd_Lot Dlg;
Dlg.DoModal();
}
void Csmart_parking_guiDlg::OnBnClickedBNewdriver() // Opens a dialog to input a new driver. Only works with added destination.
{
if (world->getDestinationCount() != 0) {
Cadd_Driver Dlg;
Dlg.DoModal();
}
}
void Csmart_parking_guiDlg::OnBnClickedBShowstatus()
{
// TODO: Add your control notification handler code here
}
Is there any way to fix this in order to make the values of the doubles show up in the GUI? I have tried the answer shown here
C++ MFC double to CString
but the numbers do not show up at all. There are no syntax errors. The code works if I use %d and replace the values with integers, but it doesn't work with double values, which is what I used in my initial classes.
I have fixed the problem myself.
As it turns out, the issue had more to do with my GUI. It turns out that the Static Text has a set length set in the Visual Studio Dialog Editor (accessed through the Resource View) and the length was too short to hold both the string containing "Grid size:" and the actual numbers. (The first Static Text initially could only hold one digit for both of them) I fixed it by extending the width of the Static Text in my GUI, and that fixed the problem.
As implied by the name, Static text controls are not expected to change once they are created. They don't automatically repaint when you change their content with SetWindowText, which is what DDX_Text calls to set the new text. You need to inform Windows that the contents have changed and the control needs repainting:
GetDlgItem(IDC_ST_GRIDSIZE)->InvalidateRect(NULL);
I wrote a code in mfc for login form
my code is here
// login1Dlg.cpp : implementation file
//
#include "stdafx.h"
#include "login1.h"
#include "login1Dlg.h"
#include "afxdialogex.h"
//#include "LOGINDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// Clogin1Dlg dialog
Clogin1Dlg::Clogin1Dlg(CWnd* pParent /*=NULL*/)
: CDialogEx(Clogin1Dlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_username = _T("");
m_password = _T("");
}
void Clogin1Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_USERNAME_EDIT, m_username);
DDX_Text(pDX, IDC_PASSWORD_EDIT, m_password);
}
BEGIN_MESSAGE_MAP(Clogin1Dlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_OK_BUTTON, &Clogin1Dlg::OnBnClickedOkButton)
END_MESSAGE_MAP()
// Clogin1Dlg message handlers
BOOL Clogin1Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void Clogin1Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR Clogin1Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void Clogin1Dlg::OnBnClickedOkButton()
{
// TODO: Add your control notification handler code here
UpdateData();
char UsernameFromFile[20], PasswordFromFile[20];
FILE *fleCredentials;
bool ValidLogin = false;
if(m_username == "" )
{
AfxMessageBox(_T("You must provide a username and a password or click Cancel"));
return;
}
if( m_password == "" )
{
AfxMessageBox(_T("Invalid Login"));
return;
}
try {
// Open the file for reading
fleCredentials = fopen("credentials.txt", "r");
// Scan the file from beginning to end
while( !feof(fleCredentials) )
{
//Read a username
fscanf(fleCredentials, "%s", UsernameFromFile);
//Compare the typed username with the username from the file
if(strcmp((LPCTSTR)m_username, UsernameFromFile) == 0 )
{
// With the current username, retrieve the corresponding password
fscanf(fleCredentials, "%s", PasswordFromFile);
//Compare the typed password with the one on file
if( strcmp((LPCTSTR)m_password, PasswordFromFile) == 0 )
{
ValidLogin = true;
}
else
ValidLogin = false;
}
}
if( ValidLogin == true )
OnOK();
else
{
AfxMessageBox(_T("Invalid Credentials. Please try again"));
//this->m_EditUsername.SetFocus();
}
fclose(fleCredentials);
}
catch(...)
{
AfxMessageBox(_T("Could not validate the credentials"));
}
UpdateData(FALSE);
}
But I got this error
Error 3 error C2664: 'strcmp' : cannot convert parameter 1 from 'LPCTSTR' to 'const char *' e:\win32\test\login1\login1dlg.cpp 130 1 login1
i want little help from u
try Change the 2 if statement code to this
if(strcmp((LPSTR)(LPCTSTR)m_username, UsernameFromFile) == 0 )
if( strcmp((LPSTR)(LPCTSTR)m_password, PasswordFromFile) == 0 )
from the error i can see cannot convert parameter 1 from 'LPCTSTR' to 'const char *'
strcmp is used with char ANSI but try using the Unicode version of it instead
as you know LPCTSTR is dependent on unicode or ansi if you use unicode library use the following function wcscmp for more information help at msdn
also for types windows data types on msdn
so you replace strcmp at line 129 and 135 with wcscmp if this solve the problem just let us know