Merge branch 'master' of https://github.com/highfidelity/hifi into stageRemoval

This commit is contained in:
Nissim Hadar 2018-01-09 15:51:46 -08:00
commit bb04b68e42
14 changed files with 499 additions and 70 deletions

View file

@ -244,6 +244,7 @@ Item {
PageIndicator {
id: pageIndicator
currentIndex: swipeView.currentIndex
visible: swipeView.count > 1
delegate: Item {
width: 15

View file

@ -3,6 +3,7 @@
// libraries/midi/src
//
// Created by Burt Sloane
// Modified by Bruce Brown
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -14,30 +15,45 @@
#include <QtCore/QLoggingCategory>
#if defined Q_OS_WIN32
#include "Windows.h"
#endif
#if defined Q_OS_WIN32
const int MIDI_BYTE_MASK = 0x0FF;
const int MIDI_NIBBLE_MASK = 0x00F;
const int MIDI_PITCH_BEND_MASK = 0x3F80;
const int MIDI_SHIFT_STATUS = 4;
const int MIDI_SHIFT_NOTE = 8;
const int MIDI_SHIFT_VELOCITY = 16;
const int MIDI_SHIFT_PITCH_BEND = 9;
// Status Decode
const int MIDI_NOTE_OFF = 0x8;
const int MIDI_NOTE_ON = 0x9;
const int MIDI_POLYPHONIC_KEY_PRESSURE = 0xa;
const int MIDI_PROGRAM_CHANGE = 0xc;
const int MIDI_CHANNEL_PRESSURE = 0xd;
const int MIDI_PITCH_BEND_CHANGE = 0xe;
const int MIDI_SYSTEM_MESSAGE = 0xf;
#endif
const int MIDI_STATUS_MASK = 0x0F0;
const int MIDI_NOTE_OFF = 0x080;
const int MIDI_NOTE_ON = 0x090;
const int MIDI_CONTROL_CHANGE = 0x0b0;
const int MIDI_CONTROL_CHANGE = 0xb;
const int MIDI_CHANNEL_MODE_ALL_NOTES_OFF = 0x07b;
static Midi* instance = NULL; // communicate this to non-class callbacks
static Midi* instance = NULL; // communicate this to non-class callbacks
static bool thruModeEnabled = false;
static bool broadcastEnabled = false;
static bool typeNoteOffEnabled = true;
static bool typeNoteOnEnabled = true;
static bool typePolyKeyPressureEnabled = false;
static bool typeControlChangeEnabled = true;
static bool typeProgramChangeEnabled = true;
static bool typeChanPressureEnabled = false;
static bool typePitchBendEnabled = true;
static bool typeSystemMessageEnabled = false;
std::vector<QString> Midi::midiinexclude;
std::vector<QString> Midi::midioutexclude;
std::vector<QString> Midi::midiInExclude;
std::vector<QString> Midi::midiOutExclude;
#if defined Q_OS_WIN32
@ -47,7 +63,6 @@ std::vector<QString> Midi::midioutexclude;
std::vector<HMIDIIN> midihin;
std::vector<HMIDIOUT> midihout;
void CALLBACK MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
switch (wMsg) {
case MIM_OPEN:
@ -58,23 +73,64 @@ void CALLBACK MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD
if (midihin[i] == hMidiIn) {
midihin[i] = NULL;
instance->allNotesOff();
instance->midiHardwareChange();
}
}
break;
case MIM_DATA: {
int status = MIDI_BYTE_MASK & dwParam1;
int note = MIDI_BYTE_MASK & (dwParam1 >> MIDI_SHIFT_NOTE);
int vel = MIDI_BYTE_MASK & (dwParam1 >> MIDI_SHIFT_VELOCITY);
if (thruModeEnabled) {
instance->sendNote(status, note, vel); // relay the note on to all other midi devices
int device = -1;
for (int i = 0; i < midihin.size(); i++) {
if (midihin[i] == hMidiIn) {
device = i;
}
}
instance->noteReceived(status, note, vel); // notify the javascript
int raw = dwParam1;
int channel = (MIDI_NIBBLE_MASK & dwParam1) + 1;
int status = MIDI_BYTE_MASK & dwParam1;
int type = MIDI_NIBBLE_MASK & (dwParam1 >> MIDI_SHIFT_STATUS);
int note = MIDI_BYTE_MASK & (dwParam1 >> MIDI_SHIFT_NOTE);
int velocity = MIDI_BYTE_MASK & (dwParam1 >> MIDI_SHIFT_VELOCITY);
int bend = 0;
int program = 0;
if (!typeNoteOffEnabled && type == MIDI_NOTE_OFF) {
return;
}
if (!typeNoteOnEnabled && type == MIDI_NOTE_ON) {
return;
}
if (!typePolyKeyPressureEnabled && type == MIDI_POLYPHONIC_KEY_PRESSURE) {
return;
}
if (!typeControlChangeEnabled && type == MIDI_CONTROL_CHANGE) {
return;
}
if (typeProgramChangeEnabled && type == MIDI_PROGRAM_CHANGE) {
program = note;
note = 0;
}
if (typeChanPressureEnabled && type == MIDI_CHANNEL_PRESSURE) {
velocity = note;
note = 0;
}
if (typePitchBendEnabled && type == MIDI_PITCH_BEND_CHANGE) {
bend = ((MIDI_BYTE_MASK & (dwParam1 >> MIDI_SHIFT_NOTE)) |
(MIDI_PITCH_BEND_MASK & (dwParam1 >> MIDI_SHIFT_PITCH_BEND))) - 8192;
channel = 0; // Weird values on different instruments
note = 0;
velocity = 0;
}
if (!typeSystemMessageEnabled && type == MIDI_SYSTEM_MESSAGE) {
return;
}
if (thruModeEnabled) {
instance->sendNote(status, note, velocity); // relay the message on to all other midi devices.
}
instance->midiReceived(device, raw, channel, status, type, note, velocity, bend, program); // notify the javascript
break;
}
}
}
void CALLBACK MidiOutProc(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
switch (wMsg) {
case MOM_OPEN:
@ -85,21 +141,45 @@ void CALLBACK MidiOutProc(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_P
if (midihout[i] == hmo) {
midihout[i] = NULL;
instance->allNotesOff();
instance->midiHardwareChange();
}
}
break;
}
}
void Midi::sendNote(int status, int note, int vel) {
for (int i = 0; i < midihout.size(); i++) {
if (midihout[i] != NULL) {
midiOutShortMsg(midihout[i], status + (note << MIDI_SHIFT_NOTE) + (vel << MIDI_SHIFT_VELOCITY));
void Midi::sendRawMessage(int device, int raw) {
if (broadcastEnabled) {
for (int i = 0; i < midihout.size(); i++) {
if (midihout[i] != NULL) {
midiOutShortMsg(midihout[i], raw);
}
}
} else {
midiOutShortMsg(midihout[device], raw);
}
}
void Midi::sendMessage(int device, int channel, int type, int note, int velocity) {
int message = (channel - 1) | (type << MIDI_SHIFT_STATUS);
if (broadcastEnabled) {
for (int i = 0; i < midihout.size(); i++) {
if (midihout[i] != NULL) {
midiOutShortMsg(midihout[i], message | (note << MIDI_SHIFT_NOTE) | (velocity << MIDI_SHIFT_VELOCITY));
}
}
} else {
midiOutShortMsg(midihout[device], message | (note << MIDI_SHIFT_NOTE) | (velocity << MIDI_SHIFT_VELOCITY));
}
}
void Midi::sendNote(int status, int note, int velocity) {
for (int i = 0; i < midihout.size(); i++) {
if (midihout[i] != NULL) {
midiOutShortMsg(midihout[i], status + (note << MIDI_SHIFT_NOTE) + (velocity << MIDI_SHIFT_VELOCITY));
}
}
}
void Midi::MidiSetup() {
midihin.clear();
@ -110,8 +190,8 @@ void Midi::MidiSetup() {
midiInGetDevCaps(i, &incaps, sizeof(MIDIINCAPS));
bool found = false;
for (int j = 0; j < midiinexclude.size(); j++) {
if (midiinexclude[j].toStdString().compare(incaps.szPname) == 0) {
for (int j = 0; j < midiInExclude.size(); j++) {
if (midiInExclude[j].toStdString().compare(incaps.szPname) == 0) {
found = true;
break;
}
@ -122,7 +202,6 @@ void Midi::MidiSetup() {
midiInStart(tmphin);
midihin.push_back(tmphin);
}
}
MIDIOUTCAPS outcaps;
@ -130,8 +209,8 @@ void Midi::MidiSetup() {
midiOutGetDevCaps(i, &outcaps, sizeof(MIDIINCAPS));
bool found = false;
for (int j = 0; j < midioutexclude.size(); j++) {
if (midioutexclude[j].toStdString().compare(outcaps.szPname) == 0) {
for (int j = 0; j < midiOutExclude.size(); j++) {
if (midiOutExclude[j].toStdString().compare(outcaps.szPname) == 0) {
found = true;
break;
}
@ -164,7 +243,13 @@ void Midi::MidiCleanup() {
midihout.clear();
}
#else
void Midi::sendNote(int status, int note, int vel) {
void Midi::sendRawMessage(int device, int raw) {
}
void Midi::sendNote(int status, int note, int velocity) {
}
void Midi::sendMessage(int device, int channel, int type, int note, int velocity){
}
void Midi::MidiSetup() {
@ -176,26 +261,30 @@ void Midi::MidiCleanup() {
}
#endif
void Midi::noteReceived(int status, int note, int velocity) {
if (((status & MIDI_STATUS_MASK) != MIDI_NOTE_OFF) &&
((status & MIDI_STATUS_MASK) != MIDI_NOTE_ON) &&
((status & MIDI_STATUS_MASK) != MIDI_CONTROL_CHANGE)) {
return; // NOTE: only sending note-on, note-off, and control-change to Javascript
}
void Midi::midiReceived(int device, int raw, int channel, int status, int type, int note, int velocity, int bend, int program) {
QVariantMap eventData;
eventData["device"] = device;
eventData["raw"] = raw;
eventData["channel"] = channel;
eventData["status"] = status;
eventData["type"] = type;
eventData["note"] = note;
eventData["velocity"] = velocity;
emit midiNote(eventData);
eventData["bend"] = bend;
eventData["program"] = program;
emit midiNote(eventData);// Legacy
emit midiMessage(eventData);
}
void Midi::midiHardwareChange() {
emit midiReset();
}
//
Midi::Midi() {
instance = this;
#if defined Q_OS_WIN32
midioutexclude.push_back("Microsoft GS Wavetable Synth"); // we don't want to hear this thing
midiOutExclude.push_back("Microsoft GS Wavetable Synth"); // we don't want to hear this thing (Lags)
#endif
MidiSetup();
}
@ -203,10 +292,18 @@ Midi::Midi() {
Midi::~Midi() {
}
void Midi::sendRawDword(int device, int raw) {
sendRawMessage(device, raw);
}
void Midi::playMidiNote(int status, int note, int velocity) {
sendNote(status, note, velocity);
}
void Midi::sendMidiMessage(int device, int channel, int type, int note, int velocity) {
sendMessage(device, channel, type, note, velocity);
}
void Midi::allNotesOff() {
sendNote(MIDI_CONTROL_CHANGE, MIDI_CHANNEL_MODE_ALL_NOTES_OFF, 0); // all notes off
}
@ -219,6 +316,7 @@ void Midi::resetDevices() {
void Midi::USBchanged() {
instance->MidiCleanup();
instance->MidiSetup();
instance->midiHardwareChange();
}
//
@ -245,16 +343,16 @@ QStringList Midi::listMidiDevices(bool output) {
void Midi::unblockMidiDevice(QString name, bool output) {
if (output) {
for (unsigned long i = 0; i < midioutexclude.size(); i++) {
if (midioutexclude[i].toStdString().compare(name.toStdString()) == 0) {
midioutexclude.erase(midioutexclude.begin() + i);
for (unsigned long i = 0; i < midiOutExclude.size(); i++) {
if (midiOutExclude[i].toStdString().compare(name.toStdString()) == 0) {
midiOutExclude.erase(midiOutExclude.begin() + i);
break;
}
}
} else {
for (unsigned long i = 0; i < midiinexclude.size(); i++) {
if (midiinexclude[i].toStdString().compare(name.toStdString()) == 0) {
midiinexclude.erase(midiinexclude.begin() + i);
for (unsigned long i = 0; i < midiInExclude.size(); i++) {
if (midiInExclude[i].toStdString().compare(name.toStdString()) == 0) {
midiInExclude.erase(midiInExclude.begin() + i);
break;
}
}
@ -264,9 +362,9 @@ void Midi::unblockMidiDevice(QString name, bool output) {
void Midi::blockMidiDevice(QString name, bool output) {
unblockMidiDevice(name, output); // make sure it's only in there once
if (output) {
midioutexclude.push_back(name);
midiOutExclude.push_back(name);
} else {
midiinexclude.push_back(name);
midiInExclude.push_back(name);
}
}
@ -274,3 +372,38 @@ void Midi::thruModeEnable(bool enable) {
thruModeEnabled = enable;
}
void Midi::broadcastEnable(bool enable) {
broadcastEnabled = enable;
}
void Midi::typeNoteOffEnable(bool enable) {
typeNoteOffEnabled = enable;
}
void Midi::typeNoteOnEnable(bool enable) {
typeNoteOnEnabled = enable;
}
void Midi::typePolyKeyPressureEnable(bool enable) {
typePolyKeyPressureEnabled = enable;
}
void Midi::typeControlChangeEnable(bool enable) {
typeControlChangeEnabled = enable;
}
void Midi::typeProgramChangeEnable(bool enable) {
typeProgramChangeEnabled = enable;
}
void Midi::typeChanPressureEnable(bool enable) {
typeChanPressureEnabled = enable;
}
void Midi::typePitchBendEnable(bool enable) {
typePitchBendEnabled = enable;
}
void Midi::typeSystemMessageEnable(bool enable) {
typeSystemMessageEnabled = enable;
}

View file

@ -3,6 +3,7 @@
// libraries/midi/src
//
// Created by Burt Sloane
// Modified by Bruce Brown
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
@ -24,13 +25,16 @@ class Midi : public QObject, public Dependency {
SINGLETON_DEPENDENCY
public:
void noteReceived(int status, int note, int velocity); // relay a note to Javascript
void sendNote(int status, int note, int vel); // relay a note to MIDI outputs
void midiReceived(int device, int raw, int channel, int status, int type, int note, int velocity, int bend, int program); // relay a note to Javascript
void midiHardwareChange(); // relay hardware change to Javascript
void sendRawMessage(int device, int raw); // relay midi message to MIDI outputs
void sendNote(int status, int note, int velocity); // relay a note to MIDI outputs
void sendMessage(int device, int channel, int type, int note, int velocity); // relay a message to MIDI outputs
static void USBchanged();
private:
static std::vector<QString> midiinexclude;
static std::vector<QString> midioutexclude;
static std::vector<QString> midiInExclude;
static std::vector<QString> midiOutExclude;
private:
void MidiSetup();
@ -38,31 +42,63 @@ private:
signals:
void midiNote(QVariantMap eventData);
void midiMessage(QVariantMap eventData);
void midiReset();
public slots:
/// play a note on all connected devices
/// @param {int} status: 0x80 is noteoff, 0x90 is noteon (if velocity=0, noteoff), etc
/// @param {int} note: midi note number
/// @param {int} velocity: note velocity (0 means noteoff)
Q_INVOKABLE void playMidiNote(int status, int note, int velocity);
public slots:
// Send Raw Midi Packet to all connected devices
Q_INVOKABLE void sendRawDword(int device, int raw);
/// Send Raw Midi message to selected device
/// @param {int} device: device number
/// @param {int} raw: raw midi message (DWORD)
/// turn off all notes on all connected devices
Q_INVOKABLE void allNotesOff();
// Send Midi Message to all connected devices
Q_INVOKABLE void sendMidiMessage(int device, int channel, int type, int note, int velocity);
/// Send midi message to selected device/devices
/// @param {int} device: device number
/// @param {int} channel: channel number
/// @param {int} type: 0x8 is noteoff, 0x9 is noteon (if velocity=0, noteoff), etc
/// @param {int} note: midi note number
/// @param {int} velocity: note velocity (0 means noteoff)
/// clean up and re-discover attached devices
Q_INVOKABLE void resetDevices();
// Send Midi Message to all connected devices
Q_INVOKABLE void playMidiNote(int status, int note, int velocity);
/// play a note on all connected devices
/// @param {int} status: 0x80 is noteoff, 0x90 is noteon (if velocity=0, noteoff), etc
/// @param {int} note: midi note number
/// @param {int} velocity: note velocity (0 means noteoff)
/// ask for a list of inputs/outputs
Q_INVOKABLE QStringList listMidiDevices(bool output);
/// turn off all notes on all connected devices
Q_INVOKABLE void allNotesOff();
/// block an input/output by name
Q_INVOKABLE void blockMidiDevice(QString name, bool output);
/// clean up and re-discover attached devices
Q_INVOKABLE void resetDevices();
/// unblock an input/output by name
Q_INVOKABLE void unblockMidiDevice(QString name, bool output);
/// ask for a list of inputs/outputs
Q_INVOKABLE QStringList listMidiDevices(bool output);
/// block an input/output by name
Q_INVOKABLE void blockMidiDevice(QString name, bool output);
/// unblock an input/output by name
Q_INVOKABLE void unblockMidiDevice(QString name, bool output);
/// repeat all incoming notes to all outputs (default disabled)
Q_INVOKABLE void thruModeEnable(bool enable);
/// broadcast on all unblocked devices
Q_INVOKABLE void broadcastEnable(bool enable);
/// filter by event types
Q_INVOKABLE void typeNoteOffEnable(bool enable);
Q_INVOKABLE void typeNoteOnEnable(bool enable);
Q_INVOKABLE void typePolyKeyPressureEnable(bool enable);
Q_INVOKABLE void typeControlChangeEnable(bool enable);
Q_INVOKABLE void typeProgramChangeEnable(bool enable);
Q_INVOKABLE void typeChanPressureEnable(bool enable);
Q_INVOKABLE void typePitchBendEnable(bool enable);
Q_INVOKABLE void typeSystemMessageEnable(bool enable);
/// repeat all incoming notes to all outputs (default disabled)
Q_INVOKABLE void thruModeEnable(bool enable);
public:
Midi();

View file

@ -29,7 +29,8 @@ var DEFAULT_SCRIPTS_COMBINED = [
"system/notifications.js",
"system/dialTone.js",
"system/firstPersonHMD.js",
"system/tablet-ui/tabletUI.js"
"system/tablet-ui/tabletUI.js",
"system/emote.js"
];
var DEFAULT_SCRIPTS_SEPARATE = [
"system/controllers/controllerScripts.js"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

122
scripts/system/emote.js Normal file
View file

@ -0,0 +1,122 @@
"use strict";
//
// emote.js
// scripts/system/
//
// Created by Brad Hefta-Gaub on 7 Jan 2018
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
/* globals Script, Tablet */
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
(function() { // BEGIN LOCAL_SCOPE
var EMOTE_ANIMATIONS = ['Crying', 'Surprised', 'Dancing', 'Cheering', 'Waving', 'Fall', 'Pointing', 'Clapping'];
var ANIMATIONS = Array();
EMOTE_ANIMATIONS.forEach(function (name) {
var animationURL = Script.resolvePath("assets/animations/" + name + ".fbx");
var resource = AnimationCache.prefetch(animationURL);
var animation = AnimationCache.getAnimation(animationURL);
ANIMATIONS[name] = { url: animationURL, animation: animation, resource: resource};
});
var EMOTE_APP_BASE = "html/EmoteApp.html";
var EMOTE_APP_URL = Script.resolvePath(EMOTE_APP_BASE);
var EMOTE_LABEL = "EMOTE";
var EMOTE_APP_SORT_ORDER = 11;
var FPS = 60;
var MSEC_PER_SEC = 1000;
var FINISHED = 3; // see ScriptableResource::State
var onEmoteScreen = false;
var button;
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
var activeTimer = false; // used to cancel active timer if a user plays an amimation while another animation is playing
var activeEmote = false; // to keep track of the currently playing emote
button = tablet.addButton({
//icon: "icons/tablet-icons/emote.svg", // TODO - we need graphics for this
text: EMOTE_LABEL,
sortOrder: EMOTE_APP_SORT_ORDER
});
function onClicked() {
if (onEmoteScreen) {
tablet.gotoHomeScreen();
} else {
onEmoteScreen = true;
tablet.gotoWebScreen(EMOTE_APP_URL);
}
}
function onScreenChanged(type, url) {
onEmoteScreen = type === "Web" && (url.indexOf(EMOTE_APP_BASE) == url.length - EMOTE_APP_BASE.length);
button.editProperties({ isActive: onEmoteScreen });
}
// Handle the events we're receiving from the web UI
function onWebEventReceived(event) {
// Converts the event to a JavasScript Object
if (typeof event === "string") {
event = JSON.parse(event);
}
if (event.type === "click") {
var emoteName = event.data;
if (ANIMATIONS[emoteName].resource.state == FINISHED) {
if (activeTimer !== false) {
Script.clearTimeout(activeTimer);
}
// if the activeEmote is different from the chosen emote, then play the new emote. Other wise,
// this is a second click on the same emote as the activeEmote, and we will just stop it.
if (activeEmote !== emoteName) {
activeEmote = emoteName;
var frameCount = ANIMATIONS[emoteName].animation.frames.length;
MyAvatar.overrideAnimation(ANIMATIONS[emoteName].url, FPS, false, 0, frameCount);
var timeOut = MSEC_PER_SEC * frameCount / FPS;
activeTimer = Script.setTimeout(function () {
MyAvatar.restoreAnimation();
activeTimer = false;
activeEmote = false;
}, timeOut);
} else {
activeEmote = false;
MyAvatar.restoreAnimation();
}
}
}
}
button.clicked.connect(onClicked);
tablet.screenChanged.connect(onScreenChanged);
tablet.webEventReceived.connect(onWebEventReceived);
Script.scriptEnding.connect(function () {
if (onEmoteScreen) {
tablet.gotoHomeScreen();
}
button.clicked.disconnect(onClicked);
tablet.screenChanged.disconnect(onScreenChanged);
if (tablet) {
tablet.removeButton(button);
}
if (activeTimer !== false) {
Script.clearTimeout(activeTimer);
MyAvatar.restoreAnimation();
}
});
}()); // END LOCAL_SCOPE

View file

@ -0,0 +1,136 @@
<!--
// EmoteApp.html
//
// Created by Brad Hefta-Gaub on 7 Jan 2018
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
-->
<html>
<head>
<title>Emote App</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Raleway:300,400,600,700"" rel="stylesheet">
<style>
body {
margin: 0;
width: 100%;
font-family: 'Raleway', sans-serif;
color: white;
background: linear-gradient(#2b2b2b, #0f212e);
}
.top-bar {
height: 90px;
background: linear-gradient(#2b2b2b, #1e1e1e);
font-weight: bold;
padding-left: 30px;
padding-right: 30px;
display: flex;
align-items: center;
position: fixed;
width: 480px;
top: 0;
z-index: 1;
}
.content {
margin-top: 90px;
padding: 30px;
}
input[type=button] {
font-family: 'Raleway';
font-weight: bold;
font-size: 13px;
text-transform: uppercase;
vertical-align: top;
height: 28px;
min-width: 120px;
padding: 0px 18px;
margin-right: 6px;
border-radius: 5px;
border: none;
color: #fff;
background-color: #000;
background: linear-gradient(#343434 20%, #000 100%);
cursor: pointer;
}
input[type=button].white {
color: #121212;
background-color: #afafaf;
background: linear-gradient(#fff 20%, #afafaf 100%);
}
input[type=button]:enabled:hover {
background: linear-gradient(#000, #000);
border: none;
}
input[type=button].white:enabled:hover {
background: linear-gradient(#fff, #fff);
border: none;
}
input[type=button]:active {
background: linear-gradient(#343434, #343434);
}
input[type=button].white:active {
background: linear-gradient(#afafaf, #afafaf);
}
input[type=button]:disabled {
color: #252525;
background: linear-gradient(#575757 20%, #252525 100%);
}
input[type=button][pressed=pressed] {
color: #00b4ef;
}
</style>
</head>
<body>
<div class="top-bar">
<h4>Emote App</h4>
</div>
<div class="content">
<p>Click an emotion to Emote:<p>
<p><input type="button" class="emote-button white" value="Crying"></p>
<p><input type="button" class="emote-button white" value="Surprised"></p>
<p><input type="button" class="emote-button white" value="Dancing"></p>
<p><input type="button" class="emote-button white" value="Cheering"></p>
<p><input type="button" class="emote-button white" value="Waving"></p>
<p><input type="button" class="emote-button white" value="Fall"></p>
<p><input type="button" class="emote-button white" value="Pointing"></p>
<p><input type="button" class="emote-button white" value="Clapping"></p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
function main() {
// Send an event to emote.js when the page loads and is ready to get things rolling
console.log("document ready");
var readyEvent = {
"type": "ready",
};
// The event bridge handles event represented as a string the best. So here we first create a Javascript object, then convert to stirng
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
// Send an event when user click on each of the emote buttons
$(".emote-button").click(function(){
console.log(this.value + " button click");
var clickEvent = {
"type": "click",
"data": this.value
};
EventBridge.emitWebEvent(JSON.stringify(clickEvent));
});
}
$(document).ready(main);
</script>
</body>
</html>