mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-02 03:00:23 +03:00
Git plugin more WIP.
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
#include <eepp/ui/uipopupmenu.hpp>
|
||||
#include <eepp/ui/uiscenenode.hpp>
|
||||
#include <eepp/ui/uithememanager.hpp>
|
||||
#include <eepp/window/input.hpp>
|
||||
#include <eepp/window/window.hpp>
|
||||
|
||||
namespace EE { namespace UI {
|
||||
|
||||
@@ -58,6 +60,17 @@ bool UIPopUpMenu::show() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void UIPopUpMenu::showAtScreenPosition( Vector2f pos ) {
|
||||
nodeToWorldTranslation( pos );
|
||||
UIMenu::findBestMenuPos( pos, this );
|
||||
setPixelsPosition( pos );
|
||||
show();
|
||||
}
|
||||
|
||||
void UIPopUpMenu::showOverMouseCursor() {
|
||||
showAtScreenPosition( getUISceneNode()->getWindow()->getInput()->getMousePosf() );
|
||||
}
|
||||
|
||||
bool UIPopUpMenu::hide() {
|
||||
if ( isVisible() && !mHidingAction ) {
|
||||
if ( NULL != getUISceneNode() &&
|
||||
|
||||
+15
-16
@@ -258,21 +258,21 @@ UIWidget* UITreeView::updateCell( const int& rowIndex, const ModelIndex& index,
|
||||
|
||||
bool hasChilds = false;
|
||||
|
||||
if ( widget->isType( UI_TYPE_TREEVIEW_CELL ) ) {
|
||||
if ( widget->isType( UI_TYPE_TREEVIEW_CELL ) &&
|
||||
index.column() == (Int64)getModel()->treeColumn() ) {
|
||||
UITreeViewCell* tcell = widget->asType<UITreeViewCell>();
|
||||
UIImage* image = widget->asType<UITreeViewCell>()->getImage();
|
||||
|
||||
Float minIndent =
|
||||
!mExpandersAsIcons && mExpandIcon && mContractIcon
|
||||
? eemax( mExpandIcon->getSize( mExpanderIconSize )->getPixelsSize().getWidth(),
|
||||
mContractIcon->getSize( mExpanderIconSize )
|
||||
->getPixelsSize()
|
||||
.getWidth() ) +
|
||||
PixelDensity::dpToPx( image->getLayoutMargin().Right )
|
||||
: 0;
|
||||
Float minIndent = 0;
|
||||
if ( !mExpandersAsIcons && mExpandIcon && mContractIcon ) {
|
||||
minIndent =
|
||||
eemax(
|
||||
mExpandIcon->getSize( mExpanderIconSize )->getPixelsSize().getWidth(),
|
||||
mContractIcon->getSize( mExpanderIconSize )->getPixelsSize().getWidth() ) +
|
||||
image->getLayoutPixelsMargin().Right;
|
||||
}
|
||||
|
||||
if ( index.column() == (Int64)getModel()->treeColumn() )
|
||||
tcell->setIndentation( minIndent + getIndentWidth() * indentLevel );
|
||||
Float indentation = minIndent + getIndentWidth() * indentLevel;
|
||||
|
||||
hasChilds = getModel()->rowCount( index ) > 0;
|
||||
|
||||
@@ -286,15 +286,14 @@ UIWidget* UITreeView::updateCell( const int& rowIndex, const ModelIndex& index,
|
||||
image->setVisible( true );
|
||||
image->setPixelsSize( drawable ? drawable->getPixelsSize() : Sizef( 0, 0 ) );
|
||||
image->setDrawable( drawable );
|
||||
if ( !mExpandersAsIcons ) {
|
||||
tcell->setIndentation(
|
||||
tcell->getIndentation() - image->getPixelsSize().getWidth() -
|
||||
PixelDensity::dpToPx( image->getLayoutMargin().Right ) );
|
||||
}
|
||||
if ( !mExpandersAsIcons )
|
||||
indentation = indentation - image->getPixelsSize().getWidth();
|
||||
}
|
||||
} else {
|
||||
image->setVisible( false );
|
||||
}
|
||||
|
||||
tcell->setIndentation( indentation );
|
||||
}
|
||||
|
||||
if ( hasChilds && mExpandersAsIcons && cell->hasIcon() ) {
|
||||
|
||||
@@ -134,17 +134,50 @@ std::string Git::setSafeDirectory( const std::string& projectDir ) const {
|
||||
return buf;
|
||||
}
|
||||
|
||||
Git::Result Git::pull( const std::string& projectDir ) {
|
||||
std::string buf;
|
||||
Git::Result res;
|
||||
int retCode = git( "pull", projectDir, buf );
|
||||
res.returnCode = retCode;
|
||||
res.result = buf;
|
||||
return res;
|
||||
}
|
||||
|
||||
Git::CheckoutResult Git::checkout( const std::string& branch,
|
||||
const std::string& projectDir ) const {
|
||||
std::string buf;
|
||||
int retCode = git( String::format( "checkout %s", branch ), projectDir, buf );
|
||||
Git::CheckoutResult res;
|
||||
if ( EXIT_SUCCESS != retCode ) {
|
||||
res.returnCode = retCode;
|
||||
res.error = buf;
|
||||
} else {
|
||||
res.branch = branch;
|
||||
}
|
||||
res.returnCode = retCode;
|
||||
res.result = buf;
|
||||
res.branch = branch;
|
||||
return res;
|
||||
}
|
||||
|
||||
Git::Result Git::add( const std::string& file, const std::string& projectDir ) {
|
||||
std::string buf;
|
||||
int retCode = git( String::format( "add --force -- %s", file ), projectDir, buf );
|
||||
Git::CheckoutResult res;
|
||||
res.returnCode = retCode;
|
||||
res.result = buf;
|
||||
return res;
|
||||
}
|
||||
|
||||
Git::Result Git::restore( const std::string& file, const std::string& projectDir ) {
|
||||
std::string buf;
|
||||
int retCode = git( String::format( "restore %s", file ), projectDir, buf );
|
||||
Git::CheckoutResult res;
|
||||
res.returnCode = retCode;
|
||||
res.result = buf;
|
||||
return res;
|
||||
}
|
||||
|
||||
Git::Result Git::reset( const std::string& file, const std::string& projectDir ) {
|
||||
std::string buf;
|
||||
int retCode = git( String::format( "reset -q HEAD -- %s", file ), projectDir, buf );
|
||||
Git::CheckoutResult res;
|
||||
res.returnCode = retCode;
|
||||
res.result = buf;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -157,12 +190,9 @@ Git::CheckoutResult Git::checkoutNewBranch( const std::string& newBranch,
|
||||
args += " " + fromBranch;
|
||||
int retCode = git( args, projectDir, buf );
|
||||
Git::CheckoutResult res;
|
||||
if ( EXIT_SUCCESS != retCode ) {
|
||||
res.returnCode = retCode;
|
||||
res.error = buf;
|
||||
} else {
|
||||
res.branch = buf;
|
||||
}
|
||||
res.returnCode = retCode;
|
||||
res.result = buf;
|
||||
res.branch = buf;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -135,8 +135,12 @@ class Git {
|
||||
};
|
||||
|
||||
struct Result {
|
||||
std::string error;
|
||||
std::string result;
|
||||
int returnCode = 0;
|
||||
|
||||
bool success() const { return returnCode == EXIT_SUCCESS; }
|
||||
|
||||
bool fail() const { return !success(); }
|
||||
};
|
||||
|
||||
struct CheckoutResult : public Result {
|
||||
@@ -195,6 +199,12 @@ class Git {
|
||||
|
||||
Status status( bool recurseSubmodules, const std::string& projectDir = "" );
|
||||
|
||||
Result add( const std::string& file, const std::string& projectDir = "" );
|
||||
|
||||
Result restore( const std::string& file, const std::string& projectDir = "" );
|
||||
|
||||
Result reset( const std::string& file, const std::string& projectDir = "" );
|
||||
|
||||
bool setProjectPath( const std::string& projectPath );
|
||||
|
||||
const std::string& getGitPath() const;
|
||||
@@ -205,6 +215,8 @@ class Git {
|
||||
|
||||
std::string setSafeDirectory( const std::string& projectDir ) const;
|
||||
|
||||
Result pull( const std::string& projectDir = "" );
|
||||
|
||||
CheckoutResult checkout( const std::string& branch, const std::string& projectDir = "" ) const;
|
||||
|
||||
CheckoutResult checkoutNewBranch( const std::string& newBranch,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <eepp/ui/doc/syntaxdefinitionmanager.hpp>
|
||||
#include <eepp/ui/uidropdownlist.hpp>
|
||||
#include <eepp/ui/uiiconthememanager.hpp>
|
||||
#include <eepp/ui/uiloader.hpp>
|
||||
#include <eepp/ui/uipopupmenu.hpp>
|
||||
#include <eepp/ui/uistackwidget.hpp>
|
||||
#include <eepp/ui/uistyle.hpp>
|
||||
@@ -128,8 +129,7 @@ class GitBranchModel : public Model {
|
||||
if ( index.column() == (Int64)treeColumn() ) {
|
||||
if ( index.hasParent() ) {
|
||||
Git::Branch* branch = static_cast<Git::Branch*>( index.internalData() );
|
||||
return mPlugin->getUISceneNode()->findIcon(
|
||||
branch->type == Git::RefType::Tag ? GIT_TAG : GIT_REPO );
|
||||
return mPlugin->findIcon( branch->type == Git::RefType::Tag ? GIT_TAG : GIT_REPO );
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@@ -371,8 +371,7 @@ class GitStatusModel : public Model {
|
||||
case ModelRole::Icon: {
|
||||
if ( (Int64)treeColumn() == index.column() ) {
|
||||
if ( index.internalId() == Repo ) {
|
||||
return Variant(
|
||||
mPlugin->getManager()->getUISceneNode()->findIcon( "repo" ) );
|
||||
return Variant( mPlugin->findIcon( "repo" ) );
|
||||
} else if ( index.internalId() == GitFile ) {
|
||||
const Git::DiffFile& s = mStatus[index.parent().parent().row()]
|
||||
.type[index.parent().row()]
|
||||
@@ -396,6 +395,14 @@ class GitStatusModel : public Model {
|
||||
|
||||
virtual bool classModelRoleEnabled() { return true; }
|
||||
|
||||
const DiffFile* file( const ModelIndex& index ) const {
|
||||
if ( index.internalId() != GitFile )
|
||||
return nullptr;
|
||||
return &mStatus[index.parent().parent().row()]
|
||||
.type[index.parent().row()]
|
||||
.files[index.row()];
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<RepoStatus> mStatus;
|
||||
GitPlugin* mPlugin{ nullptr };
|
||||
@@ -573,10 +580,7 @@ void GitPlugin::updateStatusBarSync() {
|
||||
mStatusButton->setParent( mStatusBar );
|
||||
mStatusButton->setId( "status_git" );
|
||||
mStatusButton->setClass( "status_but" );
|
||||
mStatusButton->setIcon( getManager()
|
||||
->getUISceneNode()
|
||||
->findIcon( "source-control" )
|
||||
->getSize( PixelDensity::dpToPxI( 10 ) ) );
|
||||
mStatusButton->setIcon( iconDrawable( "source-control", 10 ) );
|
||||
mStatusButton->reloadStyle( true, true );
|
||||
mStatusButton->getTextBox()->setUsingCustomStyling( true );
|
||||
auto childCount = mStatusBar->getChildCount();
|
||||
@@ -839,6 +843,83 @@ void GitPlugin::blame( UICodeEditor* editor ) {
|
||||
} );
|
||||
}
|
||||
|
||||
void GitPlugin::checkout( const std::string& branch ) {
|
||||
if ( !mGit )
|
||||
return;
|
||||
mLoader->setVisible( true );
|
||||
mThreadPool->run( [this, branch] {
|
||||
auto result = mGit->checkout( branch );
|
||||
if ( result.success() ) {
|
||||
{
|
||||
Lock l( mGitBranchMutex );
|
||||
mGitBranch = branch;
|
||||
}
|
||||
if ( mBranchesTree->getModel() )
|
||||
mBranchesTree->getModel()->invalidate( Model::DontInvalidateIndexes );
|
||||
} else {
|
||||
showMessage( LSPMessageType::Warning, result.result );
|
||||
}
|
||||
getUISceneNode()->runOnMainThread( [this] { mLoader->setVisible( false ); } );
|
||||
} );
|
||||
}
|
||||
|
||||
void GitPlugin::pull() {
|
||||
if ( !mGit )
|
||||
return;
|
||||
mLoader->setVisible( true );
|
||||
mThreadPool->run( [this] {
|
||||
auto res = mGit->pull();
|
||||
if ( res.fail() )
|
||||
showMessage( LSPMessageType::Warning, res.result );
|
||||
getUISceneNode()->runOnMainThread( [this] { mLoader->setVisible( false ); } );
|
||||
} );
|
||||
}
|
||||
|
||||
void GitPlugin::stage( const std::string& file ) {
|
||||
if ( !mGit )
|
||||
return;
|
||||
mLoader->setVisible( true );
|
||||
mThreadPool->run( [this, file] {
|
||||
auto res = mGit->add( file );
|
||||
if ( res.fail() )
|
||||
showMessage( LSPMessageType::Warning, res.result );
|
||||
getUISceneNode()->runOnMainThread( [this] { mLoader->setVisible( false ); } );
|
||||
updateStatus( true );
|
||||
} );
|
||||
}
|
||||
|
||||
void GitPlugin::unstage( const std::string& file ) {
|
||||
if ( !mGit )
|
||||
return;
|
||||
mLoader->setVisible( true );
|
||||
mThreadPool->run( [this, file] {
|
||||
auto res = mGit->reset( file );
|
||||
if ( res.fail() )
|
||||
showMessage( LSPMessageType::Warning, res.result );
|
||||
getUISceneNode()->runOnMainThread( [this] { mLoader->setVisible( false ); } );
|
||||
updateStatus( true );
|
||||
} );
|
||||
}
|
||||
|
||||
void GitPlugin::discard( const std::string& file ) {
|
||||
if ( !mGit )
|
||||
return;
|
||||
mLoader->setVisible( true );
|
||||
mThreadPool->run( [this, file] {
|
||||
auto res = mGit->restore( file );
|
||||
if ( res.fail() )
|
||||
showMessage( LSPMessageType::Warning, res.result );
|
||||
getUISceneNode()->runOnMainThread( [this] { mLoader->setVisible( false ); } );
|
||||
updateStatus( true );
|
||||
} );
|
||||
}
|
||||
|
||||
void GitPlugin::openFile( const std::string& file ) {
|
||||
getUISceneNode()->runOnMainThread( [this, file] {
|
||||
mManager->getLoadFileFn()( mGit->getProjectPath() + file, []( auto, auto ) {} );
|
||||
} );
|
||||
}
|
||||
|
||||
void GitPlugin::onRegister( UICodeEditor* editor ) {
|
||||
PluginBase::onRegister( editor );
|
||||
|
||||
@@ -858,6 +939,8 @@ void GitPlugin::onRegister( UICodeEditor* editor ) {
|
||||
if ( mTab )
|
||||
mTab->setTabSelected();
|
||||
} );
|
||||
doc.setCommand( "git-pull", [this]() { pull(); } );
|
||||
doc.setCommand( "git-checkout", [this]() { checkout( mGitBranch ); } );
|
||||
}
|
||||
|
||||
void GitPlugin::onUnregister( UICodeEditor* editor ) {
|
||||
@@ -878,8 +961,7 @@ bool GitPlugin::onCreateContextMenu( UICodeEditor*, UIPopUpMenu* menu, const Vec
|
||||
const std::string& icon = "" ) {
|
||||
subMenu
|
||||
->add( i18n( txtKey, txtVal ),
|
||||
!icon.empty() ? mManager->getUISceneNode()->findIcon( icon )->getSize(
|
||||
PixelDensity::dpToPxI( 12 ) )
|
||||
!icon.empty() ? findIcon( icon )->getSize( PixelDensity::dpToPxI( 12 ) )
|
||||
: nullptr,
|
||||
KeyBindings::keybindFormat( mKeyBindings[txtKey] ) )
|
||||
->setId( txtKey );
|
||||
@@ -946,13 +1028,12 @@ void GitPlugin::buildSidePanelTab() {
|
||||
return;
|
||||
if ( mSidePanel == nullptr )
|
||||
getUISceneNode()->bind( "panel", mSidePanel );
|
||||
UIIcon* icon = getUISceneNode()->findIcon( "source-control" );
|
||||
UIIcon* icon = findIcon( "source-control" );
|
||||
UIWidget* node = getUISceneNode()->loadLayoutFromString(
|
||||
R"html(
|
||||
<RelativeLayout id="git_panel" lw="mp" lh="mp">
|
||||
<vbox id="git_content" lw="mp" lh="mp">
|
||||
<DropDownList id="git_panel_switcher" lw="mp" lh="22dp" border-type="inside"
|
||||
border-right-width="0" border-left-width="0" border-top-width="0" border-bottom-width="0" />
|
||||
<DropDownList id="git_panel_switcher" lw="mp" lh="22dp" border-type="inside" border-right-width="0" border-left-width="0" border-top-width="0" border-bottom-left-radius="0" border-bottom-right-radius="0" />
|
||||
<StackWidget id="git_panel_stack" lw="mp" lh="0" lw8="1">
|
||||
<vbox id="git_branches" lw="mp" lh="wc">
|
||||
<!--
|
||||
@@ -971,9 +1052,10 @@ void GitPlugin::buildSidePanelTab() {
|
||||
</vbox>
|
||||
<TextView id="git_no_content" lw="mp" lh="wc" word-wrap="true" visible="false"
|
||||
text='@string(git_no_git_repo, "Current folder is not a Git repository.")' padding="16dp" />
|
||||
<Loader margin-top="32dp" id="git_panel_loader" inderterminate="true" lw="24dp" lh="24dp" outline-thickness="2dp" visible="false" layout_gravity="bottom|right" margin-bottom="24dp" margin-right="24dp" />
|
||||
</RelativeLayout>
|
||||
)html" );
|
||||
mTab = mSidePanel->add( getUISceneNode()->i18n( "source_control", "Source Control" ), node,
|
||||
mTab = mSidePanel->add( i18n( "source_control", "Source Control" ), node,
|
||||
icon ? icon->getSize( PixelDensity::dpToPx( 12 ) ) : nullptr );
|
||||
mTab->setId( "source_control" );
|
||||
mTab->setTextAsFallback( true );
|
||||
@@ -984,10 +1066,12 @@ void GitPlugin::buildSidePanelTab() {
|
||||
node->bind( "git_status_tree", mStatusTree );
|
||||
node->bind( "git_content", mGitContentView );
|
||||
node->bind( "git_no_content", mGitNoContentView );
|
||||
node->bind( "git_panel_loader", mLoader );
|
||||
|
||||
mBranchesTree->setAutoExpandOnSingleColumn( true );
|
||||
mBranchesTree->setHeadersVisible( false );
|
||||
mBranchesTree->setIndentWidth( 0 );
|
||||
mBranchesTree->setExpandersAsIcons( true );
|
||||
mBranchesTree->setIndentWidth( PixelDensity::dpToPx( 16 ) );
|
||||
mBranchesTree->on( Event::OnModelEvent, [this]( const Event* event ) {
|
||||
const ModelEvent* modelEvent = static_cast<const ModelEvent*>( event );
|
||||
if ( !modelEvent->getModelIndex().hasParent() )
|
||||
@@ -998,22 +1082,14 @@ void GitPlugin::buildSidePanelTab() {
|
||||
|
||||
switch ( modelEvent->getModelEventType() ) {
|
||||
case EE::UI::Abstract::ModelEventType::Open: {
|
||||
auto result = mGit->checkout( branch->name );
|
||||
if ( result.returnCode == EXIT_SUCCESS ) {
|
||||
{
|
||||
Lock l( mGitBranchMutex );
|
||||
mGitBranch = branch->name;
|
||||
}
|
||||
if ( mBranchesTree->getModel() )
|
||||
mBranchesTree->getModel()->invalidate( Model::DontInvalidateIndexes );
|
||||
} else {
|
||||
showMessage( LSPMessageType::Warning, result.error );
|
||||
}
|
||||
checkout( branch->name );
|
||||
break;
|
||||
}
|
||||
case EE::UI::Abstract::ModelEventType::OpenTree:
|
||||
case EE::UI::Abstract::ModelEventType::CloseTree:
|
||||
case EE::UI::Abstract::ModelEventType::OpenMenu:
|
||||
case EE::UI::Abstract::ModelEventType::OpenMenu: {
|
||||
openBranchMenu( *branch );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} );
|
||||
@@ -1031,6 +1107,109 @@ void GitPlugin::buildSidePanelTab() {
|
||||
|
||||
mStatusTree->setAutoColumnsWidth( true );
|
||||
mStatusTree->setHeadersVisible( false );
|
||||
mStatusTree->setExpandersAsIcons( true );
|
||||
mStatusTree->on( Event::OnModelEvent, [this]( const Event* event ) {
|
||||
const ModelEvent* modelEvent = static_cast<const ModelEvent*>( event );
|
||||
if ( modelEvent->getModel() == nullptr ||
|
||||
modelEvent->getModelIndex().internalId() != GitStatusModel::GitFile )
|
||||
return;
|
||||
auto model = static_cast<const GitStatusModel*>( modelEvent->getModel() );
|
||||
const Git::DiffFile* file = model->file( modelEvent->getModelIndex() );
|
||||
if ( file == nullptr )
|
||||
return;
|
||||
|
||||
switch ( modelEvent->getModelEventType() ) {
|
||||
case EE::UI::Abstract::ModelEventType::OpenMenu: {
|
||||
bool focusOnSelection = mStatusTree->getFocusOnSelection();
|
||||
mStatusTree->setFocusOnSelection( false );
|
||||
mStatusTree->getSelection().set( modelEvent->getModelIndex() );
|
||||
mStatusTree->setFocusOnSelection( focusOnSelection );
|
||||
openFileStatusMenu( *file );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
void GitPlugin::openBranchMenu( const Git::Branch& branch ) {
|
||||
UIPopUpMenu* menu = UIPopUpMenu::New();
|
||||
menu->setId( "git_branch_menu" );
|
||||
|
||||
auto addFn = [this, menu]( const std::string& txtKey, const std::string& txtVal,
|
||||
const std::string& icon = "" ) {
|
||||
menu->add( i18n( txtKey, txtVal ), iconDrawable( icon, 12 ),
|
||||
KeyBindings::keybindFormat( mKeyBindings[txtKey] ) )
|
||||
->setId( txtKey );
|
||||
};
|
||||
|
||||
if ( mGitBranch != branch.name ) {
|
||||
addFn( "git-checkout", "Check Out..." );
|
||||
} else {
|
||||
addFn( "git-pull", "Pull", "repo-pull" );
|
||||
}
|
||||
|
||||
std::string name( branch.name );
|
||||
menu->on( Event::OnItemClicked, [this, name]( const Event* event ) {
|
||||
if ( !mGit )
|
||||
return;
|
||||
UIMenuItem* item = event->getNode()->asType<UIMenuItem>();
|
||||
std::string id( item->getId() );
|
||||
mThreadPool->run( [this, id, name]() {
|
||||
if ( id == "git-checkout" ) {
|
||||
checkout( name );
|
||||
} else if ( id == "git-pull" ) {
|
||||
pull();
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
menu->showOverMouseCursor();
|
||||
}
|
||||
|
||||
void GitPlugin::openFileStatusMenu( const Git::DiffFile& file ) {
|
||||
UIPopUpMenu* menu = UIPopUpMenu::New();
|
||||
menu->setId( "git_file_status_menu" );
|
||||
|
||||
auto addFn = [this, menu]( const std::string& txtKey, const std::string& txtVal,
|
||||
const std::string& icon = "" ) {
|
||||
menu->add( i18n( txtKey, txtVal ), iconDrawable( icon, 12 ),
|
||||
KeyBindings::keybindFormat( mKeyBindings[txtKey] ) )
|
||||
->setId( txtKey );
|
||||
};
|
||||
|
||||
addFn( "git-open-file", "Open File" );
|
||||
|
||||
if ( file.statusType != Git::GitStatusType::Staged ) {
|
||||
addFn( "git-stage", "Stage" );
|
||||
} else {
|
||||
addFn( "git-unstage", "Unstage" );
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
addFn( "git-discard", "Discard" );
|
||||
}
|
||||
|
||||
menu->on( Event::OnItemClicked, [this, file]( const Event* event ) {
|
||||
if ( !mGit )
|
||||
return;
|
||||
UIMenuItem* item = event->getNode()->asType<UIMenuItem>();
|
||||
std::string id( item->getId() );
|
||||
mThreadPool->run( [this, id, file]() {
|
||||
if ( id == "git-stage" ) {
|
||||
stage( file.file );
|
||||
} else if ( id == "git-unstage" ) {
|
||||
unstage( file.file );
|
||||
} else if ( id == "git-discard" ) {
|
||||
discard( file.file );
|
||||
} else if ( id == "git-open-file" ) {
|
||||
openFile( file.file );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
menu->showOverMouseCursor();
|
||||
}
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
@@ -103,6 +103,7 @@ class GitPlugin : public PluginBase {
|
||||
std::vector<UIWidget*> mStackMap;
|
||||
UIWidget* mGitContentView{ nullptr };
|
||||
UIWidget* mGitNoContentView{ nullptr };
|
||||
UILoader* mLoader{ nullptr };
|
||||
std::atomic<bool> mRunningUpdateBranches{ false };
|
||||
std::atomic<bool> mRunningUpdateStatus{ false };
|
||||
Mutex mGitBranchMutex;
|
||||
@@ -119,6 +120,18 @@ class GitPlugin : public PluginBase {
|
||||
|
||||
void blame( UICodeEditor* editor );
|
||||
|
||||
void checkout( const std::string& branch );
|
||||
|
||||
void pull();
|
||||
|
||||
void stage( const std::string& file );
|
||||
|
||||
void unstage( const std::string& file );
|
||||
|
||||
void discard( const std::string& file );
|
||||
|
||||
void openFile( const std::string& file );
|
||||
|
||||
void updateStatus( bool force = false );
|
||||
|
||||
void updateStatusBarSync();
|
||||
@@ -132,6 +145,10 @@ class GitPlugin : public PluginBase {
|
||||
void buildSidePanelTab();
|
||||
|
||||
void updateBranchesUI( std::shared_ptr<GitBranchModel> );
|
||||
|
||||
void openBranchMenu( const Git::Branch& branch );
|
||||
|
||||
void openFileStatusMenu( const Git::DiffFile& file );
|
||||
};
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
@@ -1348,12 +1348,9 @@ bool LSPClientPlugin::onCreateContextMenu( UICodeEditor* editor, UIPopUpMenu* me
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
auto addFn = [this, editor, menu]( const std::string& txtKey, const std::string& txtVal,
|
||||
auto addFn = [this, menu]( const std::string& txtKey, const std::string& txtVal,
|
||||
const std::string& icon = "" ) {
|
||||
menu->add( editor->getUISceneNode()->i18n( txtKey, txtVal ),
|
||||
!icon.empty() ? mManager->getUISceneNode()->findIcon( icon )->getSize(
|
||||
PixelDensity::dpToPxI( 12 ) )
|
||||
: nullptr,
|
||||
menu->add( i18n( txtKey, txtVal ), iconDrawable( icon, 12 ),
|
||||
KeyBindings::keybindFormat( mKeyBindings[txtKey] ) )
|
||||
->setId( txtKey );
|
||||
};
|
||||
|
||||
@@ -53,6 +53,15 @@ String Plugin::i18n( const std::string& key, const String& def ) const {
|
||||
return getManager()->getUISceneNode()->i18n( key, def );
|
||||
}
|
||||
|
||||
UIIcon* Plugin::findIcon( const std::string& iconName ) {
|
||||
return getManager()->getUISceneNode()->findIcon( iconName );
|
||||
}
|
||||
|
||||
Drawable* Plugin::iconDrawable( const std::string& iconName, Float dpSize ) {
|
||||
UIIcon* icon = findIcon( iconName );
|
||||
return icon ? icon->getSize( PixelDensity::dpToPx( dpSize ) ) : nullptr;
|
||||
}
|
||||
|
||||
void Plugin::showMessage( LSPMessageType type, const std::string& message,
|
||||
const std::string& title ) {
|
||||
if ( !mManager )
|
||||
|
||||
@@ -41,6 +41,10 @@ class Plugin : public UICodeEditorPlugin {
|
||||
|
||||
String i18n( const std::string& key, const String& def ) const;
|
||||
|
||||
UIIcon* findIcon( const std::string& iconName );
|
||||
|
||||
Drawable* iconDrawable( const std::string& iconName, Float dpSize );
|
||||
|
||||
virtual void onVersionUpgrade( Uint32 /*oldVersion*/, Uint32 /*currentVersion*/ ) {}
|
||||
|
||||
void showMessage( LSPMessageType type, const std::string& message,
|
||||
|
||||
@@ -1529,11 +1529,7 @@ void SettingsMenu::updateDocumentMenu() {
|
||||
}
|
||||
|
||||
void SettingsMenu::showProjectTreeMenu() {
|
||||
Vector2f pos( mApp->getWindow()->getInput()->getMousePosf() );
|
||||
mProjectTreeMenu->nodeToWorldTranslation( pos );
|
||||
UIMenu::findBestMenuPos( pos, mProjectTreeMenu );
|
||||
mProjectTreeMenu->setPixelsPosition( pos );
|
||||
mProjectTreeMenu->show();
|
||||
mProjectTreeMenu->showOverMouseCursor();
|
||||
}
|
||||
|
||||
void SettingsMenu::createProjectTreeMenu() {
|
||||
|
||||
Reference in New Issue
Block a user