ggwave-gui : polishing UX

This commit is contained in:
Georgi Gerganov
2020-12-30 19:43:42 +02:00
parent d620f5c15b
commit ccf6c90d60
6 changed files with 231 additions and 111 deletions

View File

@@ -1,9 +1,10 @@
#include "ggwave-common-sdl2.h" #include "ggwave-common-sdl2.h"
#include "ggwave/ggwave.h"
#include "ggwave-common.h" #include "ggwave-common.h"
#include "ggwave/ggwave.h"
#include <SDL.h>
#include <SDL_opengl.h> #include <SDL_opengl.h>
#include <chrono> #include <chrono>
@@ -14,8 +15,6 @@
#define EMSCRIPTEN_KEEPALIVE #define EMSCRIPTEN_KEEPALIVE
#endif #endif
constexpr double kBaseSampleRate = 48000.0;
namespace { namespace {
std::string g_defaultCaptureDeviceName = ""; std::string g_defaultCaptureDeviceName = "";
@@ -31,6 +30,7 @@ GGWave *g_ggWave = nullptr;
} }
// JS interface // JS interface
extern "C" { extern "C" {
EMSCRIPTEN_KEEPALIVE EMSCRIPTEN_KEEPALIVE
int sendData(int textLength, const char * text, int protocolId, int volume) { int sendData(int textLength, const char * text, int protocolId, int volume) {
@@ -117,7 +117,7 @@ bool GGWave_init(
SDL_AudioSpec playbackSpec; SDL_AudioSpec playbackSpec;
SDL_zero(playbackSpec); SDL_zero(playbackSpec);
playbackSpec.freq = ::kBaseSampleRate; playbackSpec.freq = GGWave::kBaseSampleRate;
playbackSpec.format = AUDIO_S16SYS; playbackSpec.format = AUDIO_S16SYS;
playbackSpec.channels = 1; playbackSpec.channels = 1;
playbackSpec.samples = 16*1024; playbackSpec.samples = 16*1024;
@@ -160,7 +160,7 @@ bool GGWave_init(
if (g_devIdIn == 0) { if (g_devIdIn == 0) {
SDL_AudioSpec captureSpec; SDL_AudioSpec captureSpec;
captureSpec = g_obtainedSpecOut; captureSpec = g_obtainedSpecOut;
captureSpec.freq = ::kBaseSampleRate; captureSpec.freq = GGWave::kBaseSampleRate;
captureSpec.format = AUDIO_F32SYS; captureSpec.format = AUDIO_F32SYS;
captureSpec.samples = 4096; captureSpec.samples = 4096;

View File

@@ -1,7 +1,5 @@
#pragma once #pragma once
#include <SDL.h>
#include <string> #include <string>
class GGWave; class GGWave;

View File

@@ -4,6 +4,8 @@
#include <string> #include <string>
#include <map> #include <map>
// some basic helper methods for the examples
template <class T> template <class T>
float getTime_ms(const T & tStart, const T & tEnd) { float getTime_ms(const T & tStart, const T & tEnd) {
return ((float)(std::chrono::duration_cast<std::chrono::microseconds>(tEnd - tStart).count()))/1000.0; return ((float)(std::chrono::duration_cast<std::chrono::microseconds>(tEnd - tStart).count()))/1000.0;

View File

@@ -13,6 +13,7 @@
#include <SDL.h> #include <SDL.h>
#include <algorithm>
#include <atomic> #include <atomic>
#include <cmath> #include <cmath>
#include <cstdio> #include <cstdio>
@@ -60,10 +61,59 @@ void ScrollWhenDraggingOnVoid(const ImVec2& delta, ImGuiMouseButton mouse_button
if (held && delta.y != 0.0f) if (held && delta.y != 0.0f)
ImGui::SetScrollY(window, window->Scroll.y + delta.y); ImGui::SetScrollY(window, window->Scroll.y + delta.y);
} }
} }
static const char * kFileBroadcastPrefix = "\xbc"; namespace ImGui {
bool ButtonDisabled(const char* label, const ImVec2& size = ImVec2(0, 0)) {
{
auto col = ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled);
col.x *= 0.8;
col.y *= 0.8;
col.z *= 0.8;
PushStyleColor(ImGuiCol_Button, col);
PushStyleColor(ImGuiCol_ButtonHovered, col);
PushStyleColor(ImGuiCol_ButtonActive, col);
}
{
auto col = ImGui::GetStyleColorVec4(ImGuiCol_Text);
col.x *= 0.75;
col.y *= 0.75;
col.z *= 0.75;
PushStyleColor(ImGuiCol_Text, col);
}
bool result = Button(label, size);
PopStyleColor(4);
return result;
}
bool ButtonDisablable(const char* label, const ImVec2& size = ImVec2(0, 0), bool isDisabled = false) {
if (isDisabled) {
ButtonDisabled(label, size);
return false;
}
return Button(label, size);
}
bool ButtonSelected(const char* label, const ImVec2& size = ImVec2(0, 0)) {
auto col = ImGui::GetStyleColorVec4(ImGuiCol_ButtonActive);
PushStyleColor(ImGuiCol_Button, col);
PushStyleColor(ImGuiCol_ButtonHovered, col);
bool result = Button(label, size);
PopStyleColor(2);
return result;
}
bool ButtonSelectable(const char* label, const ImVec2& size = ImVec2(0, 0), bool isSelected = false) {
if (isSelected) return ButtonSelected(label, size);
return Button(label, size);
}
}
static const char * kFileBroadcastPrefix = "\xba\xbc\xbb";
static const int kMaxSimultaneousChunkRequests = 4; static const int kMaxSimultaneousChunkRequests = 4;
static const float kBroadcastTime_sec = 60.0f;
struct Message { struct Message {
enum Type { enum Type {
@@ -157,7 +207,14 @@ Buffer g_buffer;
std::atomic<bool> g_isRunning; std::atomic<bool> g_isRunning;
// file send data // file send data
struct BroadcastInfo {
std::string ip;
int port;
int key;
};
bool g_focusFileSend = false; bool g_focusFileSend = false;
float g_tLastBroadcast = -100.0f;
GGSock::FileServer g_fileServer; GGSock::FileServer g_fileServer;
// file received data // file received data
@@ -238,8 +295,8 @@ bool confirmReceive(const char * uri) {
return false; return false;
} }
g_receivedFiles.erase(uri);
g_receivedFileInfosExtended[uri].readyToShare = true; g_receivedFileInfosExtended[uri].readyToShare = true;
g_receivedFiles.erase(uri);
return true; return true;
} }
@@ -264,7 +321,7 @@ void addFile(
std::memcpy(file.data.data(), dataBuffer, dataSize); std::memcpy(file.data.data(), dataBuffer, dataSize);
g_fileServer.addFile(std::move(file)); g_fileServer.addFile(std::move(file));
g_focusFileSend = true; //g_focusFileSend = true;
} }
void addFile( void addFile(
@@ -277,31 +334,83 @@ void addFile(
file.data = std::move(data); file.data = std::move(data);
g_fileServer.addFile(std::move(file)); g_fileServer.addFile(std::move(file));
g_focusFileSend = true; //g_focusFileSend = true;
} }
std::string generateFileBroadcastMessage() { std::string generateFileBroadcastMessage() {
// todo : to binary // todo : to binary
std::string result; std::string result;
result = kFileBroadcastPrefix; int plen = strlen(kFileBroadcastPrefix);
result += ' '; result.resize(plen + 4 + 2 + 2);
result += GGSock::Communicator::getLocalAddress();
result += ' '; char *p = &result[0];
result += std::to_string(g_fileServer.getParameters().listenPort); for (int i = 0; i < (int) plen; ++i) {
result += ' '; *p++ = kFileBroadcastPrefix[i];
result += std::to_string(rand()%32000); // todo : generated key should be used to authorize incoming messages }
{
auto ip = GGSock::Communicator::getLocalAddress();
std::replace(ip.begin(), ip.end(), '.', ' ');
std::stringstream ss(ip);
{ int b; ss >> b; *p++ = b; }
{ int b; ss >> b; *p++ = b; }
{ int b; ss >> b; *p++ = b; }
{ int b; ss >> b; *p++ = b; }
}
{
uint16_t port = g_fileServer.getParameters().listenPort;
{ int b = port/256; *p++ = b; }
{ int b = port%256; *p++ = b; }
}
{
uint16_t key = rand()%65536;
{ int b = key/256; *p++ = b; }
{ int b = key%256; *p++ = b; }
}
return result;
}
BroadcastInfo parseBroadcastInfo(const std::string & message) {
BroadcastInfo result;
const uint8_t *p = (uint8_t *) message.data();
p += strlen(kFileBroadcastPrefix);
result.ip += std::to_string((uint8_t)(*p++));
result.ip += '.';
result.ip += std::to_string((uint8_t)(*p++));
result.ip += '.';
result.ip += std::to_string((uint8_t)(*p++));
result.ip += '.';
result.ip += std::to_string((uint8_t)(*p++));
result.port = 256*((int)(*p++));
result.port += ((int)(*p++));
result.key = 256*((int)(*p++));
result.key += ((int)(*p++));
return result; return result;
} }
bool isFileBroadcastMessage(const std::string & message) { bool isFileBroadcastMessage(const std::string & message) {
if (message.size() != strlen(kFileBroadcastPrefix) + 4 + 2 + 2) {
return false;
}
bool result = true; bool result = true;
auto pSrc = kFileBroadcastPrefix; auto pSrc = kFileBroadcastPrefix;
auto pDst = message.data(); auto pDst = message.data();
while (pSrc != 0) { while (*pSrc != 0) {
if (*pDst == 0 || *pSrc++ != *pDst++) { if (*pDst == 0 || *pSrc++ != *pDst++) {
result = false; result = false;
break; break;
@@ -390,6 +499,7 @@ std::thread initMain() {
lastRxDataLength = g_ggWave->takeRxData(lastRxData); lastRxDataLength = g_ggWave->takeRxData(lastRxData);
if (lastRxDataLength > 0) { if (lastRxDataLength > 0) {
auto message = std::string((char *) lastRxData.data(), lastRxDataLength); auto message = std::string((char *) lastRxData.data(), lastRxDataLength);
const Message::Type type = isFileBroadcastMessage(message) ? Message::FileBroadcast : Message::Text;
g_buffer.stateCore.update = true; g_buffer.stateCore.update = true;
g_buffer.stateCore.flags.newMessage = true; g_buffer.stateCore.flags.newMessage = true;
g_buffer.stateCore.message = { g_buffer.stateCore.message = {
@@ -398,7 +508,7 @@ std::thread initMain() {
std::move(message), std::move(message),
g_ggWave->getRxProtocolId(), g_ggWave->getRxProtocolId(),
0, 0,
isFileBroadcastMessage(message) ? Message::FileBroadcast : Message::Text, type,
}; };
} }
@@ -436,6 +546,10 @@ std::thread initMain() {
void renderMain() { void renderMain() {
g_fileServer.update(); g_fileServer.update();
if (ImGui::GetTime() - g_tLastBroadcast > kBroadcastTime_sec && g_fileServer.isListening()) {
g_fileServer.stopListening();
}
if (g_fileClient.isConnected()) { if (g_fileClient.isConnected()) {
if (!g_hasRequestedFileInfos) { if (!g_hasRequestedFileInfos) {
g_receivedFileInfos.clear(); g_receivedFileInfos.clear();
@@ -482,23 +596,6 @@ void renderMain() {
++fileInfoExtended.nRequestedChunks; ++fileInfoExtended.nRequestedChunks;
} }
} }
//for (const auto & fileInfo : g_receivedFileInfos) {
// for (int i = 0; i < fileInfo.second.nChunks; ++i) {
// GGSock::FileServer::FileChunkRequestData data;
// data.uri = fileInfo.second.uri;
// data.chunkId = i;
// data.nChunksHave = 0;
// data.nChunksExpected = fileInfo.second.nChunks;
// GGSock::SerializationBuffer buffer;
// GGSock::Serialize()(data, buffer);
// g_fileClient.send(GGSock::FileServer::MsgFileChunkRequest, buffer.data(), (int32_t) buffer.size());
// g_fileClient.update();
// }
//}
//g_hasReceivedFiles = true;
//g_receivedId++;
} }
} }
@@ -624,22 +721,22 @@ void renderMain() {
ImGui::InvisibleButton("StatusBar", { ImGui::GetContentRegionAvailWidth(), statusBarHeight }); ImGui::InvisibleButton("StatusBar", { ImGui::GetContentRegionAvailWidth(), statusBarHeight });
if (ImGui::Button(ICON_FA_COGS, { menuButtonHeight, menuButtonHeight } )) { if (ImGui::ButtonSelectable(ICON_FA_COGS, { menuButtonHeight, menuButtonHeight }, windowId == WindowId::Settings )) {
windowId = WindowId::Settings; windowId = WindowId::Settings;
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(ICON_FA_COMMENT_ALT " Messages", { 0.35f*ImGui::GetContentRegionAvailWidth(), menuButtonHeight })) { if (ImGui::ButtonSelectable(ICON_FA_COMMENT_ALT " Messages", { 0.35f*ImGui::GetContentRegionAvailWidth(), menuButtonHeight }, windowId == WindowId::Messages)) {
windowId = WindowId::Messages; windowId = WindowId::Messages;
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(ICON_FA_FILE " Files", { 0.40f*ImGui::GetContentRegionAvailWidth(), menuButtonHeight })) { if (ImGui::ButtonSelectable(ICON_FA_FILE " Files", { 0.40f*ImGui::GetContentRegionAvailWidth(), menuButtonHeight }, windowId == WindowId::Files)) {
windowId = WindowId::Files; windowId = WindowId::Files;
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(ICON_FA_SIGNAL " Spectrum", { 1.0f*ImGui::GetContentRegionAvailWidth(), menuButtonHeight })) { if (ImGui::ButtonSelectable(ICON_FA_SIGNAL " Spectrum", { 1.0f*ImGui::GetContentRegionAvailWidth(), menuButtonHeight }, windowId == WindowId::Spectrum)) {
windowId = WindowId::Spectrum; windowId = WindowId::Spectrum;
} }
@@ -806,8 +903,8 @@ void renderMain() {
if (message.type == Message::FileBroadcast) { if (message.type == Message::FileBroadcast) {
auto col = ImVec4 { 0.0f, 1.0f, 1.0f, 1.0f }; auto col = ImVec4 { 0.0f, 1.0f, 1.0f, 1.0f };
col.w = interp; col.w = interp;
ImGui::TextColored(col, "-=[ File Broadcast ]=-"); auto broadcastInfo = parseBroadcastInfo(message.data);
ImGui::TextColored(col, "%s", message.data.c_str()); ImGui::TextColored(col, "-=[ File Broadcast from %s:%d ]=-", broadcastInfo.ip.c_str(), broadcastInfo.port);
} else { } else {
auto col = style.Colors[ImGuiCol_Text]; auto col = style.Colors[ImGuiCol_Text];
col.w = interp; col.w = interp;
@@ -851,7 +948,7 @@ void renderMain() {
if (ImGui::BeginPopup("Message options")) { if (ImGui::BeginPopup("Message options")) {
const auto & messageSelected = messageHistory[messageIdHolding]; const auto & messageSelected = messageHistory[messageIdHolding];
if (ImGui::Button("Resend")) { if (ImGui::ButtonDisablable("Resend", {}, messageSelected.type != Message::Text)) {
g_buffer.inputUI.update = true; g_buffer.inputUI.update = true;
g_buffer.inputUI.message = { false, std::chrono::system_clock::now(), messageSelected.data, messageSelected.protocolId, settings.volume, Message::Text }; g_buffer.inputUI.message = { false, std::chrono::system_clock::now(), messageSelected.data, messageSelected.protocolId, settings.volume, Message::Text };
@@ -863,23 +960,21 @@ void renderMain() {
ImGui::TextDisabled("|"); ImGui::TextDisabled("|");
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Copy")) { if (ImGui::ButtonDisablable("Copy", {}, messageSelected.type != Message::Text)) {
SDL_SetClipboardText(messageSelected.data.c_str()); SDL_SetClipboardText(messageSelected.data.c_str());
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
//if (messageSelected.received && messageSelected.type == Message::FileBroadcast) {
if (messageSelected.type == Message::FileBroadcast) { if (messageSelected.type == Message::FileBroadcast) {
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextDisabled("|"); ImGui::TextDisabled("|");
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Receive")) { if (ImGui::ButtonDisablable("Receive", {}, !messageSelected.received || messageSelected.type != Message::FileBroadcast)) {
std::string tmp = messageSelected.data.data() + strlen(kFileBroadcastPrefix); auto broadcastInfo = parseBroadcastInfo(messageSelected.data);
std::stringstream ss(tmp);
ss >> g_remoteIP; g_remoteIP = broadcastInfo.ip;
ss >> g_remotePort; g_remotePort = broadcastInfo.port;
g_hasRemoteInfo = true; g_hasRemoteInfo = true;
g_fileClient.disconnect(); g_fileClient.disconnect();
@@ -1053,26 +1148,29 @@ void renderMain() {
if (windowId == WindowId::Files) { if (windowId == WindowId::Files) {
const float subWindowButtonHeight = menuButtonHeight; const float subWindowButtonHeight = menuButtonHeight;
if (ImGui::Button("Send", { 0.50f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight })) { if (ImGui::ButtonSelectable("Send", { 0.50f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight }, subWindowId == SubWindowId::Send)) {
subWindowId = SubWindowId::Send; subWindowId = SubWindowId::Send;
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Receive", { 1.0f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight })) { if (ImGui::ButtonSelectable("Receive", { 1.0f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight }, subWindowId == SubWindowId::Receive)) {
subWindowId = SubWindowId::Receive; subWindowId = SubWindowId::Receive;
} }
switch (subWindowId) { switch (subWindowId) {
case SubWindowId::Send: case SubWindowId::Send:
{ {
const float statusWindowHeight = 2*style.ItemInnerSpacing.y + 4*ImGui::GetTextLineHeightWithSpacing();
bool hasAtLeastOneFile = false;
{ {
const auto wSize = ImVec2 { ImGui::GetContentRegionAvailWidth(), 0.60f*ImGui::GetContentRegionAvail().y }; const auto wSize = ImVec2 { ImGui::GetContentRegionAvailWidth(), ImGui::GetContentRegionAvail().y - subWindowButtonHeight - statusWindowHeight - 2*style.ItemInnerSpacing.y };
ImGui::BeginChild("Files:Send:fileInfos", wSize, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); ImGui::BeginChild("Files:Send:fileInfos", wSize, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
//ImGui::PushTextWrapPos();
auto fileInfos = g_fileServer.getFileInfos(); auto fileInfos = g_fileServer.getFileInfos();
for (const auto & fileInfo : fileInfos) { for (const auto & fileInfo : fileInfos) {
hasAtLeastOneFile = true;
ImGui::PushID(fileInfo.first); ImGui::PushID(fileInfo.first);
ImGui::Text("File: '%s' (%4.2f MB)\n", fileInfo.second.filename.c_str(), float(fileInfo.second.filesize)/1024.0f/1024.0f); ImGui::Text("File: '%s' (%4.2f MB)\n", fileInfo.second.filename.c_str(), float(fileInfo.second.filesize)/1024.0f/1024.0f);
if (ImGui::Button("Save")) { if (ImGui::Button("Save")) {
@@ -1093,49 +1191,32 @@ void renderMain() {
ImGui::PopID(); ImGui::PopID();
} }
//ImGui::PopTextWrapPos();
ImGui::PushTextWrapPos();
if (hasAtLeastOneFile == false) {
ImGui::TextColored({ 1.0f, 1.0f, 0.0f, 1.0f }, "There are currently no files availble to share.");
#if defined(IOS) || defined(ANDROID)
ImGui::TextColored({ 1.0f, 1.0f, 0.0f, 1.0f }, "Share some files with this app to be able to broadcast them to nearby devices through sound.");
#else
ImGui::TextColored({ 1.0f, 1.0f, 0.0f, 1.0f }, "Drag and drop some files on this window to be able to broadcast them to nearby devices through sound.");
#endif
}
ImGui::PopTextWrapPos();
ScrollWhenDraggingOnVoid(ImVec2(-mouse_delta.x, -mouse_delta.y), ImGuiMouseButton_Left); ScrollWhenDraggingOnVoid(ImVec2(-mouse_delta.x, -mouse_delta.y), ImGuiMouseButton_Left);
ImGui::EndChild(); ImGui::EndChild();
if (ImGui::Button("Broadcast", { 0.40f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight })) {
g_buffer.inputUI.update = true;
g_buffer.inputUI.message = {
false,
std::chrono::system_clock::now(),
::generateFileBroadcastMessage(),
settings.protocolId,
settings.volume,
Message::FileBroadcast
};
messageHistory.push_back(g_buffer.inputUI.message);
g_fileServer.startListening();
}
ImGui::SameLine();
if (ImGui::Button("Stop", { 0.50f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight })) {
g_fileServer.stopListening();
}
ImGui::SameLine();
if (ImGui::Button("Clear", { 1.0f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight })) {
g_deleteInfo.uri = "###ALL-FILES###";
g_deleteInfo.filename = "";
g_deleteId++;
}
} }
{ {
const auto wSize = ImVec2 { ImGui::GetContentRegionAvailWidth(), ImGui::GetContentRegionAvail().y }; const auto wSize = ImVec2 { ImGui::GetContentRegionAvailWidth(), ImGui::GetContentRegionAvail().y - subWindowButtonHeight - style.ItemInnerSpacing.y };
ImGui::BeginChild("Files:Send:clientInfos", wSize, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); ImGui::BeginChild("Files:Send:clientInfos", wSize, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
if (g_fileServer.isListening() == false) { if (g_fileServer.isListening() == false) {
ImGui::TextColored({ 1.0f, 1.0f, 0.0f, 1.0f }, "Not accepting new connections"); ImGui::TextColored({ 1.0f, 1.0f, 0.0f, 1.0f }, "Not accepting new connections.");
} else { } else {
ImGui::TextColored({ 0.0f, 1.0f, 0.0f, 1.0f }, "Accepting new connections at %s:%d", ImGui::TextColored({ 0.0f, 1.0f, 0.0f, 1.0f }, "Accepting new connections at: %s:%d (%4.1f sec)",
GGSock::Communicator::getLocalAddress().c_str(), g_fileServer.getParameters().listenPort); GGSock::Communicator::getLocalAddress().c_str(), g_fileServer.getParameters().listenPort, kBroadcastTime_sec - ImGui::GetTime() + g_tLastBroadcast);
} }
auto clientInfos = g_fileServer.getClientInfos(); auto clientInfos = g_fileServer.getClientInfos();
@@ -1150,6 +1231,37 @@ void renderMain() {
ScrollWhenDraggingOnVoid(ImVec2(-mouse_delta.x, -mouse_delta.y), ImGuiMouseButton_Left); ScrollWhenDraggingOnVoid(ImVec2(-mouse_delta.x, -mouse_delta.y), ImGuiMouseButton_Left);
ImGui::EndChild(); ImGui::EndChild();
} }
{
if (ImGui::Button("Broadcast", { 0.40f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight })) {
g_buffer.inputUI.update = true;
g_buffer.inputUI.message = {
false,
std::chrono::system_clock::now(),
::generateFileBroadcastMessage(),
settings.protocolId,
settings.volume,
Message::FileBroadcast
};
messageHistory.push_back(g_buffer.inputUI.message);
g_tLastBroadcast = ImGui::GetTime();
g_fileServer.startListening();
}
ImGui::SameLine();
if (ImGui::ButtonDisablable("Stop", { 0.50f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight }, !g_fileServer.isListening())) {
g_fileServer.stopListening();
}
ImGui::SameLine();
if (ImGui::ButtonDisablable("Clear", { 1.0f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight }, !hasAtLeastOneFile)) {
g_deleteInfo.uri = "###ALL-FILES###";
g_deleteInfo.filename = "";
g_deleteId++;
}
}
} }
break; break;
case SubWindowId::Receive: case SubWindowId::Receive:
@@ -1183,7 +1295,7 @@ void renderMain() {
if (fileInfoExtended.readyToShare) { if (fileInfoExtended.readyToShare) {
ImGui::TextColored({ 0.0f, 1.0f, 0.0f, 1.0f }, "Ready to share!"); ImGui::TextColored({ 0.0f, 1.0f, 0.0f, 1.0f }, "Ready to share!");
} }
} else if (fileInfoExtended.isReceiving || fileInfoExtended.nReceivedChunks > 0) { } else if (g_fileClient.isConnected() && (fileInfoExtended.isReceiving || fileInfoExtended.nReceivedChunks > 0)) {
if (fileInfoExtended.isReceiving) { if (fileInfoExtended.isReceiving) {
if (ImGui::Button("Pause")) { if (ImGui::Button("Pause")) {
fileInfoExtended.isReceiving = false; fileInfoExtended.isReceiving = false;
@@ -1196,12 +1308,14 @@ void renderMain() {
ImGui::SameLine(); ImGui::SameLine();
ImGui::ProgressBar(float(fileInfoExtended.nReceivedChunks)/fileInfo.second.nChunks); ImGui::ProgressBar(float(fileInfoExtended.nReceivedChunks)/fileInfo.second.nChunks);
} else { } else if (g_fileClient.isConnected()) {
if (ImGui::Button("Receive")) { if (ImGui::Button("Receive")) {
fileInfoExtended.isReceiving = true; fileInfoExtended.isReceiving = true;
fileInfoExtended.isChunkReceived.resize(fileInfo.second.nChunks); fileInfoExtended.isChunkReceived.resize(fileInfo.second.nChunks);
fileInfoExtended.isChunkRequested.resize(fileInfo.second.nChunks); fileInfoExtended.isChunkRequested.resize(fileInfo.second.nChunks);
} }
} else {
ImGui::Text("%s", "");
} }
if ((fileInfoExtended.isReceiving == false || isReceived) && fileInfoExtended.requestToShare == false) { if ((fileInfoExtended.isReceiving == false || isReceived) && fileInfoExtended.requestToShare == false) {
@@ -1225,6 +1339,7 @@ void renderMain() {
{ {
const auto wSize = ImVec2 { ImGui::GetContentRegionAvailWidth(), ImGui::GetContentRegionAvail().y - subWindowButtonHeight - style.ItemInnerSpacing.y }; const auto wSize = ImVec2 { ImGui::GetContentRegionAvailWidth(), ImGui::GetContentRegionAvail().y - subWindowButtonHeight - style.ItemInnerSpacing.y };
ImGui::BeginChild("Files:Receive:status", wSize, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); ImGui::BeginChild("Files:Receive:status", wSize, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
ImGui::PushTextWrapPos(); ImGui::PushTextWrapPos();
@@ -1243,25 +1358,27 @@ void renderMain() {
ImGui::TextColored({ 1.0f, 1.0f, 0.0f, 1.0f }, "Attempting to connect ..."); ImGui::TextColored({ 1.0f, 1.0f, 0.0f, 1.0f }, "Attempting to connect ...");
} }
} }
ImGui::PopTextWrapPos();
ScrollWhenDraggingOnVoid(ImVec2(-mouse_delta.x, -mouse_delta.y), ImGuiMouseButton_Left);
ImGui::EndChild();
} }
ImGui::PopTextWrapPos(); {
if (g_fileClient.isConnecting() == false && g_fileClient.isConnected() == false) {
ScrollWhenDraggingOnVoid(ImVec2(-mouse_delta.x, -mouse_delta.y), ImGuiMouseButton_Left); if (ImGui::ButtonDisablable("Connect", { 1.00f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight }, !g_hasRemoteInfo)) {
ImGui::EndChild(); g_fileClient.connect(g_remoteIP, g_remotePort, 0);
}
if (g_hasRemoteInfo && g_fileClient.isConnecting() == false && g_fileClient.isConnected() == false) {
if (ImGui::Button("Connect", { 1.00f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight })) {
g_fileClient.connect(g_remoteIP, g_remotePort, 0);
} }
}
if (g_fileClient.isConnecting() || g_fileClient.isConnected()) { if (g_fileClient.isConnecting() || g_fileClient.isConnected()) {
if (ImGui::Button("Disconnect", { 1.00f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight })) { if (ImGui::Button("Disconnect", { 1.00f*ImGui::GetContentRegionAvailWidth(), subWindowButtonHeight })) {
g_fileClient.disconnect(); g_fileClient.disconnect();
g_hasReceivedFileInfos = false; g_hasReceivedFileInfos = false;
g_hasRequestedFileInfos = false; g_hasRequestedFileInfos = false;
g_hasReceivedFiles = false; g_hasReceivedFiles = false;
}
} }
} }
} }

View File

@@ -43,7 +43,10 @@ bool ImGui_BeginFrame(SDL_Window * window) {
printf("Dropped file: '%s'\n", event.drop.file); printf("Dropped file: '%s'\n", event.drop.file);
auto data = readFile(event.drop.file); auto data = readFile(event.drop.file);
std::string uri = event.drop.file; std::string uri = event.drop.file;
auto filename = uri.substr(uri.find_last_of("/\\") + 1); std::string filename = event.drop.file;
if (uri.find("/") || uri.find("\\")) {
filename = uri.substr(uri.find_last_of("/\\") + 1);
}
addFile(uri.c_str(), filename.c_str(), std::move(data)); addFile(uri.c_str(), filename.c_str(), std::move(data));
break; break;
} }
@@ -175,9 +178,9 @@ int main(int argc, char** argv) {
auto worker = initMain(); auto worker = initMain();
// tmp // tmp
addFile("test0.raw", "test0.raw", std::vector<char>(1024)); //addFile("test0.raw", "test0.raw", std::vector<char>(1024));
addFile("test1.jpg", "test0.jpg", std::vector<char>(1024*1024 + 624)); //addFile("test1.jpg", "test0.jpg", std::vector<char>(1024*1024 + 624));
addFile("test2.mpv", "test0.mov", std::vector<char>(1024*1024*234 + 53827)); //addFile("test2.mpv", "test0.mov", std::vector<char>(1024*1024*234 + 53827));
while (true) { while (true) {
if (ImGui_BeginFrame(window) == false) { if (ImGui_BeginFrame(window) == false) {