Skip to content
This repository has been archived by the owner on Apr 3, 2018. It is now read-only.

Commit

Permalink
LANG: Added Build elements decorator, and navigator refresh.
Browse files Browse the repository at this point in the history
  • Loading branch information
bruno-medeiros committed Jul 3, 2015
1 parent 23ad055 commit 795de4a
Show file tree
Hide file tree
Showing 12 changed files with 430 additions and 158 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public BuildManager(BuildModel buildModel) {
this.buildModel = buildModel; this.buildModel = buildModel;
} }


public BuildModel getBuildModel() {
return buildModel;
}

public ProjectBuildInfo getBuildInfo(IProject project) { public ProjectBuildInfo getBuildInfo(IProject project) {
return buildModel.getProjectInfo(project); return buildModel.getProjectInfo(project);
} }
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions plugin_ide.ui/src-lang/melnorme/lang/ide/ui/LangImages.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ protected static ImageDescriptor createUnmanaged(String prefix, String name) {
public static final ImageDescriptor DESC_OVR_ALIAS = createUnmanaged(LANG_OVERLAYS, "ovr_alias_arrow.png"); public static final ImageDescriptor DESC_OVR_ALIAS = createUnmanaged(LANG_OVERLAYS, "ovr_alias_arrow.png");




public static final ImageDescriptor OVR_CHECKED = createUnmanaged(LANG_OVERLAYS, "ovr_checked.png");

/* ----------------- Image cache keyed by ImageDescriptor ----------------- */ /* ----------------- Image cache keyed by ImageDescriptor ----------------- */


public static ImageDescriptorRegistry getImageDescriptorRegistry() { public static ImageDescriptorRegistry getImageDescriptorRegistry() {
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ public String getTargetName() {
return targetName == null ? "<default>" : targetName; return targetName == null ? "<default>" : targetName;
} }


public BuildTarget getBuildTarget() {
return buildTarget;
}

public BuildManager getBuildManager() { public BuildManager getBuildManager() {
return BuildManager.getInstance(); return BuildManager.getInstance();
} }
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
package melnorme.lang.ide.ui.navigator; package melnorme.lang.ide.ui.navigator;


import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull; import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull;
import static melnorme.utilbox.core.CoreUtil.areEqual;


import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;


Expand All @@ -21,6 +22,7 @@
import melnorme.lang.ide.core.project_model.ProjectBuildInfo; import melnorme.lang.ide.core.project_model.ProjectBuildInfo;
import melnorme.utilbox.collections.ArrayList2; import melnorme.utilbox.collections.ArrayList2;
import melnorme.utilbox.collections.Indexable; import melnorme.utilbox.collections.Indexable;
import melnorme.utilbox.misc.HashcodeUtil;


public class BuildTargetsContainer extends ElementContainer<BuildTargetElement> { public class BuildTargetsContainer extends ElementContainer<BuildTargetElement> {


Expand All @@ -45,4 +47,23 @@ public String getText() {
return "Build Targets"; return "Build Targets";
} }


public IProject getProject() {
return buildInfo.getProject();
}

@Override
public boolean equals(Object obj) {
if(this == obj) return true;
if(!(obj instanceof BuildTargetsContainer)) return false;

BuildTargetsContainer other = (BuildTargetsContainer) obj;

return areEqual(getProject(), other.getProject());
}

@Override
public int hashCode() {
return HashcodeUtil.combinedHashCode(getProject());
}

} }
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -22,17 +22,25 @@
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IMemento; import org.eclipse.ui.IMemento;
import org.eclipse.ui.navigator.ICommonContentExtensionSite; import org.eclipse.ui.navigator.ICommonContentExtensionSite;
import org.eclipse.ui.navigator.ICommonContentProvider; import org.eclipse.ui.navigator.ICommonContentProvider;


import melnorme.lang.ide.core.LangCore; import melnorme.lang.ide.core.LangCore;
import melnorme.lang.ide.core.project_model.BuildManager.BuildModel;
import melnorme.lang.ide.core.project_model.IProjectModelListener;
import melnorme.lang.ide.core.project_model.ProjectBuildInfo; import melnorme.lang.ide.core.project_model.ProjectBuildInfo;
import melnorme.lang.ide.core.project_model.UpdateEvent;
import melnorme.lang.ide.ui.navigator.BuildTargetElement; import melnorme.lang.ide.ui.navigator.BuildTargetElement;
import melnorme.lang.ide.ui.navigator.BuildTargetsContainer; import melnorme.lang.ide.ui.navigator.BuildTargetsContainer;
import melnorme.lang.ide.ui.navigator.NavigatorElementsSwitcher; import melnorme.lang.ide.ui.navigator.NavigatorElementsSwitcher;
import melnorme.util.swt.SWTUtil;
import melnorme.util.swt.jface.AbstractTreeContentProvider; import melnorme.util.swt.jface.AbstractTreeContentProvider;
import melnorme.utilbox.collections.ArrayList2;
import melnorme.utilbox.collections.Indexable;
import melnorme.utilbox.misc.CollectionUtil; import melnorme.utilbox.misc.CollectionUtil;
import melnorme.utilbox.ownership.IDisposable;


public abstract class AbstractNavigatorContentProvider extends AbstractTreeContentProvider public abstract class AbstractNavigatorContentProvider extends AbstractTreeContentProvider
implements ICommonContentProvider { implements ICommonContentProvider {
Expand Down Expand Up @@ -63,73 +71,25 @@ protected StructuredViewer getViewer() {
return (StructuredViewer) viewer; return (StructuredViewer) viewer;
} }


// useful mostly to workaround bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=430005 protected BuildModel getBuildModel() {
/** return LangCore.getBuildManager().getBuildModel();
* Helper to throttle some code, that is, to prevent some recorring code to run too soon after each other }
* within a given a time interval.
*/ @Override
public abstract class ThrottleCodeJob extends Job { protected void viewerInitialized() {

super.viewerInitialized();
protected final int throttleDelayMillis;
protected long lastRequestMillis;
protected boolean isScheduled = false;

public ThrottleCodeJob(int throttleDelayMillis) {
super("throttle job");
this.throttleDelayMillis = throttleDelayMillis;
setSystem(true);
}

/** Schedule this job to run again. Will run throttled code immediatly if past time delay,
* schedule otherwise.
* Multiple schedule requests within the delay period will be squashed into just one request.
*/
public void scheduleRefreshJob() {

synchronized (this) {
if(isScheduled) {
return;
}
assertTrue(getState() == Job.NONE || getState() == Job.RUNNING);

isScheduled = true;
long runningTimeMillis = getRunningTimeMillis();
long nextPeriod = lastRequestMillis + throttleDelayMillis;
long deltaToNext = nextPeriod - runningTimeMillis;
if(deltaToNext > 0) {
//System.out.println(" schedule delta to next:" + deltaToNext);
schedule(deltaToNext);
return;
} else {
// continue and run immediately
}
}

runThrottledCode();
}

protected long getRunningTimeMillis() {
return System.nanoTime() / 1000_000;
}

@Override
protected final IStatus run(IProgressMonitor monitor) {
//System.out.println(getRunningTimeMillis() + " :job#run");
runThrottledCode();
return LangCore.createOkStatus("ok");
}


public void markRequestFinished() { getBuildModel().addListener(listener);
synchronized (this) { }
isScheduled = false;
lastRequestMillis = getRunningTimeMillis(); @Override
} public void dispose() {
//System.out.println(lastRequestMillis + " lastRequestFinished"); getBuildModel().removeListener(listener);
}


protected abstract void runThrottledCode(); super.dispose();
} }



/* ----------------- ----------------- */ /* ----------------- ----------------- */




Expand Down Expand Up @@ -246,4 +206,123 @@ default Object visitOther(Object element) {
} }
} }


