| /******************************************************************************* |
| * Copyright (c) 2020 Christian Pontesegger and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Christian Pontesegger - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.skills.ui.views; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.nio.file.Files; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.skills.Activator; |
| import org.eclipse.skills.Logger; |
| import org.eclipse.skills.model.ISkill; |
| import org.eclipse.skills.model.ISkillsFactory; |
| import org.eclipse.skills.model.IUser; |
| import org.eclipse.skills.service.AvatarCreator; |
| import org.eclipse.skills.service.ISkillService; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.MouseAdapter; |
| import org.eclipse.swt.events.MouseEvent; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.ImageData; |
| import org.eclipse.swt.layout.FillLayout; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.FileDialog; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Link; |
| import org.eclipse.swt.widgets.ProgressBar; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.part.ViewPart; |
| import org.eclipse.wb.swt.SWTResourceManager; |
| |
| public class CharacterSheet extends ViewPart { |
| |
| /** |
| * Creates fake user data. Needed for developers when working with the SWT designer as we do not have a real service running there. |
| * |
| * @return fake user instance |
| */ |
| public static IUser createDummyUser() { |
| final IUser user = ISkillsFactory.eINSTANCE.createUser(); |
| |
| final ISkill xp = ISkillsFactory.eINSTANCE.createSkill(); |
| xp.setName("XP"); |
| xp.setExperience(12345); |
| xp.setProgression(ISkillsFactory.eINSTANCE.createFactorProgression()); |
| |
| user.setExperience(xp); |
| |
| final ISkill flexibility = ISkillsFactory.eINSTANCE.createSkill(); |
| flexibility.setName("Flexibility"); |
| flexibility.setExperience(445); |
| flexibility.setProgression(ISkillsFactory.eINSTANCE.createFactorProgression()); |
| user.getSkills().add(flexibility); |
| |
| final ISkill knowledge = ISkillsFactory.eINSTANCE.createSkill(); |
| knowledge.setName("Knowledge"); |
| knowledge.setExperience(5774); |
| knowledge.setProgression(ISkillsFactory.eINSTANCE.createFactorProgression()); |
| user.getSkills().add(knowledge); |
| |
| final ISkill scripting = ISkillsFactory.eINSTANCE.createSkill(); |
| scripting.setName("Scripting"); |
| scripting.setExperience(1111); |
| scripting.setProgression(ISkillsFactory.eINSTANCE.createFactorProgression()); |
| user.getSkills().add(scripting); |
| |
| user.setName("Hendrik"); |
| user.setImageLocation("platform:/plugin/" + Activator.PLUGIN_ID + "/resources/defaultAvatars/gentleman.png"); |
| |
| return user; |
| } |
| |
| private Label flblCharacterImage; |
| private SkillsComposite fskillsComposite; |
| private Composite fDataComposite; |
| private Label fLblTitle; |
| |
| public CharacterSheet() { |
| } |
| |
| @Override |
| public void createPartControl(Composite parent) { |
| |
| final Composite composite = new Composite(parent, SWT.NONE); |
| composite.setLayout(new GridLayout(3, false)); |
| |
| fLblTitle = new Label(composite, SWT.NONE); |
| fLblTitle.setFont(SWTResourceManager.getFont("Cantarell", 24, SWT.BOLD)); |
| fLblTitle.setForeground(SWTResourceManager.getColor(SWT.COLOR_TITLE_BACKGROUND)); |
| final GridData gd_lblNewLabel_2 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1); |
| gd_lblNewLabel_2.horizontalIndent = 20; |
| fLblTitle.setLayoutData(gd_lblNewLabel_2); |
| fLblTitle.setText("Scripting Expert"); |
| |
| flblCharacterImage = new Label(composite, SWT.NONE); |
| flblCharacterImage.setImage(getAvatarImage()); |
| final GridData gd_lblCharacterImage = new GridData(SWT.LEFT, SWT.TOP, false, true, 2, 1); |
| gd_lblCharacterImage.verticalIndent = 20; |
| flblCharacterImage.setLayoutData(gd_lblCharacterImage); |
| |
| fDataComposite = new Composite(composite, SWT.NONE); |
| fDataComposite.setLayout(new GridLayout(3, false)); |
| fDataComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); |
| new Label(fDataComposite, SWT.NONE); |
| new Label(fDataComposite, SWT.NONE); |
| new Label(fDataComposite, SWT.NONE); |
| |
| createSkillComponent(getUser().getExperience()); |
| |
| final Label label_1 = new Label(fDataComposite, SWT.SEPARATOR | SWT.HORIZONTAL); |
| final GridData gd_label_1 = new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1); |
| gd_label_1.verticalIndent = 20; |
| label_1.setLayoutData(gd_label_1); |
| |
| final Label lblNewLabel_6 = new Label(fDataComposite, SWT.NONE); |
| lblNewLabel_6.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1)); |
| lblNewLabel_6.setText("Your Skills:"); |
| new Label(fDataComposite, SWT.NONE); |
| new Label(fDataComposite, SWT.NONE); |
| |
| fskillsComposite = new SkillsComposite(fDataComposite, SWT.NONE); |
| fskillsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); |
| new Label(fDataComposite, SWT.NONE); |
| |
| final BadgesComposite badgesComposite = new BadgesComposite(fDataComposite, SWT.H_SCROLL); |
| final FillLayout fillLayout = (FillLayout) badgesComposite.getLayout(); |
| fillLayout.spacing = 20; |
| badgesComposite.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1)); |
| new Label(fDataComposite, SWT.NONE); |
| |
| final Label label = new Label(fDataComposite, SWT.SEPARATOR | SWT.HORIZONTAL); |
| label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); |
| new Label(fDataComposite, SWT.NONE); |
| |
| final Link link = new Link(composite, SWT.NONE); |
| link.addMouseListener(new MouseAdapter() { |
| @Override |
| public void mouseDown(MouseEvent e) { |
| final FileDialog fileDialog = new FileDialog(Display.getDefault().getActiveShell()); |
| final String location = fileDialog.open(); |
| if (location != null) { |
| try { |
| final File imageFile = new File(location); |
| final Image image = ImageDescriptor.createFromURL(imageFile.toURL()).createImage(); |
| // FIXME resource handling |
| flblCharacterImage.setImage(image); |
| flblCharacterImage.getParent().layout(true); |
| |
| final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class); |
| skillService.storeResource(ISkillService.RESOURCE_AVATAR, Files.readAllBytes(imageFile.toPath())); |
| |
| } catch (final IOException ex) { |
| Logger.error(Activator.PLUGIN_ID, "Could not load avatar image from file: " + location, ex); |
| } |
| } |
| } |
| }); |
| link.setText("<a>Load image...</a>"); |
| |
| final Link link_1 = new Link(composite, SWT.NONE); |
| link_1.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); |
| link_1.setText("<a>Random image</a>"); |
| link_1.addMouseListener(new MouseAdapter() { |
| @Override |
| public void mouseDown(MouseEvent e) { |
| |
| try { |
| final byte[] imageData = AvatarCreator.getRandomAvatarData(); |
| final Image image = new Image(Display.getDefault(), new ImageData(new ByteArrayInputStream(imageData))); |
| // FIXME resource handling |
| flblCharacterImage.setImage(image); |
| flblCharacterImage.getParent().layout(true); |
| |
| final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class); |
| skillService.storeResource(ISkillService.RESOURCE_AVATAR, imageData); |
| |
| } catch (final IOException ex) { |
| Logger.error(Activator.PLUGIN_ID, "Could not load random avatar image", ex); |
| } |
| } |
| }); |
| new Label(composite, SWT.NONE); |
| |
| loadUserData(); |
| } |
| |
| private void createSkillComponent(ISkill skill) { |
| final Label lblNewLabel = new Label(fDataComposite, SWT.NONE); |
| lblNewLabel.setText(skill.getName() + ":"); |
| |
| final ProgressBar prgExperience = new ProgressBar(fDataComposite, SWT.SMOOTH); |
| prgExperience.setMinimum(100); |
| prgExperience.setMaximum(1000); |
| prgExperience.setSelection(100); |
| prgExperience.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); |
| prgExperience.setToolTipText("2523 / 3000"); |
| |
| final Label lblNewLabel_1 = new Label(fDataComposite, SWT.NONE); |
| lblNewLabel_1.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); |
| lblNewLabel_1.setText("Level " + skill.getProgression().getLevel(skill.getExperience())); |
| } |
| |
| /** |
| * Get the avatar image. |
| * |
| * @return |
| */ |
| private Image getAvatarImage() { |
| // FIXME add resource handling |
| final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class); |
| if (skillService != null) |
| return new Image(Display.getDefault(), skillService.getUser().getAvatar()); |
| |
| return SWTResourceManager.getImage("/home/christian/character.png"); |
| } |
| |
| @Override |
| public void setFocus() { |
| } |
| |
| public IUser getUser() { |
| final ISkillService skillService = PlatformUI.getWorkbench().getService(ISkillService.class); |
| if (skillService != null) |
| return skillService.getUser(); |
| |
| // needed when used in development mode in SWT designer |
| return createDummyUser(); |
| } |
| |
| public void loadUserData() { |
| final IUser user = getUser(); |
| final String imageLocation = user.getImageLocation(); |
| if (imageLocation != null) { |
| // FIXME add resource handling |
| try { |
| final ImageDescriptor imageDescriptor = ImageDescriptor.createFromURL(new URL(imageLocation)); |
| flblCharacterImage.setImage(imageDescriptor.createImage()); |
| |
| } catch (final MalformedURLException e) { |
| Logger.error(Activator.PLUGIN_ID, "Cannot load character image from \"" + imageLocation + "\"", e); |
| } |
| } |
| |
| fLblTitle.setText(user.getName() + ", an expert (TODO)"); |
| |
| for (final ISkill skill : getSkillsSortedByProgress(user)) |
| createSkillComponent(skill); |
| |
| fskillsComposite.setSkills(user.getSkills()); |
| } |
| |
| private List<ISkill> getSkillsSortedByProgress(final IUser user) { |
| final List<ISkill> skills = new ArrayList<>(user.getSkills()); |
| Collections.sort(skills, (o1, o2) -> { |
| if (o1.getProgression().getLevel(o1.getExperience()) == o2.getProgression().getLevel(o2.getExperience())) |
| return o2.getExperience() - o1.getExperience(); |
| |
| return o2.getProgression().getLevel(o2.getExperience()) - o1.getProgression().getLevel(o1.getExperience()); |
| }); |
| |
| return skills; |
| } |
| } |