/*
* ChunkRowExecState.java
*
* Copyright (C) 2009-16 by RStudio, Inc.
*
* Unless you have received this program directly from RStudio pursuant
* to the terms of a commercial license agreement with RStudio, then
* this program is licensed to you under the terms of version 3 of the
* GNU Affero General Public License. This program is distributed WITHOUT
* ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
* AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
*
*/
package org.rstudio.studio.client.workbench.views.source.editors.text;
import org.rstudio.studio.client.workbench.views.source.editors.text.ace.AceEditorNative;
import org.rstudio.studio.client.workbench.views.source.editors.text.ace.Anchor;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Timer;
public class ChunkRowExecState
{
public ChunkRowExecState(final AceEditorNative editor, int row, int state,
Command onRemoved)
{
anchor_ = Anchor.createAnchor(editor.getSession().getDocument(), row, 0);
editor_ = editor;
row_ = row;
state_ = state;
onRemoved_ = onRemoved;
anchor_.addOnChangeHandler(new Command()
{
@Override
public void execute()
{
// no work if anchor hasn't changed rows
if (getRow() == anchor_.getRow())
return;
// if we're just cleaning up this line, finish the cleanup
// immediately rather than trying to shift
if (state_ == LINE_RESTING || state_ == LINE_ERROR)
{
detach();
return;
}
// remove all cumulative state from the old line and reapply to
// the new line
removeClazz();
row_ = anchor_.getRow();
for (int i = LINE_QUEUED; i <= state_; i++)
{
addClazz(i);
}
}
});
addClazz(state_);
}
// Public methods ----------------------------------------------------------
public int getRow()
{
return row_;
}
public void setRow(int row)
{
row_ = row;
}
public void detach()
{
resetTimer();
removeClazz();
anchor_.detach();
if (onRemoved_ != null)
onRemoved_.execute();
}
public int getState()
{
return state_;
}
public static String getClazz(int state)
{
switch (state)
{
case LINE_QUEUED:
return LINE_QUEUED_CLASS;
case LINE_EXECUTED:
return LINE_EXECUTED_CLASS;
case LINE_RESTING:
return LINE_RESTING_CLASS;
case LINE_ERROR:
return LINE_ERROR_CLASS;
}
return "";
}
public void setState(int state)
{
// ignore if already at this state
if (state_ == state)
return;
// if the moving to the error state, clean other states
if (state == LINE_ERROR)
removeClazz();
// if this is the error state, there's no transition to the resting state
if (state_ == LINE_ERROR && state == LINE_RESTING)
return;
state_ = state;
if (state_ == LINE_RESTING)
{
timer_ = new Timer()
{
@Override
public void run()
{
addClazz(state_);
scheduleDismiss();
}
};
timer_.schedule(LINGER_MS);
}
else
{
addClazz(state_);
}
}
// Private methods ---------------------------------------------------------
private void addClazz(int state)
{
editor_.getRenderer().addGutterDecoration(getRow() - 1, getClazz(state));
}
private void removeClazz()
{
for (int i = LINE_QUEUED; i <= state_; i++)
{
editor_.getRenderer().removeGutterDecoration(
getRow() - 1, getClazz(i));
}
}
private void scheduleDismiss()
{
resetTimer();
timer_ = new Timer()
{
@Override
public void run()
{
detach();
}
};
timer_.schedule(FADE_MS);
}
private void resetTimer()
{
if (timer_ != null && timer_.isRunning())
{
timer_.cancel();
timer_ = null;
}
}
private int row_;
private int state_;
private final Anchor anchor_;
private final AceEditorNative editor_;
private final Command onRemoved_;
private Timer timer_;
private final static int LINGER_MS = 250;
private final static int FADE_MS = 400;
public final static String LINE_QUEUED_CLASS = "ace_chunk-queued-line";
public final static String LINE_EXECUTED_CLASS = "ace_chunk-executed-line";
public final static String LINE_RESTING_CLASS = "ace_chunk-resting-line";
public final static String LINE_ERROR_CLASS = "ace_chunk-error-line";
public final static int LINE_QUEUED = 0;
public final static int LINE_EXECUTED = 1;
public final static int LINE_RESTING = 2;
public final static int LINE_ERROR = 3;
public final static int LINE_NONE = 4;
}