/* ----------------- ----------------- */

protected final BuildModelListener listener = new BuildModelListener();

protected class BuildModelListener implements IProjectModelListener<ProjectBuildInfo> {

@Override
public void notifyUpdateEvent(UpdateEvent<ProjectBuildInfo> updateEvent) {
getViewer().refresh(updateEvent.project);
}

}

/* ----------------- ----------------- */

// useful mostly to workaround bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=430005
/**
* Helper to throttle some code, that is, to prevent some recorring code to run too soon after each other
* within a given a time interval.
*/
public abstract class ThrottleCodeJob extends Job {

protected final int throttleDelayMillis;
protected long lastRequestMillis;
protected boolean isScheduled = false;

public ThrottleCodeJob(int throttleDelayMillis) {
super("throttle job");
this.throttleDelayMillis = throttleDelayMillis;
setSystem(true);
}

/** Schedule this job to run again. Will run throttled code immediatly if past time delay,
* schedule otherwise.
* Multiple schedule requests within the delay period will be squashed into just one request.
*/
public void scheduleRefreshJob() {

synchronized (this) {
if(isScheduled) {
return;
}
assertTrue(getState() == Job.NONE || getState() == Job.RUNNING);

isScheduled = true;
long runningTimeMillis = getRunningTimeMillis();
long nextPeriod = lastRequestMillis + throttleDelayMillis;
long deltaToNext = nextPeriod - runningTimeMillis;
if(deltaToNext > 0) {
//System.out.println(" schedule delta to next:" + deltaToNext);
schedule(deltaToNext);
return;
} else {
// continue and run immediately
}
}

runThrottledCode();
}

protected long getRunningTimeMillis() {
return System.nanoTime() / 1000_000;
}

@Override
protected final IStatus run(IProgressMonitor monitor) {
//System.out.println(getRunningTimeMillis() + " :job#run");
runThrottledCode();
return LangCore.createOkStatus("ok");
}

public void markRequestFinished() {
synchronized (this) {
isScheduled = false;
lastRequestMillis = getRunningTimeMillis();
}
//System.out.println(lastRequestMillis + " lastRequestFinished");
}

protected abstract void runThrottledCode();
}

