const char* file = file_dialog_show( parent, open, title, path, pattern, want_load, want_import, want_save );
if ( open
- || file == 0
+ || !file
|| !file_exists( file )
- || parent.alert("The file specified already exists.\nDo you want to replace it?", title, ui::alert_type::NOYES, ui::alert_icon::Question ) == ui::alert_response::YES ) {
+ || ui::alert(parent, "The file specified already exists.\nDo you want to replace it?", title, ui::alert_type::NOYES, ui::alert_icon::Question ) == ui::alert_response::YES ) {
return file;
}
}
return toolbar_append_button( toolbar, description, icon, command.m_callback );
}
-void toggle_button_set_active_callback(ui::ToggleToolButton& button, bool active ){
+void toggle_button_set_active_callback(void *it, bool active ){
+ auto button = ui::ToggleToolButton::from(it);
toggle_button_set_active_no_signal( button, active );
}
-using ToggleButtonSetActiveCaller = ReferenceCaller<ui::ToggleToolButton, void(bool), toggle_button_set_active_callback>;
ui::ToggleToolButton toolbar_append_toggle_button( ui::Toolbar toolbar, const char* description, const char* icon, const Toggle& toggle ){
auto button = toolbar_append_toggle_button( toolbar, description, icon, toggle.m_command.m_callback );
- toggle.m_exportCallback( ToggleButtonSetActiveCaller( button ) );
+ toggle.m_exportCallback( PointerCaller<void, void(bool), toggle_button_set_active_callback>( button._handle ) );
return button;
}
}
}
- Widget root{ui::null};
-
#define IMPL(T, F) template<> _IMPL(T, F)
#define _IMPL(T, F) struct verify<T *> { using self = T; static self test(self it) { return self::from(F(it)); } }
)))
{}
- alert_response IWindow::alert(std::string text, std::string title, alert_type type, alert_icon icon)
- {
- auto ret = gtk_MessageBox(this, text.c_str(),
- title.c_str(),
- type == alert_type::OK ? eMB_OK :
- type == alert_type::OKCANCEL ? eMB_OKCANCEL :
- type == alert_type::YESNO ? eMB_YESNO :
- type == alert_type::YESNOCANCEL ? eMB_YESNOCANCEL :
- type == alert_type::NOYES ? eMB_NOYES :
- eMB_OK,
- icon == alert_icon::Default ? eMB_ICONDEFAULT :
- icon == alert_icon::Error ? eMB_ICONERROR :
- icon == alert_icon::Warning ? eMB_ICONWARNING :
- icon == alert_icon::Question ? eMB_ICONQUESTION :
- icon == alert_icon::Asterisk ? eMB_ICONASTERISK :
- eMB_ICONDEFAULT
- );
- return
- ret == eIDOK ? alert_response::OK :
- ret == eIDCANCEL ? alert_response::CANCEL :
- ret == eIDYES ? alert_response::YES :
- ret == eIDNO ? alert_response::NO :
- alert_response::OK;
- }
-
Window IWindow::create_dialog_window(const char *title, void func(), void *data, int default_w, int default_h)
{
return Window(::create_dialog_window(this, title, func, data, default_w, default_h));
#endif
}
+ // global
+
+ Window root{ui::null};
+
+ alert_response alert(Window parent, std::string text, std::string title, alert_type type, alert_icon icon)
+ {
+ auto ret = gtk_MessageBox(parent, text.c_str(),
+ title.c_str(),
+ type == alert_type::OK ? eMB_OK :
+ type == alert_type::OKCANCEL ? eMB_OKCANCEL :
+ type == alert_type::YESNO ? eMB_YESNO :
+ type == alert_type::YESNOCANCEL ? eMB_YESNOCANCEL :
+ type == alert_type::NOYES ? eMB_NOYES :
+ eMB_OK,
+ icon == alert_icon::Default ? eMB_ICONDEFAULT :
+ icon == alert_icon::Error ? eMB_ICONERROR :
+ icon == alert_icon::Warning ? eMB_ICONWARNING :
+ icon == alert_icon::Question ? eMB_ICONQUESTION :
+ icon == alert_icon::Asterisk ? eMB_ICONASTERISK :
+ eMB_ICONDEFAULT
+ );
+ return
+ ret == eIDOK ? alert_response::OK :
+ ret == eIDCANCEL ? alert_response::CANCEL :
+ ret == eIDYES ? alert_response::YES :
+ ret == eIDNO ? alert_response::NO :
+ alert_response::OK;
+ }
+
}
void process();
- extern class Widget root;
-
- enum class alert_type {
- OK,
- OKCANCEL,
- YESNO,
- YESNOCANCEL,
- NOYES,
- };
-
- enum class alert_icon {
- Default,
- Error,
- Warning,
- Question,
- Asterisk,
- };
-
- enum class alert_response {
- OK,
- CANCEL,
- YES,
- NO,
- };
-
enum class window_type {
TOP,
POPUP
};
}
- extern struct Null {} null;
- extern struct New_t {} New;
+ const struct Null {} null = {};
+ const struct New_t {} New = {};
class Object :
public details::Convertible<Object, _GtkObject *, details::Convert::Explicit>,
using self = name *; \
using native = T *; \
protected: \
- explicit name(native h) : super(reinterpret_cast<super::native>(h)) {} \
+ explicit name(native h) noexcept : super(reinterpret_cast<super::native>(h)) {} \
public: \
- explicit name(Null n) : name((native) nullptr) {} \
+ explicit name(Null n) noexcept : name((native) nullptr) {} \
explicit name(New_t); \
static name from(native h) { return name(h); } \
static name from(void *ptr) { return name((native) ptr); } \
WRAP(Window, Bin, _GtkWindow, (),
explicit Window(window_type type);
,
- alert_response alert(
- std::string text,
- std::string title = "NetRadiant",
- alert_type type = alert_type::OK,
- alert_icon icon = alert_icon::Default
- );
-
Window create_dialog_window(
const char *title,
void func(),
#undef WRAP
+ // global
+
+ enum class alert_response {
+ OK,
+ CANCEL,
+ YES,
+ NO,
+ };
+
+ enum class alert_type {
+ OK,
+ OKCANCEL,
+ YESNO,
+ YESNOCANCEL,
+ NOYES,
+ };
+
+ enum class alert_icon {
+ Default,
+ Error,
+ Warning,
+ Question,
+ Asterisk,
+ };
+
+ extern class Window root;
+
+ alert_response alert(
+ Window parent,
+ std::string text,
+ std::string title = "NetRadiant",
+ alert_type type = alert_type::OK,
+ alert_icon icon = alert_icon::Default
+ );
+
// callbacks
namespace {
{
StringOutputStream strMsg( 256 );
strMsg << "Snapshot save failed.. unabled to create directory\n" << snapshotsDir.c_str();
- MainFrame_getWindow().alert( strMsg.c_str() );
+ ui::alert( MainFrame_getWindow(), strMsg.c_str() );
}
}
/*
StringOutputStream msg;
msg << "The command " << name << " is already assigned to the key " << accelerator << ".\n\n"
<< "Do you want to unassign " << name << " first?";
- auto r = widget.window().alert( msg.c_str(), "Key already used", ui::alert_type::YESNOCANCEL );
+ auto r = ui::alert( widget.window(), msg.c_str(), "Key already used", ui::alert_type::YESNOCANCEL );
if ( r == ui::alert_response::YES ) {
// clear the ACTUAL accelerator too!
disconnect_accelerator( name );
<< "This is NetRadiant '" RADIANT_VERSION "' compiled " __DATE__ "\n" RADIANT_ABOUTMSG "\n";
}
else{
- ui::root.window().alert( "Failed to create log file, check write permissions in Radiant directory.\n",
+ ui::alert( ui::root, "Failed to create log file, check write permissions in Radiant directory.\n",
"Console logging", ui::alert_type::OK, ui::alert_icon::Error );
}
}
GtkTreeModel* model;
GtkTreeIter iter;
if ( gtk_tree_selection_get_selected( gtk_tree_view_get_selection( g_entityClassList ), &model, &iter ) == FALSE ) {
- view.window().alert( "You must have a selected class to create an entity", "info" );
+ ui::alert( view.window(), "You must have a selected class to create an entity", "info" );
return;
}
// TTimo: if you change the classname to worldspawn you won't merge back in the structural brushes but create a parasite entity
if ( !strcmp( key.c_str(), "classname" ) && !strcmp( value.c_str(), "worldspawn" ) ) {
- g_entityKeyEntry.window().alert( "Cannot change \"classname\" key back to worldspawn.", 0, ui::alert_type::OK );
+ ui::alert( g_entityKeyEntry.window(), "Cannot change \"classname\" key back to worldspawn.", 0, ui::alert_type::OK );
return;
}
// RR2DO2: we don't want spaces in entity keys
if ( strstr( key.c_str(), " " ) ) {
- g_entityKeyEntry.window().alert( "No spaces are allowed in entity keys.", 0, ui::alert_type::OK );
+ ui::alert( g_entityKeyEntry.window(), "No spaces are allowed in entity keys.", 0, ui::alert_type::OK );
return;
}
static ui::Widget text_widget{ui::null}; // slave, text widget from the gtk editor
static gint editor_delete( ui::Widget widget, gpointer data ){
- if ( widget.window().alert( "Close the shader editor ?", "Radiant", ui::alert_type::YESNO, ui::alert_icon::Question ) == ui::alert_response::NO ) {
+ if ( ui::alert( widget.window(), "Close the shader editor ?", "Radiant", ui::alert_type::YESNO, ui::alert_icon::Question ) == ui::alert_response::NO ) {
return TRUE;
}
gpointer text = g_object_get_data( G_OBJECT( data ), "text" );
if ( f == 0 ) {
- ui::Widget::from(data).window().alert( "Error saving file !" );
+ ui::alert( ui::Widget::from(data).window(), "Error saving file !" );
return;
}
}
static void editor_close( ui::Widget widget, gpointer data ){
- if ( text_editor.window().alert( "Close the shader editor ?", "Radiant", ui::alert_type::YESNO, ui::alert_icon::Question ) == ui::alert_response::NO ) {
+ if ( ui::alert( text_editor.window(), "Close the shader editor ?", "Radiant", ui::alert_type::YESNO, ui::alert_icon::Question ) == ui::alert_response::NO ) {
return;
}
ScopedLock lock( m_lock );
#if GDEF_DEBUG
m_buffer << "Break into the debugger?\n";
- bool handled = ui::root.window().alert( m_buffer.c_str(), "Radiant - Runtime Error", ui::alert_type::YESNO, ui::alert_icon::Error ) == ui::alert_response::NO;
+ bool handled = alert( ui::root, m_buffer.c_str(), "Radiant - Runtime Error", ui::alert_type::YESNO, ui::alert_icon::Error ) == ui::alert_response::NO;
m_buffer.clear();
return handled;
#else
if ( remove( g_pidFile.c_str() ) == -1 ) {
StringOutputStream msg( 256 );
msg << "WARNING: Could not delete " << g_pidFile.c_str();
- ui::root.window().alert( msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error );
+ ui::alert( ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error );
}
// in debug, never prompt to clean registry, turn console logging auto after a failed start
if ( remove( g_pidFile.c_str() ) == -1 ) {
StringOutputStream msg( 256 );
msg << "WARNING: Could not delete " << g_pidFile.c_str();
- ui::root.window().alert( msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error );
+ ui::alert( ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error );
}
}
if ( remove( g_pidGameFile.c_str() ) == -1 ) {
StringOutputStream msg;
msg << "WARNING: Could not delete " << g_pidGameFile.c_str();
- ui::root.window().alert( msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error );
+ ui::alert( ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error );
}
// in debug, never prompt to clean registry, turn console logging auto after a failed start
ui::Window create_splash(){
- ui::Window window = ui::Window( ui::window_type::TOP );
- gtk_window_set_decorated( window, FALSE );
- gtk_window_set_resizable( window, FALSE );
- gtk_window_set_modal( window, TRUE );
- gtk_window_set_default_size( window, -1, -1 );
- gtk_window_set_position( window, GTK_WIN_POS_CENTER );
- gtk_container_set_border_width( GTK_CONTAINER( window ), 0 );
-
- auto image = new_local_image( "splash.png" );
+ auto window = ui::Window( ui::window_type::TOP );
+ gtk_window_set_decorated(window, false);
+ gtk_window_set_resizable(window, false);
+ gtk_window_set_modal(window, true);
+ gtk_window_set_default_size(window, -1, -1);
+ gtk_window_set_position(window, GTK_WIN_POS_CENTER);
+ gtk_container_set_border_width(window, 0);
+
+ auto image = new_local_image("splash.png");
image.show();
window.add(image);
}
// update the point-by-point view
- OnSelchangeComboColRow( ui::root ,0 );
+ OnSelchangeComboColRow( ui::root, 0 );
}
static gint OnDialogKey( ui::Widget widget, GdkEventKey* event, gpointer data ){
static void OnButtonClean( ui::Widget widget, gpointer data ){
// make sure this is what the user wants
- if ( g_Preferences.GetWidget().alert( "This will close Radiant and clean the corresponding registry entries.\n"
+ if ( ui::alert( g_Preferences.GetWidget(), "This will close Radiant and clean the corresponding registry entries.\n"
"Next time you start Radiant it will be good as new. Do you wish to continue?",
"Reset Registry", ui::alert_type::YESNO, ui::alert_icon::Asterisk ) == ui::alert_response::YES ) {
PrefsDlg *dlg = (PrefsDlg*)data;
{
message << ( *i ) << '\n';
}
- MainFrame_getWindow().alert( message.c_str() );
+ ui::alert( MainFrame_getWindow(), message.c_str() );
g_restart_required.clear();
}
}
return true;
}
- auto result = MainFrame_getWindow().alert( "The current map has changed since it was last saved.\nDo you want to save the current map before continuing?", title, ui::alert_type::YESNOCANCEL, ui::alert_icon::Question );
+ auto result = ui::alert( MainFrame_getWindow(), "The current map has changed since it was last saved.\nDo you want to save the current map before continuing?", title, ui::alert_type::YESNOCANCEL, ui::alert_icon::Question );
if ( result == ui::alert_response::CANCEL ) {
return false;
}
ui::Window m_parent{ui::null};
ui::GLArea m_gl_widget{ui::null};
ui::Widget m_texture_scroll{ui::null};
-ui::TreeView m_treeViewTree{ui::null};
+ui::TreeView m_treeViewTree{ui::New};
ui::TreeView m_treeViewTags{ui::null};
ui::Frame m_tag_frame{ui::null};
ui::ListStore m_assigned_store{ui::null};
}
void TextureBrowser_createTreeViewTree(){
- g_TextureBrowser.m_treeViewTree = ui::TreeView(ui::New);
gtk_tree_view_set_enable_search(g_TextureBrowser.m_treeViewTree, FALSE );
gtk_tree_view_set_headers_visible(g_TextureBrowser.m_treeViewTree, FALSE );
}
else
{
- g_TextureBrowser.m_parent.alert( "Select a single tag for renaming." );
+ ui::alert( g_TextureBrowser.m_parent, "Select a single tag for renaming." );
}
}
gtk_tree_selection_selected_foreach( selection, GtkTreeSelectionForeachFunc( TextureBrowser_selectionHelper ), &selected );
if ( g_slist_length( selected ) == 1 ) { // we only delete a single tag
- auto result = g_TextureBrowser.m_parent.alert( "Are you sure you want to delete the selected tag?", "Delete Tag", ui::alert_type::YESNO, ui::alert_icon::Question );
+ auto result = ui::alert( g_TextureBrowser.m_parent, "Are you sure you want to delete the selected tag?", "Delete Tag", ui::alert_type::YESNO, ui::alert_icon::Question );
if ( result == ui::alert_response::YES ) {
GtkTreeIter iterSelected;
}
}
else {
- g_TextureBrowser.m_parent.alert( "Select a single tag for deletion." );
+ ui::alert( g_TextureBrowser.m_parent, "Select a single tag for deletion." );
}
}
}
void TextureBrowser_showUntagged(){
- auto result = g_TextureBrowser.m_parent.alert( "WARNING! This function might need a lot of memory and time. Are you sure you want to use it?", "Show Untagged", ui::alert_type::YESNO, ui::alert_icon::Warning );
+ auto result = ui::alert( g_TextureBrowser.m_parent, "WARNING! This function might need a lot of memory and time. Are you sure you want to use it?", "Show Untagged", ui::alert_type::YESNO, ui::alert_icon::Warning );
if ( result == ui::alert_response::YES ) {
g_TextureBrowser.m_found_shaders.clear();
// let's put a little comment
globalOutputStream() << "OpenURL: " << url << "\n";
if ( !open_url( url ) ) {
- MainFrame_getWindow().alert( "Failed to launch browser!" );
+ ui::alert( MainFrame_getWindow(), "Failed to launch browser!" );
}
}
if ( SetupListening() == false ) {
const char* msg = "Failed to get a listening socket on port 39000.\nTry running with Build monitoring disabled if you can't fix this.\n";
globalOutputStream() << msg;
- MainFrame_getWindow().alert( msg, "Build monitoring", ui::alert_type::OK, ui::alert_icon::Error );
+ ui::alert( MainFrame_getWindow(), msg, "Build monitoring", ui::alert_type::OK, ui::alert_icon::Error );
return;
}
// set the timer for timeouts and step cancellation
msg << reinterpret_cast<const char*>( g_ptr_array_index( m_pCmd, m_iCurrentStep ) );
msg << "\nCheck that the file exists and that you don't run out of system resources.\n";
globalOutputStream() << msg.c_str();
- MainFrame_getWindow().alert( msg.c_str(), "Build monitoring", ui::alert_type::OK, ui::alert_icon::Error );
+ ui::alert( MainFrame_getWindow(), msg.c_str(), "Build monitoring", ui::alert_type::OK, ui::alert_icon::Error );
return;
}
// re-initialise the debug window
case EBeginStep:
// timeout: if we don't get an incoming connection fast enough, go back to idle
if ( g_timer_elapsed( m_pTimer, NULL ) > g_WatchBSP_Timeout ) {
- MainFrame_getWindow().alert( "The connection timed out, assuming the build process failed\nMake sure you are using a networked version of Q3Map?\nOtherwise you need to disable BSP Monitoring in prefs.", "BSP process monitoring", ui::alert_type::OK );
+ ui::alert( MainFrame_getWindow(), "The connection timed out, assuming the build process failed\nMake sure you are using a networked version of Q3Map?\nOtherwise you need to disable BSP Monitoring in prefs.", "BSP process monitoring", ui::alert_type::OK );
EndMonitoringLoop();
#if 0
if ( m_bBSPPlugin ) {
StringOutputStream msg;
msg << "Failed to execute the following command: " << cmd.c_str() << cmdline.c_str();
globalOutputStream() << msg.c_str();
- MainFrame_getWindow().alert( msg.c_str(), "Build monitoring", ui::alert_type::OK, ui::alert_icon::Error );
+ ui::alert( MainFrame_getWindow(), msg.c_str(), "Build monitoring", ui::alert_type::OK, ui::alert_icon::Error );
}
}
EndMonitoringLoop();
if ( m_eState != EIdle ) {
globalOutputStream() << "WatchBSP got a monitoring request while not idling...\n";
// prompt the user, should we cancel the current process and go ahead?
- if ( MainFrame_getWindow().alert( "I am already monitoring a Build process.\nDo you want me to override and start a new compilation?",
+ if ( ui::alert( MainFrame_getWindow(), "I am already monitoring a Build process.\nDo you want me to override and start a new compilation?",
"Build process monitoring", ui::alert_type::YESNO ) == ui::alert_response::YES ) {
// disconnect and set EIdle state
Reset();
void WXY_BackgroundSelect( void ){
bool brushesSelected = Scene_countSelectedBrushes( GlobalSceneGraph() ) != 0;
if ( !brushesSelected ) {
- ui::root.window().alert( "You have to select some brushes to get the bounding box for.\n",
+ ui::alert( ui::root, "You have to select some brushes to get the bounding box for.\n",
"No selection", ui::alert_type::OK, ui::alert_icon::Error );
return;
}