218 lines
7.1 KiB
C++
218 lines
7.1 KiB
C++
/*
|
|
Copyright (C) 2001-2006, William Joseph.
|
|
All Rights Reserved.
|
|
|
|
This file is part of GtkRadiant.
|
|
|
|
GtkRadiant is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
GtkRadiant is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GtkRadiant; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "clippertool.h"
|
|
|
|
#include "math/plane.h"
|
|
#include "csg.h"
|
|
#include "iscenegraph.h"
|
|
#include "iselection.h"
|
|
#include "iundo.h"
|
|
#include "mainframe.h"
|
|
#include "camwindow.h"
|
|
#include "xywindow.h"
|
|
|
|
ClipperPoints g_clipper_points;
|
|
bool g_clipper_flipped = false;
|
|
bool g_clipper_quick = false;
|
|
|
|
/* preferences */
|
|
bool g_clipper_caulk = true;
|
|
bool g_clipper_resetFlip = true;
|
|
bool g_clipper_resetPoints = true;
|
|
bool g_clipper_2pointsIn2d = true;
|
|
int g_clipper_doubleclicked_split = 1;
|
|
|
|
bool Clipper_get2pointsIn2d(){
|
|
return g_clipper_2pointsIn2d;
|
|
}
|
|
|
|
void ClipperModeQuick(){
|
|
g_clipper_quick = true;
|
|
ClipperMode(); //enable
|
|
}
|
|
|
|
|
|
bool Clipper_ok_plane(){
|
|
return GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip && g_clipper_points._count > 1 && plane3_valid( plane3_for_points( g_clipper_points._points ) );
|
|
}
|
|
|
|
bool Clipper_ok(){
|
|
return GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip && g_clipper_points._count > 0;
|
|
}
|
|
|
|
void Clipper_update(){
|
|
Scene_BrushSetClipPlane( GlobalSceneGraph(), g_clipper_points, g_clipper_flipped );
|
|
SceneChangeNotify();
|
|
}
|
|
|
|
void Clipper_setPlanePoints( const ClipperPoints& points ){
|
|
g_clipper_points = points;
|
|
Clipper_update();
|
|
}
|
|
|
|
const ClipperPoints& Clipper_getPlanePoints(){
|
|
return g_clipper_points;
|
|
}
|
|
|
|
#include "gtkutil/idledraw.h"
|
|
void Clipper_BoundsChanged(){
|
|
if ( Clipper_ok_plane() )
|
|
Clipper_update();
|
|
}
|
|
|
|
IdleDraw g_idle_clipper_update = IdleDraw( FreeCaller<Clipper_BoundsChanged>() );
|
|
|
|
void Clipper_BoundsChanged_Queue(){
|
|
g_idle_clipper_update.queueDraw();
|
|
}
|
|
|
|
void Clipper_SelectionChanged( const Selectable& selectable ){
|
|
Clipper_BoundsChanged_Queue();
|
|
}
|
|
|
|
|
|
void Clipper_modeChanged( bool isClipper ){
|
|
if( g_pParentWnd ){
|
|
g_pParentWnd->forEachXYWnd( [isClipper]( XYWnd* xywnd ){
|
|
isClipper? xywnd->GetWidget()->setCursor( Qt::CursorShape::PointingHandCursor ) : xywnd->GetWidget()->unsetCursor();
|
|
} );
|
|
if( g_pParentWnd->GetCamWnd() )
|
|
isClipper? CamWnd_getWidget( *g_pParentWnd->GetCamWnd() )->setCursor( Qt::CursorShape::PointingHandCursor ) : CamWnd_getWidget( *g_pParentWnd->GetCamWnd() )->unsetCursor();
|
|
}
|
|
|
|
if( g_clipper_resetFlip )
|
|
g_clipper_flipped = false;
|
|
if( !isClipper )
|
|
g_clipper_quick = false;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Clipper_do( bool split ){
|
|
Scene_BrushSplitByPlane( GlobalSceneGraph(), g_clipper_points, g_clipper_flipped, g_clipper_caulk, split );
|
|
if( g_clipper_resetPoints ){
|
|
GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eClip ); /* reset points this way */
|
|
if( g_clipper_resetFlip )
|
|
g_clipper_flipped = false;
|
|
}
|
|
if( g_clipper_quick )
|
|
ClipperMode(); //disable
|
|
}
|
|
|
|
|
|
void Clipper_doClip(){
|
|
if ( Clipper_ok() ) {
|
|
UndoableCommand undo( "clipperClip" );
|
|
Clipper_do( false );
|
|
}
|
|
}
|
|
|
|
void Clipper_doSplit(){
|
|
if ( Clipper_ok() ) {
|
|
UndoableCommand undo( "clipperSplit" );
|
|
Clipper_do( true );
|
|
}
|
|
}
|
|
|
|
void Clipper_doFlip(){
|
|
if( Clipper_ok_plane() ){
|
|
g_clipper_flipped = !g_clipper_flipped;
|
|
Clipper_update();
|
|
}
|
|
}
|
|
|
|
#include "timer.h"
|
|
Timer g_clipper_timer;
|
|
bool g_clipper_doubleclicked = false;
|
|
std::size_t g_clipper_doubleclicked_point = 0; //monitor clicking the same point twice
|
|
|
|
void Clipper_tryDoubleclick(){ //onMouseDown
|
|
g_clipper_doubleclicked = g_clipper_timer.elapsed_msec() < 200;
|
|
g_clipper_timer.start();
|
|
g_clipper_doubleclicked_point = g_clipper_points._count;
|
|
}
|
|
|
|
void Clipper_tryDoubleclickedCut(){ //onMouseUp
|
|
if( g_clipper_doubleclicked && g_clipper_doubleclicked_point == g_clipper_points._count ){
|
|
g_clipper_doubleclicked = false;
|
|
return g_clipper_doubleclicked_split? Clipper_doSplit() : Clipper_doClip();
|
|
}
|
|
}
|
|
|
|
#include "preferencesystem.h"
|
|
#include "stringio.h"
|
|
#include "preferences.h"
|
|
#include "commands.h"
|
|
#include "signal/isignal.h"
|
|
void Clipper_constructPreferences( PreferencesPage& page ){
|
|
page.appendCheckBox( "", "Caulk Clipper Cuts", g_clipper_caulk );
|
|
QCheckBox* resetFlip = page.appendCheckBox( "", "Reset Flipped State", g_clipper_resetFlip );
|
|
QCheckBox* resetPoints = page.appendCheckBox( "", "Reset Points on Split", g_clipper_resetPoints );
|
|
Widget_connectToggleDependency( resetFlip, resetPoints );
|
|
page.appendCheckBox( "", "2 Points in 2D Views", g_clipper_2pointsIn2d );
|
|
{
|
|
const char* dowhat[] = { "Clip ", "Split", };
|
|
page.appendRadio(
|
|
"On DoubleClick do: ",
|
|
StringArrayRange( dowhat ),
|
|
IntImportCaller( g_clipper_doubleclicked_split ),
|
|
IntExportCaller( g_clipper_doubleclicked_split )
|
|
);
|
|
}
|
|
}
|
|
void Clipper_constructPage( PreferenceGroup& group ){
|
|
PreferencesPage page( group.createPage( "Clipper", "Clipper Tool Settings" ) );
|
|
Clipper_constructPreferences( page );
|
|
}
|
|
void Clipper_registerPreferencesPage(){
|
|
PreferencesDialog_addSettingsPage( FreeCaller1<PreferenceGroup&, Clipper_constructPage>() );
|
|
}
|
|
|
|
void Clipper_registerCommands(){
|
|
GlobalCommands_insert( "ClipperClip", FreeCaller<Clipper_doClip>(), QKeySequence( "Return" ) );
|
|
GlobalCommands_insert( "ClipperSplit", FreeCaller<Clipper_doSplit>(), QKeySequence( "Shift+Return" ) );
|
|
GlobalCommands_insert( "ClipperFlip", FreeCaller<Clipper_doFlip>(), QKeySequence( "Ctrl+Return" ) );
|
|
}
|
|
|
|
SignalHandlerId ClipperTool_boundsChanged;
|
|
|
|
void Clipper_Construct(){
|
|
Clipper_registerCommands();
|
|
GlobalPreferenceSystem().registerPreference( "ClipperCaulk", BoolImportStringCaller( g_clipper_caulk ), BoolExportStringCaller( g_clipper_caulk ) );
|
|
GlobalPreferenceSystem().registerPreference( "ClipperResetFlip", BoolImportStringCaller( g_clipper_resetFlip ), BoolExportStringCaller( g_clipper_resetFlip ) );
|
|
GlobalPreferenceSystem().registerPreference( "ClipperResetPoints", BoolImportStringCaller( g_clipper_resetPoints ), BoolExportStringCaller( g_clipper_resetPoints ) );
|
|
GlobalPreferenceSystem().registerPreference( "Clipper2PointsIn2D", BoolImportStringCaller( g_clipper_2pointsIn2d ), BoolExportStringCaller( g_clipper_2pointsIn2d ) );
|
|
GlobalPreferenceSystem().registerPreference( "ClipperDoubleclickedSplit", IntImportStringCaller( g_clipper_doubleclicked_split ), IntExportStringCaller( g_clipper_doubleclicked_split ) );
|
|
Clipper_registerPreferencesPage();
|
|
|
|
typedef FreeCaller1<const Selectable&, Clipper_SelectionChanged> ClipperSelectionChangedCaller;
|
|
GlobalSelectionSystem().addSelectionChangeCallback( ClipperSelectionChangedCaller() );
|
|
|
|
ClipperTool_boundsChanged = GlobalSceneGraph().addBoundsChangedCallback( FreeCaller<Clipper_BoundsChanged_Queue>() );
|
|
}
|
|
|
|
void Clipper_Destroy(){
|
|
GlobalSceneGraph().removeBoundsChangedCallback( ClipperTool_boundsChanged );
|
|
}
|