protected class NavigatorModelListener implements IDisposable {

@Override
public void dispose() {
}

// we use throttle Job as a workaround to to ensure label is updated, due to bug:
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430005
protected final ThrottleCodeJob viewerRefreshThrottleJob = new ThrottleCodeJob(1200) {
@Override
protected void runThrottledCode() {
postRefreshEventToUI(this, getElementsToRefresh());
}
};

protected Indexable<Object> getElementsToRefresh() {
return new ArrayList2<>();
};

protected void postRefreshEventToUI(ThrottleCodeJob throttleCodeJob, Indexable<Object> elementsToRefresh) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
throttleCodeJob.markRequestFinished();

if(SWTUtil.isOkToUse(getViewer().getControl())) {
for (Object element : elementsToRefresh) {
getViewer().refresh(element);
}
}
}
});

}

}

} }
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -25,17 +25,18 @@
import melnorme.lang.ide.ui.navigator.BuildTargetElement; import melnorme.lang.ide.ui.navigator.BuildTargetElement;
import melnorme.lang.ide.ui.navigator.BuildTargetsContainer; import melnorme.lang.ide.ui.navigator.BuildTargetsContainer;
import melnorme.lang.ide.ui.navigator.NavigatorElementsSwitcher; import melnorme.lang.ide.ui.navigator.NavigatorElementsSwitcher;
import melnorme.util.swt.jface.resources.CompositeImageDescriptorExt.Corner;
import melnorme.util.swt.jface.resources.DecoratedImageDescriptor;
import melnorme.util.swt.jface.resources.ImageDescriptorRegistry; import melnorme.util.swt.jface.resources.ImageDescriptorRegistry;
import melnorme.utilbox.collections.ArrayList2; import melnorme.utilbox.collections.ArrayList2;





public abstract class LangNavigatorLabelProvider extends AbstractLangLabelProvider {
public abstract class AbstractLangNavigatorLabelProvider extends AbstractLangLabelProvider {


protected final ArrayList2<ILabelDecorator> labelDecorators = new ArrayList2<>(); protected final ArrayList2<ILabelDecorator> labelDecorators = new ArrayList2<>();
protected final ImageDescriptorRegistry registry; protected final ImageDescriptorRegistry registry;


public AbstractLangNavigatorLabelProvider() { public LangNavigatorLabelProvider() {
super(); super();
this.registry = init_getImageRegistry(); this.registry = init_getImageRegistry();
this.labelDecorators.add(new ProblemsLabelDecorator(registry)); this.labelDecorators.add(new ProblemsLabelDecorator(registry));
Expand Down Expand Up @@ -89,9 +90,9 @@ public Image getImage(Object element) {
} }


public Image getBaseImage(Object element) { public Image getBaseImage(Object element) {
Image baseImage = getBaseImage_switcher().switchElement(element); ImageDescriptor baseImage = getBaseImage_switcher().switchElement(element);
if(baseImage != null) { if(baseImage != null) {
return baseImage; return registry.get(baseImage);
} }


if(element instanceof IResource) { if(element instanceof IResource) {
Expand All @@ -103,21 +104,25 @@ public Image getBaseImage(Object element) {


protected abstract DefaultGetImageSwitcher getBaseImage_switcher(); protected abstract DefaultGetImageSwitcher getBaseImage_switcher();


public static abstract class DefaultGetImageSwitcher implements NavigatorElementsSwitcher<Image> { public static abstract class DefaultGetImageSwitcher implements NavigatorElementsSwitcher<ImageDescriptor> {


@Override @Override
public Image visitProject(IProject project) { public ImageDescriptor visitProject(IProject project) {
return null; return null;
} }


@Override @Override
public Image visitBuildTargetsElement(BuildTargetsContainer buildTargetsElement) { public ImageDescriptor visitBuildTargetsElement(BuildTargetsContainer buildTargetsElement) {
return LangImages.BUILD_TARGETS_ELEM.getImage(); return LangImages.BUILD_TARGETS_ELEM.getDescriptor();
} }


@Override @Override
public Image visitBuildTarget(BuildTargetElement buildTarget) { public ImageDescriptor visitBuildTarget(BuildTargetElement buildTarget) {
return LangImages.BUILD_TARGET.getImage(); ImageDescriptor baseImage = LangImages.BUILD_TARGET.getDescriptor();
if(buildTarget.getBuildTarget().isEnabled()) {
return new DecoratedImageDescriptor(baseImage, LangImages.OVR_CHECKED, Corner.BOTTOM_RIGHT);
}
return baseImage;
} }


} }
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -20,9 +20,18 @@ public abstract class AbstractContentProvider implements IStructuredContentProvi
protected Object input; protected Object input;


@Override @Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { public void inputChanged(Viewer newViewer, Object oldInput, Object newInput) {
this.viewer = viewer; boolean isInitialization = (viewer == null && newViewer != null);

this.viewer = newViewer;
this.input = newInput; this.input = newInput;

if(isInitialization) {
viewerInitialized();
}
}

protected void viewerInitialized() {
} }


@Override @Override
Expand Down
Loading

0 comments on commit 795de4a

Please sign in to comment.