From b5b54c20f50a66cba7f1a21cebe80f810b06ab76 Mon Sep 17 00:00:00 2001 From: RobinsAviary Date: Wed, 1 Oct 2025 19:10:11 -0400 Subject: [PATCH] added clipboard example --- examples/core/core_clipboard_text.c | 190 ++++++++++++++++++++++++++ examples/core/core_clipboard_text.png | Bin 0 -> 15863 bytes 2 files changed, 190 insertions(+) create mode 100644 examples/core/core_clipboard_text.c create mode 100644 examples/core/core_clipboard_text.png diff --git a/examples/core/core_clipboard_text.c b/examples/core/core_clipboard_text.c new file mode 100644 index 000000000..302e21918 --- /dev/null +++ b/examples/core/core_clipboard_text.c @@ -0,0 +1,190 @@ +/******************************************************************************************* +* +* raylib [core] example - clipboard text +* +* Example complexity rating: [★☆☆☆] 1/4 +* +* Example originally created with raylib 5.5 +* +* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025-2025 Robin (@RobinsAviary) +* +********************************************************************************************/ + +#include "raylib.h" + +#include + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - clipboard text"); + + const char* clipboardText = NULL; + + // List of text the user can switch through and copy + const char* copyableText[] = {"raylib is fun", "hello, clipboard!", "potato chips"}; + + unsigned int textIndex = 0; + + const char* popupText = NULL; + + // Initialize timers + // The amount of time the pop-up text is on screen, before fading + const float maxTime = 3.0f; + float textTimer = 0.0f; + // The length of time text is offset + const float animMaxTime = 0.1f; + float pasteAnim = 0.0f; + float copyAnim = 0.0f; + int copyAnimMult = 1; + float textAnim = 0.0f; + float textAlpha = 0.0f; + // Offset amount for animations + const int offsetAmount = -4; + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // Check if the user has pressed the copy/paste key combinations + bool pastePressed = (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_V)); + bool copyPressed = (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_C)); + + // Update animation timers + if (textTimer > 0) textTimer -= GetFrameTime(); + if (pasteAnim > 0) pasteAnim -= GetFrameTime(); + if (copyAnim > 0) copyAnim -= GetFrameTime(); + if (textAnim > 0) textAnim -= GetFrameTime(); + + // React to the user pressing paste + if (pastePressed) + { + // Get the text from the user's clipboard. Most operating systems explicitly hide this information until the key combination is pressed while the window is selected + clipboardText = GetClipboardText(); + + // Reset values + textTimer = maxTime; + textAnim = animMaxTime; + pasteAnim = animMaxTime; + textAlpha = 1; + // Update the text that pops up at the bottom of the screen + popupText = "text pasted"; + } + + // React to the user pressing copy + if (copyPressed) + { + // Set the text on the user's clipboard + SetClipboardText(copyableText[textIndex]); + + // Reset values + textTimer = maxTime; + textAnim = animMaxTime; + copyAnim = animMaxTime; + copyAnimMult = 1; + textAlpha = 1; + // Update the text that pops up at the bottom of the screen + popupText = "text copied"; + } + + // Switch to the next item in the list when the user presses up + if (IsKeyPressed(KEY_UP)) + { + // Reset animation + copyAnim = animMaxTime; + copyAnimMult = 1; + + textIndex += 1; + + if (textIndex >= sizeof(copyableText) / sizeof(const char*)) { // Length of array + // Loop back to the other end + textIndex = 0; + } + } + + // Switch to the previous item in the list when the user presses down + if (IsKeyPressed(KEY_DOWN)) + { + // Reset animation + copyAnim = animMaxTime; + copyAnimMult = -1; + + if (textIndex == 0) + { + // Loop back to the other end + textIndex = (sizeof(copyableText) / sizeof(const char*)) - 1; // Length of array minus one + } + else + { + textIndex -= 1; + } + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + // Draw the user's pasted text, if there is any yet + if (clipboardText) + { + // Offset animation + int offset = 0; + if (pasteAnim > 0) offset = offsetAmount; + + // Draw the pasted text + DrawText("pasted clipboard:", 10, 10 + offset, 20, DARKGREEN); + DrawText(clipboardText, 10, 30 + offset, 20, DARKGRAY); + } + + // Offset animation + int textOffset = 0; + if (copyAnim > 0) textOffset = offsetAmount; + + // Draw copyable text and controls + DrawText(copyableText[textIndex], 10, 330 + (textOffset * copyAnimMult), 20, MAROON); + DrawText("up/down to change string, ctrl-c to copy, ctrl-v to paste", 10, 355, 20, DARKGRAY); + + // Alpha / Offset animation + if (textAlpha > 0) + { + // Offset animation + int offset = 0; + if (textAnim > 0) offset = offsetAmount; + // Draw pop up text + DrawText(popupText, 10, 425 + offset, 20, ColorAlpha(DARKGREEN, textAlpha)); + + // Fade-out animation + if (textTimer < 0) + { + textAlpha -= GetFrameTime(); + } + } + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/core/core_clipboard_text.png b/examples/core/core_clipboard_text.png new file mode 100644 index 0000000000000000000000000000000000000000..437d8ea1615371b5a70271a8973797487691d22f GIT binary patch literal 15863 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